brew/Library/Homebrew/resource.rb

135 lines
3.1 KiB
Ruby
Raw Normal View History

2013-09-17 21:25:38 -05:00
require 'download_strategy'
require 'checksum'
require 'version'
# 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
attr_reader :name
2013-09-17 21:25:38 -05:00
attr_reader :checksum, :mirrors, :specs, :using
attr_writer :url, :checksum, :version
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
def initialize name=nil, &block
@name = name
@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?
end
def downloader
@downloader ||= download_strategy.new(download_name, self)
end
2013-09-17 21:25:40 -05:00
def download_name
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
def clear_cache
downloader.clear_cache
end
# Fetch, verify, and unpack the resource
def stage(target=nil, &block)
verify_download_integrity(fetch)
unpack(target, &block)
end
# 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 unpack(target=nil)
2013-10-02 22:01:09 -05:00
mktemp(download_name) do
downloader.stage
if block_given?
yield self
elsif target
target = Pathname.new(target) unless target.is_a? Pathname
target.install Dir['*']
end
end
end
Partial = Struct.new(:resource, :files)
def files(*files)
Partial.new(self, files)
end
# For brew-fetch and others.
def fetch
begin
# Ensure the cache exists
HOMEBREW_CACHE.mkpath
downloader.fetch
cached_download
rescue ErrorDuringExecution, CurlDownloadStrategyError => e
raise DownloadError.new(downloader.name)
end
end
def verify_download_integrity fn
if fn.respond_to?(:file?) && fn.file?
ohai "Verifying #{fn.basename} checksum" if ARGV.verbose?
fn.verify_checksum(checksum)
end
2013-09-17 21:25:38 -05:00
rescue ChecksumMissingError
opoo "Cannot verify integrity of #{fn.basename}"
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}"
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
@specs.merge!(specs)
@using = @specs.delete(:using)
2013-09-17 21:25:38 -05:00
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