Files
picopackage/lib/picopackage/fetch.rb

106 lines
3.0 KiB
Ruby

require 'net/http'
require 'fileutils'
require 'tempfile'
require 'json'
require 'debug'
module Picopackage
class Fetch
def self.fetch(url, destination, force: false)
raise ArgumentError, "Destination directory does not exist: #{destination}" unless Dir.exist?(destination)
provider = Provider.for(url)
source_file = provider.source_file
file_path = File.join(destination, source_file.filename)
if File.exist?(file_path) && force
source_file.save(destination)
elsif File.exist?(file_path)
local_source_file = SourceFile.from_file(file_path)
status = Status.compare(local_source_file, source_file)
if force
source_file.save(destination)
elsif status.modified?
raise LocalModificationError, "#{status.message}. Use -f or --force to overwrite local version"
elsif status.outdated?
puts "Updated from #{local_source_file.version} to #{source_file.version}"
source_file.save(destination)
elsif status.up_to_date?
puts status.message
end
else
source_file.save(destination)
if source_file.imported?
source_file.digest!
puts "Picopackage created for #{source_file.filename}"
else
puts "Picopackage downloaded to #{file_path}"
end
end
provider.source_file
end
end
class Status
attr_reader :state, :local_version, :remote_version
def self.compare(local_source_file, remote_source_file)
return new(:outdated) if local_source_file.metadata.nil? || remote_source_file.metadata.nil?
local_version = local_source_file.metadata["version"]
remote_version = remote_source_file.metadata["version"]
if local_version == remote_version
if local_source_file.modified?
new(:modified, local_version:)
else
new(:up_to_date, local_version:)
end
else
new(:outdated,
local_version:,
remote_version:,
modified: local_source_file.modified?
)
end
end
def initialize(state, local_version: nil, remote_version: nil, modified: false)
@state = state
@local_version = local_version
@remote_version = remote_version
@modified = modified
end
def modified?
@modified || @state == :modified
end
def up_to_date?
@state == :up_to_date
end
def outdated?
@state == :outdated
end
def message
case state
when :up_to_date
"Picopackage is up to date"
when :outdated
if modified?
"Local Picopackage (v#{local_version}) has modifications but remote version (v#{remote_version}) is available"
else
"Local Picopackage (v#{local_version}) is outdated. Remote version: v#{remote_version}"
end
when :modified
"Local Picopackage has been modified from original version (v#{local_version})"
end
end
end
end