mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
resource: allow patches to be applied
This commit is contained in:
parent
97f0ef4c49
commit
7c07ec5fc1
@ -119,7 +119,7 @@ class ExternalPatch
|
|||||||
|
|
||||||
def initialize(strip, &block)
|
def initialize(strip, &block)
|
||||||
@strip = strip
|
@strip = strip
|
||||||
@resource = Resource::Patch.new(&block)
|
@resource = Resource::PatchResource.new(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def external?
|
def external?
|
||||||
|
@ -8,13 +8,13 @@ require "version"
|
|||||||
class Resource
|
class Resource
|
||||||
include FileUtils
|
include FileUtils
|
||||||
|
|
||||||
attr_reader :mirrors, :specs, :using, :source_modified_time
|
attr_reader :mirrors, :specs, :using, :source_modified_time, :patches, :owner
|
||||||
attr_writer :version
|
attr_writer :version
|
||||||
attr_accessor :download_strategy, :checksum
|
attr_accessor :download_strategy, :checksum
|
||||||
|
|
||||||
# Formula name must be set after the DSL, as we have no access to the
|
# Formula name must be set after the DSL, as we have no access to the
|
||||||
# formula name before initialization of the formula
|
# formula name before initialization of the formula
|
||||||
attr_accessor :name, :owner
|
attr_accessor :name
|
||||||
|
|
||||||
class Download
|
class Download
|
||||||
def initialize(resource)
|
def initialize(resource)
|
||||||
@ -46,9 +46,15 @@ class Resource
|
|||||||
@specs = {}
|
@specs = {}
|
||||||
@checksum = nil
|
@checksum = nil
|
||||||
@using = nil
|
@using = nil
|
||||||
|
@patches = []
|
||||||
instance_eval(&block) if block_given?
|
instance_eval(&block) if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def owner=(owner)
|
||||||
|
@owner = owner
|
||||||
|
patches.each { |p| p.owner = owner }
|
||||||
|
end
|
||||||
|
|
||||||
def downloader
|
def downloader
|
||||||
download_strategy.new(download_name, Download.new(self))
|
download_strategy.new(download_name, Download.new(self))
|
||||||
end
|
end
|
||||||
@ -82,9 +88,24 @@ class Resource
|
|||||||
end
|
end
|
||||||
|
|
||||||
verify_download_integrity(fetch)
|
verify_download_integrity(fetch)
|
||||||
|
prepare_patches
|
||||||
unpack(target, &block)
|
unpack(target, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def prepare_patches
|
||||||
|
patches.grep(DATAPatch) { |p| p.path = owner.owner.path }
|
||||||
|
|
||||||
|
patches.each do |patch|
|
||||||
|
patch.verify_download_integrity(patch.fetch) if patch.external?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_patches
|
||||||
|
return if patches.empty?
|
||||||
|
ohai "Patching #{name}"
|
||||||
|
patches.each(&:apply)
|
||||||
|
end
|
||||||
|
|
||||||
# If a target is given, unpack there; else unpack to a temp folder.
|
# If a target is given, unpack there; else unpack to a temp folder.
|
||||||
# If block is given, yield to that block with |stage|, where stage
|
# If block is given, yield to that block with |stage|, where stage
|
||||||
# is a ResourceStagingContext.
|
# is a ResourceStagingContext.
|
||||||
@ -93,6 +114,7 @@ class Resource
|
|||||||
mktemp(download_name) do |staging|
|
mktemp(download_name) do |staging|
|
||||||
downloader.stage
|
downloader.stage
|
||||||
@source_modified_time = downloader.source_modified_time
|
@source_modified_time = downloader.source_modified_time
|
||||||
|
apply_patches
|
||||||
if block_given?
|
if block_given?
|
||||||
yield ResourceStageContext.new(self, staging)
|
yield ResourceStageContext.new(self, staging)
|
||||||
elsif target
|
elsif target
|
||||||
@ -154,6 +176,11 @@ class Resource
|
|||||||
mirrors << val
|
mirrors << val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def patch(strip = :p1, src = nil, &block)
|
||||||
|
p = Patch.create(strip, src, &block)
|
||||||
|
patches << p
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def detect_version(val)
|
def detect_version(val)
|
||||||
@ -174,7 +201,7 @@ class Resource
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Patch < Resource
|
class PatchResource < Resource
|
||||||
attr_reader :patch_files
|
attr_reader :patch_files
|
||||||
|
|
||||||
def initialize(&block)
|
def initialize(&block)
|
||||||
|
@ -48,7 +48,7 @@ describe Patch do
|
|||||||
subject { described_class.create(:p2, nil) }
|
subject { described_class.create(:p2, nil) }
|
||||||
|
|
||||||
context "empty patch" do
|
context "empty patch" do
|
||||||
its(:resource) { is_expected.to be_kind_of Resource::Patch }
|
its(:resource) { is_expected.to be_kind_of Resource::PatchResource }
|
||||||
its(:patch_files) { is_expected.to eq(subject.resource.patch_files) }
|
its(:patch_files) { is_expected.to eq(subject.resource.patch_files) }
|
||||||
its(:patch_files) { is_expected.to eq([]) }
|
its(:patch_files) { is_expected.to eq([]) }
|
||||||
end
|
end
|
||||||
|
@ -30,6 +30,17 @@ describe "patching" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
matcher :have_its_resource_patched do
|
||||||
|
match do |formula|
|
||||||
|
formula.brew do
|
||||||
|
formula.resources.first.stage Pathname.pwd/"resource_dir"
|
||||||
|
s = File.read("resource_dir/libexec/NOOP")
|
||||||
|
expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected"
|
||||||
|
expect(s).to include("ABCD"), "libexec/NOOP was not patched as expected"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
matcher :be_sequentially_patched do
|
matcher :be_sequentially_patched do
|
||||||
match do |formula|
|
match do |formula|
|
||||||
formula.brew do
|
formula.brew do
|
||||||
@ -73,6 +84,22 @@ describe "patching" do
|
|||||||
).to be_patched
|
).to be_patched
|
||||||
end
|
end
|
||||||
|
|
||||||
|
specify "single_patch_dsl_for_resource" do
|
||||||
|
expect(
|
||||||
|
formula do
|
||||||
|
resource "some_resource" do
|
||||||
|
url TESTBALL_URL
|
||||||
|
sha256 TESTBALL_SHA256
|
||||||
|
|
||||||
|
patch do
|
||||||
|
url PATCH_URL_A
|
||||||
|
sha256 PATCH_A_SHA256
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
).to have_its_resource_patched
|
||||||
|
end
|
||||||
|
|
||||||
specify "single_patch_dsl_with_apply" do
|
specify "single_patch_dsl_with_apply" do
|
||||||
expect(
|
expect(
|
||||||
formula do
|
formula do
|
||||||
|
@ -119,6 +119,31 @@ describe Resource do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#owner" do
|
||||||
|
it "sets the owner" do
|
||||||
|
owner = Object.new
|
||||||
|
subject.owner = owner
|
||||||
|
expect(subject.owner).to eq(owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets its owner to be the patches' owner" do
|
||||||
|
subject.patch(:p1) { url "file:///my.patch" }
|
||||||
|
owner = Object.new
|
||||||
|
subject.owner = owner
|
||||||
|
subject.patches.each do |p|
|
||||||
|
expect(p.resource.owner).to eq(owner)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#patch" do
|
||||||
|
it "adds a patch" do
|
||||||
|
subject.patch(:p1, :DATA)
|
||||||
|
expect(subject.patches.count).to eq(1)
|
||||||
|
expect(subject.patches.first.strip).to eq(:p1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
specify "#verify_download_integrity_missing" do
|
specify "#verify_download_integrity_missing" do
|
||||||
fn = Pathname.new("test")
|
fn = Pathname.new("test")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user