mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
183 lines
3.2 KiB
Ruby
183 lines
3.2 KiB
Ruby
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, args = "/usr/bin/patch", %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.new("patch", &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
|
|
# Assumption: the only file in the staging directory is the patch
|
|
patchfile = Pathname.pwd.children.first
|
|
dir.cd { safe_system "/usr/bin/patch", "-g", "0", "-f", "-#{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
|