1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
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 :checksum, :mirrors, :specs, :using
attr_writer :url, :checksum, :version
# Formula name must be set after the DSL, as we have no access to the
# formula name before initialization of the formula
attr_accessor :name, :owner
def initialize name=nil, &block
@name = name
@url = nil
@version = nil
@mirrors = []
@specs = {}
@checksum = nil
@using = nil
instance_eval(&block) if block_given?
end
def downloader
@downloader ||= download_strategy.new(download_name, self)
end
def download_name
name.nil? ? owner.name : "#{owner.name}--#{name}"
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)
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
# Ensure the cache exists
HOMEBREW_CACHE.mkpath
downloader.fetch
rescue ErrorDuringExecution, CurlDownloadStrategyError => e
raise DownloadError.new(self, e)
else
cached_download
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
rescue ChecksumMissingError
opoo "Cannot verify integrity of #{fn.basename}"
puts "A checksum was not provided for this resource"
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)
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
|