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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
require "resource"
require "erb"
module Patch
def self.create(strip, src, &block)
case strip
when :DATA
DATAPatch.new(:p1)
when String
StringPatch.new(:p1, strip)
when Symbol
case src
when :DATA
DATAPatch.new(strip)
when String
StringPatch.new(strip, src)
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, :DATA
{ :p1 => list }
else
{}
end.each_pair do |strip, urls|
Array(urls).each do |url|
case url
when :DATA
patch = DATAPatch.new(strip)
else
patch = LegacyPatch.new(strip, url)
end
patches << patch
end
end
patches
end
end
class EmbeddedPatch
attr_writer :owner
attr_reader :strip
def initialize(strip)
@strip = strip
end
def external?
false
end
def contents
end
def apply
data = contents.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX)
cmd = "/usr/bin/patch"
args = %W[-g 0 -f -#{strip}]
IO.popen("#{cmd} #{args.join(" ")}", "w") { |p| p.write(data) }
raise ErrorDuringExecution.new(cmd, args) unless $?.success?
end
def inspect
"#<#{self.class.name}: #{strip.inspect}>"
end
end
class DATAPatch < EmbeddedPatch
attr_accessor :path
def initialize(strip)
super
@path = nil
end
def contents
data = ""
path.open("rb") do |f|
begin
line = f.gets
end until line.nil? || /^__END__$/ === line
data << line while line = f.gets
end
data
end
end
class StringPatch < EmbeddedPatch
def initialize(strip, str)
super(strip)
@str = str
end
def contents
@str
end
end
class ExternalPatch
attr_reader :resource, :strip
def initialize(strip, &block)
@strip = strip
@resource = Resource::Patch.new(&block)
end
def external?
true
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
patch_dir = Pathname.pwd
if patch_files.empty?
children = patch_dir.children
if (children.length == 1 && children.first.file?)
patch_files << children.first.basename
else
raise MissingApplyError, <<-EOS.undent
There should be exactly one patch file in the staging directory unless
the "apply" method was used one or more times in the patch-do block.
EOS
end
end
dir.cd do
patch_files.each do |patch_file|
ohai "Applying #{patch_file}"
patch_file = patch_dir/patch_file
safe_system "/usr/bin/patch", "-g", "0", "-f", "-#{strip}", "-i", patch_file
end
end
end
end
def url
resource.url
end
def fetch
resource.fetch
end
def patch_files
resource.patch_files
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
|