lib/kpm/base_artifact.rb in kpm-0.0.5 vs lib/kpm/base_artifact.rb in kpm-0.0.6
- old
+ new
@@ -1,32 +1,127 @@
+require 'digest/sha1'
require 'nexus_cli'
+require 'rexml/document'
module KPM
+
+ class ArtifactCorruptedException < IOError
+ def message
+ 'Downloaded artifact failed checksum verification'
+ end
+ end
+
class BaseArtifact
- KILLBILL_GROUP_ID = 'org.kill-bill.billing'
- KILLBILL_JAVA_PLUGIN_GROUP_ID = 'org.kill-bill.billing.plugin.java'
- KILLBILL_RUBY_PLUGIN_GROUP_ID = 'org.kill-bill.billing.plugin.ruby'
+ KILLBILL_GROUP_ID = 'org.kill-bill.billing'
+ KILLBILL_ARTIFACT_ID = 'killbill-profiles-killbill'
+ KILLBILL_PACKAGING = 'war'
+ KILLBILL_CLASSIFIER = 'jar-with-dependencies'
+
+ KILLPAY_ARTIFACT_ID = 'killbill-profiles-killpay'
+ KILLPAY_PACKAGING = 'war'
+ KILLPAY_CLASSIFIER = 'jar-with-dependencies'
+
+ KILLBILL_JAVA_PLUGIN_GROUP_ID = 'org.kill-bill.billing.plugin.java'
+ KILLBILL_JAVA_PLUGIN_PACKAGING = 'jar'
+ KILLBILL_JAVA_PLUGIN_CLASSIFIER = nil
+
+ KILLBILL_RUBY_PLUGIN_GROUP_ID = 'org.kill-bill.billing.plugin.ruby'
+ KILLBILL_RUBY_PLUGIN_PACKAGING = 'tar.gz'
+ KILLBILL_RUBY_PLUGIN_CLASSIFIER = nil
+
+ KAUI_GROUP_ID = 'org.kill-bill.billing.kaui'
+ KAUI_ARTIFACT_ID = 'kaui-standalone'
+ KAUI_PACKAGING = 'war'
+ KAUI_CLASSIFIER = nil
+
class << self
- def pull(group_id, artifact_id, packaging='jar', version='LATEST', destination=nil, overrides={}, ssl_verify=true)
- coordinates = build_coordinates(group_id, artifact_id, packaging, nil, version)
- nexus_remote(overrides, ssl_verify).pull_artifact(coordinates, destination)
+ def pull(logger, group_id, artifact_id, packaging='jar', classifier=nil, version='LATEST', destination_path=nil, 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)
end
def nexus_remote(overrides={}, ssl_verify=true)
nexus_remote ||= NexusCli::RemoteFactory.create(nexus_defaults.merge(overrides || {}), ssl_verify)
end
def nexus_defaults
{
- url: 'https://repository.sonatype.org',
- repository: 'central-proxy'
+ url: 'https://repository.sonatype.org',
+ repository: 'central-proxy'
}
end
protected
+ def pull_and_put_in_place(logger, coordinates, destination_path=nil, skip_top_dir=true, 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)
+
+ # 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]
+ else
+ FileUtils.mv info[:file_path], destination_path
+ 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)
+
+ if is_tgz
+ info[:file_name] = nil
+ info[:size] = nil
+ else
+ info[:file_name] = File.basename(destination)
+ end
+
+ logger.info "Successful installation of #{coordinates} to #{info[:file_path]}"
+ end
+ info
+ end
+
+ def pull_and_verify(logger, coordinates, destination_dir, 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)
+ 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']
+ # Can't check :(
+ if sha1_element.nil?
+ logger.warn("Unable to find sha1 in Nexus repo 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
+ end
+
def build_coordinates(group_id, artifact_id, packaging, classifier, version=nil)
if classifier.nil?
if version.nil?
"#{group_id}:#{artifact_id}:#{packaging}"
else
@@ -37,9 +132,37 @@
"#{group_id}:#{artifact_id}:#{packaging}:#{classifier}"
else
"#{group_id}:#{artifact_id}:#{packaging}:#{classifier}:#{version}"
end
end
+ end
+
+ # Magic methods...
+
+ def is_ruby_plugin_and_should_skip_top_dir(group_id, artifact_id)
+ # The second check is for custom ruby plugins
+ group_id == KILLBILL_RUBY_PLUGIN_GROUP_ID || artifact_id.include?('plugin')
+ end
+
+ def path_looks_like_a_directory(path)
+ # It already is!
+ return true if File.directory?(path)
+ # It already isn't!
+ return false if File.file?(path)
+
+ last_part = File.basename(path).downcase
+
+ %w(.pom .xml .war .jar .xsd .tar.gz .tgz .gz .zip).each do |classic_file_extension|
+ return false if last_part.end_with?(classic_file_extension)
+ end
+
+ # Known magic files
+ %w(root).each do |classic_filename|
+ return false if last_part == classic_filename
+ end
+
+ # Probably a directory
+ true
end
end
end
end