2013-09-17 21:25:38 -05:00
|
|
|
require 'download_strategy'
|
|
|
|
require 'checksum'
|
|
|
|
require 'version'
|
|
|
|
|
2013-09-17 21:25:38 -05:00
|
|
|
# Resource is the fundamental representation of an external resource. The
|
|
|
|
# primary formula download, along with other declared resources, are instances
|
|
|
|
# of this class.
|
2013-08-06 19:52:58 -07:00
|
|
|
class Resource
|
|
|
|
include FileUtils
|
|
|
|
|
|
|
|
attr_reader :name
|
2013-09-17 21:25:38 -05:00
|
|
|
attr_reader :checksum, :mirrors, :specs, :using
|
2013-09-23 21:39:19 -05:00
|
|
|
attr_writer :url, :checksum, :version
|
2013-09-17 21:25:38 -05:00
|
|
|
|
2013-09-17 21:25:38 -05:00
|
|
|
# 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
|
|
|
|
|
2013-09-23 21:39:19 -05:00
|
|
|
def initialize name=nil, &block
|
2013-08-06 19:52:58 -07:00
|
|
|
@name = name
|
2013-09-23 21:39:19 -05:00
|
|
|
@url = nil
|
|
|
|
@version = nil
|
2013-09-17 21:25:38 -05:00
|
|
|
@mirrors = []
|
|
|
|
@specs = {}
|
|
|
|
@checksum = nil
|
|
|
|
@using = nil
|
2013-09-17 21:25:39 -05:00
|
|
|
instance_eval(&block) if block_given?
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
|
2013-09-17 21:25:38 -05:00
|
|
|
def downloader
|
|
|
|
@downloader ||= download_strategy.new(download_name, self)
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
|
2013-09-17 21:25:40 -05:00
|
|
|
def download_name
|
2013-09-23 21:39:19 -05:00
|
|
|
name.nil? ? owner.name : "#{owner.name}--#{name}"
|
2013-09-17 21:25:40 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def download_strategy
|
|
|
|
@download_strategy ||= DownloadStrategyDetector.detect(url, using)
|
|
|
|
end
|
|
|
|
|
|
|
|
def cached_download
|
|
|
|
downloader.cached_location
|
|
|
|
end
|
|
|
|
|
2013-08-06 19:52:58 -07:00
|
|
|
# Download the resource
|
|
|
|
# If a target is given, unpack there; else unpack to a temp folder
|
|
|
|
# If block is given, yield to that block
|
|
|
|
# A target or a block must be given, but not both
|
|
|
|
def stage(target=nil)
|
|
|
|
fetched = fetch
|
2013-09-16 10:58:47 +10:00
|
|
|
verify_download_integrity(fetched) if fetched.respond_to?(:file?) and fetched.file?
|
2013-10-02 22:01:09 -05:00
|
|
|
mktemp(download_name) do
|
2013-09-17 21:25:38 -05:00
|
|
|
downloader.stage
|
2013-08-06 19:52:58 -07:00
|
|
|
if block_given?
|
|
|
|
yield self
|
|
|
|
else
|
|
|
|
target.install Dir['*']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-17 21:25:43 -05:00
|
|
|
Partial = Struct.new(:resource, :files)
|
|
|
|
|
|
|
|
def files(*files)
|
|
|
|
Partial.new(self, files)
|
|
|
|
end
|
|
|
|
|
2013-08-06 19:52:58 -07:00
|
|
|
# For brew-fetch and others.
|
|
|
|
def fetch
|
|
|
|
# Ensure the cache exists
|
|
|
|
HOMEBREW_CACHE.mkpath
|
2013-09-17 21:25:38 -05:00
|
|
|
downloader.fetch
|
2013-08-06 19:52:58 -07:00
|
|
|
cached_download
|
|
|
|
end
|
|
|
|
|
|
|
|
def verify_download_integrity fn
|
2013-09-17 21:25:38 -05:00
|
|
|
fn.verify_checksum(checksum)
|
|
|
|
rescue ChecksumMissingError
|
2013-09-17 21:25:41 -05:00
|
|
|
opoo "Cannot verify integrity of #{fn.basename}"
|
2013-09-17 21:25:38 -05:00
|
|
|
puts "A checksum was not provided for this resource"
|
2013-09-17 21:25:38 -05:00
|
|
|
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
|
2013-08-06 19:52:58 -07:00
|
|
|
end
|
|
|
|
end
|