From eb3071332c07c7841c44020e2a644889d131f0c6 Mon Sep 17 00:00:00 2001 From: Jack Nagel Date: Tue, 17 Sep 2013 21:25:38 -0500 Subject: [PATCH] Decouple Resource from SoftwareSpec --- Library/Homebrew/formula.rb | 10 +++--- Library/Homebrew/resource.rb | 68 +++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index a3e5ef656b..813aeaff0e 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -720,11 +720,11 @@ class Formula end # Define a named resource using a SoftwareSpec style block - def resource res_name, &block - raise DuplicateResourceError.new(res_name) if resources.has_key?(res_name) - spec = SoftwareSpec.new - spec.instance_eval(&block) - resources[res_name] = Resource.new(res_name, spec) + def resource name, &block + raise DuplicateResourceError.new(name) if resources.has_key?(name) + resource = Resource.new(name) + resource.instance_eval(&block) + resources[name] = resource end def dependencies diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index 02de04214d..df5eef9d26 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -1,3 +1,7 @@ +require 'download_strategy' +require 'checksum' +require 'version' + # A Resource describes a tarball that a formula needs in addition # to the formula's own download. class Resource @@ -7,16 +11,23 @@ class Resource # This is the resource name attr_reader :name - def initialize name, spec + attr_reader :checksum, :mirrors, :specs, :using + + def initialize name @name = name - @spec = spec + @url = nil + @version = nil + @mirrors = [] + @specs = {} + @checksum = nil + @using = nil end # Formula name must be set after the DSL, as we have no access to the # formula name before initialization of the formula def set_owner owner @owner = owner - @downloader = @spec.download_strategy.new("#{owner}--#{name}", @spec) + @downloader = download_strategy.new("#{owner}--#{name}", self) end # Download the resource @@ -36,6 +47,10 @@ class Resource end end + def download_strategy + @download_strategy ||= DownloadStrategyDetector.detect(url, using) + end + def cached_download @downloader.cached_location end @@ -49,6 +64,51 @@ class Resource end def verify_download_integrity fn - @spec.verify_download_integrity(fn) + fn.verify_checksum(checksum) + rescue ChecksumMissingError + opoo "Cannot verify package integrity" + puts "The formula did not provide a download checksum" + puts "For your reference the SHA1 is: #{fn.sha1}" + rescue ChecksumMismatchError => e + e.advice = <<-EOS.undent + Archive: #{fn} + (To retry an incomplete download, remove the file above.) + EOS + raise e + end + + Checksum::TYPES.each do |cksum| + class_eval <<-EOS, __FILE__, __LINE__ + 1 + def #{cksum}(val) + @checksum = Checksum.new(:#{cksum}, val) + end + EOS + end + + def url val=nil, specs={} + return @url if val.nil? + @url = val + @using = specs.delete(:using) + @specs.merge!(specs) + end + + def version val=nil + @version ||= detect_version(val) + end + + def mirror val + mirrors << val + end + + private + + def detect_version(val) + case val + when nil then Version.detect(url, specs) + when String then Version.new(val) + when Hash then Version.new_with_scheme(*val.shift) + else + raise TypeError, "version '#{val.inspect}' should be a string" + end end end