diff --git a/Library/Homebrew/compat/md5.rb b/Library/Homebrew/compat/md5.rb index d600bab6d2..55383f0c14 100644 --- a/Library/Homebrew/compat/md5.rb +++ b/Library/Homebrew/compat/md5.rb @@ -1,11 +1,17 @@ class Formula def self.md5(val) - @stable ||= SoftwareSpec.new + @stable ||= create_spec(SoftwareSpec) @stable.md5(val) end end class SoftwareSpec + def md5(val) + @resource.md5(val) + end +end + +class Resource def md5(val) @checksum = Checksum.new(:md5, val) end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 813aeaff0e..db0e9e02bb 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1,5 +1,4 @@ require 'resource' -require 'download_strategy' require 'dependency_collector' require 'formula_support' require 'formula_lock' @@ -49,7 +48,7 @@ class Formula @active_spec = determine_active_spec validate_attributes :url, :name, :version - @downloader = active_spec.download_strategy.new(name, active_spec) + @downloader = active_spec.downloader # Combine DSL `option` and `def options` options.each do |opt, desc| @@ -60,15 +59,14 @@ class Formula @pin = FormulaPin.new(self) @resources = self.class.resources - @resources.each_value do |r| - r.set_owner name - end + @resources.each_value { |r| r.owner = self } end def set_spec(name) spec = self.class.send(name) return if spec.nil? if block_given? && yield(spec) || !spec.url.nil? + spec.owner = self instance_variable_set("@#{name}", spec) end end @@ -515,10 +513,7 @@ class Formula # For brew-fetch and others. def fetch - # Ensure the cache exists - HOMEBREW_CACHE.mkpath - downloader.fetch - cached_download + active_spec.fetch end # For FormulaInstaller. @@ -610,11 +605,7 @@ class Formula private def stage - fetched = fetch - verify_download_integrity(fetched) if fetched.respond_to?(:file?) and fetched.file? - mktemp do - downloader.stage - # Set path after the downloader changes the working folder. + active_spec.stage do @buildpath = Pathname.pwd yield @buildpath = nil diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb index df5eef9d26..ee04014a87 100644 --- a/Library/Homebrew/resource.rb +++ b/Library/Homebrew/resource.rb @@ -2,32 +2,35 @@ require 'download_strategy' require 'checksum' require 'version' -# A Resource describes a tarball that a formula needs in addition -# to the formula's own download. +# Resource is the fundamental representation of an external resource. The +# primary formula download, along with other declared resources, are instances +# of this class. class Resource include FileUtils - # The mktmp mixin expects a name property - # This is the resource name attr_reader :name - attr_reader :checksum, :mirrors, :specs, :using - def initialize name + # Formula name must be set after the DSL, as we have no access to the + # formula name before initialization of the formula + attr_accessor :owner + + # XXX: for bottles, address this later + attr_writer :url, :checksum + + def initialize name, url=nil, version=nil @name = name - @url = nil - @version = nil + @url = url + @version = version @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 = download_strategy.new("#{owner}--#{name}", self) + def downloader + download_name = name == :default ? owner.name : "#{owner.name}--#{name}" + @downloader ||= download_strategy.new(download_name, self) end # Download the resource @@ -38,7 +41,7 @@ class Resource fetched = fetch verify_download_integrity(fetched) if fetched.respond_to?(:file?) and fetched.file? mktemp do - @downloader.stage + downloader.stage if block_given? yield self else @@ -52,22 +55,22 @@ class Resource end def cached_download - @downloader.cached_location + downloader.cached_location end # For brew-fetch and others. def fetch # Ensure the cache exists HOMEBREW_CACHE.mkpath - @downloader.fetch + downloader.fetch cached_download end def verify_download_integrity fn fn.verify_checksum(checksum) rescue ChecksumMissingError - opoo "Cannot verify package integrity" - puts "The formula did not provide a download checksum" + opoo "Cannot verify download integrity" + puts "A checksum was not provided for this resource" puts "For your reference the SHA1 is: #{fn.sha1}" rescue ChecksumMismatchError => e e.advice = <<-EOS.undent diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index 856fe40715..6f8191f78e 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -1,69 +1,19 @@ -require 'download_strategy' +require 'forwardable' +require 'resource' require 'checksum' require 'version' class SoftwareSpec - attr_reader :checksum, :mirrors, :specs, :using + extend Forwardable + + def_delegators :@resource, :owner= + def_delegators :@resource, :stage, :fetch + def_delegators :@resource, :download_strategy, :verify_download_integrity + def_delegators :@resource, :checksum, :mirrors, :specs, :using, :downloader + def_delegators :@resource, :url, :version, :mirror, *Checksum::TYPES def initialize url=nil, version=nil - @url = url - @version = version - @mirrors = [] - @specs = {} - @checksum = nil - @using = nil - end - - def download_strategy - @download_strategy ||= DownloadStrategyDetector.detect(url, using) - end - - def 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 - - 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 - - # The methods that follow are used in the block-form DSL spec methods - 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 + @resource = Resource.new(:default, url, version) end end @@ -78,9 +28,10 @@ class HeadSoftwareSpec < SoftwareSpec end class Bottle < SoftwareSpec - attr_writer :url attr_rw :root_url, :prefix, :cellar, :revision + def_delegators :@resource, :url= + def initialize super @revision = 0 @@ -102,7 +53,7 @@ class Bottle < SoftwareSpec end if @#{cksum}.has_key? bottle_tag - @checksum = @#{cksum}[bottle_tag] + @resource.checksum = @#{cksum}[bottle_tag] end end EOS