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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
require 'resource'
require 'stringio'
require 'erb'
class Patch
def self.create(strip, io=nil, &block)
case strip ||= :p1
when :DATA, IO, StringIO
IOPatch.new(strip, :p1)
when String
IOPatch.new(StringIO.new(strip), :p1)
when Symbol
case io
when :DATA, IO, StringIO
IOPatch.new(io, strip)
when String
IOPatch.new(StringIO.new(io), strip)
else
ExternalPatch.new(strip, &block)
end
else
raise ArgumentError, "unexpected value #{strip.inspect} for strip"
end
end
def self.normalize_legacy_patches(list)
patches = []
case list
when Hash
list
when Array, String, IO
{ :p1 => list }
else
{}
end.each_pair do |strip, urls|
urls = [urls] unless Array === urls
urls.each do |url|
case url
when IO
patch = IOPatch.new(url, strip)
else
patch = LegacyPatch.new(strip, url)
end
patches << patch
end
end
patches
end
attr_reader :whence
def external?
whence == :resource
end
end
class IOPatch < Patch
attr_writer :owner
attr_reader :strip
def initialize(io, strip)
@io = io
@strip = strip
@whence = :io
end
def apply
@io = DATA if @io == :DATA
data = @io.read
data.gsub!("HOMEBREW_PREFIX", HOMEBREW_PREFIX)
IO.popen("/usr/bin/patch -g 0 -f -#{strip}", "w") { |p| p.write(data) }
raise ErrorDuringExecution, "Applying DATA patch failed" unless $?.success?
ensure
# IO and StringIO cannot be marshaled, so remove the reference
# in case we are indirectly referenced by an exception later.
@io = nil
end
def inspect
"#<#{self.class.name}: #{strip.inspect}>"
end
end
class ExternalPatch < Patch
attr_reader :resource, :strip
def initialize(strip, &block)
@strip = strip
@resource = Resource.new("patch", &block)
@whence = :resource
end
def owner= owner
resource.owner = owner
resource.version = resource.checksum || ERB::Util.url_encode(resource.url)
end
def apply
dir = Pathname.pwd
resource.unpack do
# Assumption: the only file in the staging directory is the patch
patchfile = Pathname.pwd.children.first
safe_system "/usr/bin/patch", "-g", "0", "-f", "-d", dir, "-#{strip}", "-i", patchfile
end
end
def url
resource.url
end
def fetch
resource.fetch
end
def verify_download_integrity(fn)
resource.verify_download_integrity(fn)
end
def cached_download
resource.cached_download
end
def clear_cache
resource.clear_cache
end
def inspect
"#<#{self.class.name}: #{strip.inspect} #{url.inspect}>"
end
end
# Legacy patches have no checksum and are not cached
class LegacyPatch < ExternalPatch
def initialize(strip, url)
super(strip)
resource.url = url
resource.download_strategy = CurlDownloadStrategy
end
def fetch
clear_cache
super
end
def verify_download_integrity(fn)
# no-op
end
def apply
super
ensure
clear_cache
end
end
|