lib/kpm/base_artifact.rb in kpm-0.0.10 vs lib/kpm/base_artifact.rb in kpm-0.0.11
- old
+ new
@@ -33,13 +33,13 @@
KAUI_ARTIFACT_ID = 'kaui-standalone'
KAUI_PACKAGING = 'war'
KAUI_CLASSIFIER = nil
class << self
- def pull(logger, group_id, artifact_id, packaging='jar', classifier=nil, version='LATEST', destination_path=nil, overrides={}, ssl_verify=true)
+ def pull(logger, group_id, artifact_id, packaging='jar', classifier=nil, version='LATEST', destination_path=nil, sha1_file=nil, force_download=false, overrides={}, ssl_verify=true)
coordinates = build_coordinates(group_id, artifact_id, packaging, classifier, version)
- pull_and_put_in_place(logger, coordinates, destination_path, is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id), overrides, ssl_verify)
+ pull_and_put_in_place(logger, coordinates, destination_path, is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id), sha1_file, force_download, overrides, ssl_verify)
end
def nexus_remote(overrides={}, ssl_verify=true)
nexus_remote ||= NexusCli::RemoteFactory.create(nexus_defaults.merge(overrides || {}), ssl_verify)
end
@@ -51,74 +51,117 @@
}
end
protected
- def pull_and_put_in_place(logger, coordinates, destination_path=nil, skip_top_dir=true, overrides={}, ssl_verify=true)
+ def pull_and_put_in_place(logger, coordinates, destination_path=nil, skip_top_dir=true, sha1_file=nil, force_download=false, overrides={}, ssl_verify=true)
destination_path = KPM::root if destination_path.nil?
# Create the destination directory
if path_looks_like_a_directory(destination_path)
destination_dir = destination_path
else
destination_dir = File.dirname(destination_path)
end
FileUtils.mkdir_p(destination_dir)
+ # Build artifact info
+ artifact_info = artifact_info(coordinates, destination_path, overrides, ssl_verify)
+ if !force_download && skip_if_exists(artifact_info, coordinates, sha1_file)
+ logger.info "Skipping installation of #{coordinates} to #{artifact_info[:file_path]}, file already exists"
+ artifact_info[:skipped] = true
+ return artifact_info
+ end
+
# Download the artifact in a temporary directory in case of failures
- info = {}
Dir.mktmpdir do |tmp_destination_dir|
logger.info " Starting download of #{coordinates} to #{tmp_destination_dir}"
- info = pull_and_verify(logger, coordinates, tmp_destination_dir, overrides, ssl_verify)
-
- # Move the file to the final destination, unpacking if necessary
- is_tgz = info[:file_path].end_with?('.tar.gz') || info[:file_path].end_with?('.tgz')
- if is_tgz
- Utils.unpack_tgz(info[:file_path], destination_path, skip_top_dir)
- FileUtils.rm info[:file_path]
+ downloaded_artifact_info = pull_and_verify(logger, artifact_info[:sha1], coordinates, tmp_destination_dir, sha1_file, overrides, ssl_verify)
+ if artifact_info[:is_tgz]
+ Utils.unpack_tgz(downloaded_artifact_info[:file_path], destination_path, skip_top_dir)
+ FileUtils.rm downloaded_artifact_info[:file_path]
else
- FileUtils.mv info[:file_path], destination_path
+ FileUtils.mv downloaded_artifact_info[:file_path], destination_path
+ artifact_info[:size] = downloaded_artifact_info[:size]
end
+ logger.info "Successful installation of #{coordinates} to #{artifact_info[:file_path]}"
+ end
+ artifact_info
+ end
- # Update the info hash with the real destination
- if File.directory?(destination_path) && !is_tgz
- destination = File.join(File.expand_path(destination_path), info[:file_name])
- else
- destination = destination_path
- end
- info[:file_path] = File.expand_path(destination)
+ def skip_if_exists(artifact_info, coordinates, sha1_file)
- if is_tgz
- info[:file_name] = nil
- info[:size] = nil
- else
- info[:file_name] = File.basename(destination)
- end
+ # Unclear if this is even possible
+ return false if artifact_info[:sha1].nil?
- logger.info "Successful installation of #{coordinates} to #{info[:file_path]}"
+ # Check entry in sha1_file if exists
+ if sha1_file && File.exists?(sha1_file)
+ sha1_checker = Sha1Checker.from_file(sha1_file)
+ local_sha1 = sha1_checker.sha1(coordinates)
+ return true if local_sha1 == artifact_info[:sha1]
end
+
+ # If not using sha1_file mechanism, exit early if file_path odes not exist or is a directory
+ if !File.exists?(artifact_info[:file_path]) ||
+ File.directory?(artifact_info[:file_path])
+ return false
+ end
+
+ # Finally check if remote_sha1 matches what we have locally
+ local_sha1 = Digest::SHA1.file(artifact_info[:file_path]).hexdigest
+ local_sha1 == artifact_info[:sha1]
+ end
+
+
+ def artifact_info(coordinates, destination_path, overrides={}, ssl_verify=true)
+
+ info = {}
+ nexus_info = nexus_remote(overrides, ssl_verify).get_artifact_info(coordinates)
+
+ xml = REXML::Document.new(nexus_info)
+ repository_path = xml.elements['//repositoryPath'].text unless xml.elements['//repositoryPath'].nil?
+ sha1 = xml.elements['//sha1'].text unless xml.elements['//sha1'].nil?
+ version = xml.elements['//version'].text unless xml.elements['//version'].nil?
+
+ info[:sha1] = sha1
+ info[:version] = version
+ info[:is_tgz] = repository_path.end_with?('.tar.gz') || repository_path.end_with?('.tgz')
+ if File.directory?(destination_path) && !info[:is_tgz]
+ destination = File.join(File.expand_path(destination_path), File.basename(repository_path))
+ info[:file_name] = File.basename(repository_path)
+ else
+ # The destination was a fully specified path or this is an archive and we keep the directory
+ destination = destination_path
+ info[:file_name] = File.basename(destination_path) if !info[:is_tgz]
+ end
+ info[:file_path] = File.expand_path(destination)
+ info[:skipped] = false
info
end
- def pull_and_verify(logger, coordinates, destination_dir, overrides={}, ssl_verify=true)
+
+ def pull_and_verify(logger, remote_sha1, coordinates, destination_dir, sha1_file, overrides={}, ssl_verify=true)
info = nexus_remote(overrides, ssl_verify).pull_artifact(coordinates, destination_dir)
- raise ArtifactCorruptedException unless verify(logger, coordinates, info[:file_path], overrides, ssl_verify)
+ raise ArtifactCorruptedException unless verify(logger, info[:file_path], remote_sha1)
+
+ if sha1_file
+ sha1_checker = Sha1Checker.from_file(sha1_file)
+ sha1_checker.add_or_modify_entry!(coordinates, remote_sha1)
+ end
+
info
end
- def verify(logger, coordinates, file_path, overrides={}, ssl_verify=true)
- artifact_info = nexus_remote(overrides, ssl_verify).get_artifact_info(coordinates)
- sha1_element = REXML::Document.new(artifact_info).elements['//sha1']
+ def verify(logger, file_path, remote_sha1)
# Can't check :(
- if sha1_element.nil?
- logger.warn("Unable to find sha1 in Nexus repo for #{coordinates}. Artifact info: #{artifact_info.inspect}")
+ if remote_sha1.nil?
+ logger.warn("Unable to verify sha1 for #{coordinates}. Artifact info: #{artifact_info.inspect}")
return true
end
local_sha1 = Digest::SHA1.file(file_path).hexdigest
- sha1 = sha1_element.text
- local_sha1 == sha1
+ local_sha1 == remote_sha1
end
def build_coordinates(group_id, artifact_id, packaging, classifier, version=nil)
if classifier.nil?
if version.nil?