From a03d65b5c964a9981f15f36f70a55bd94e073685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kryger?= Date: Wed, 23 Oct 2024 12:37:53 +0100 Subject: [PATCH 1/5] Allow HOMEBREW_PREFIX replacement in external patches This fixes #15925 --- Library/Homebrew/patch.rb | 10 +++++-- Library/Homebrew/test/patching_spec.rb | 27 ++++++++++++++++++- .../test/support/fixtures/patches/noop-d.diff | 10 +++++++ .../test/support/lib/startup/config.rb | 1 + docs/Formula-Cookbook.md | 2 +- 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 Library/Homebrew/test/support/fixtures/patches/noop-d.diff diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 39e67b1d24031..0894262ac8097 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -94,7 +94,7 @@ def contents end end -# A string containing a patch. +# A file containing a patch. class ExternalPatch extend Forwardable @@ -140,7 +140,13 @@ def apply patch_files.each do |patch_file| ohai "Applying #{patch_file}" patch_file = patch_dir/patch_file - safe_system "patch", "-g", "0", "-f", "-#{strip}", "-i", patch_file + args = %W[-g 0 -f -#{strip}] + Utils.safe_popen_write("patch", *args) do |p| + File.foreach(patch_file) do |line| + data = line.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX) + p.write(data) + end + end end end end diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb index 74171d053528e..d4314021d59b1 100644 --- a/Library/Homebrew/test/patching_spec.rb +++ b/Library/Homebrew/test/patching_spec.rb @@ -11,11 +11,13 @@ TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze + PATCH_URL_D = "file://#{TEST_FIXTURE_DIR}/patches/noop-d.diff".freeze PATCH_A_CONTENTS = File.read("#{TEST_FIXTURE_DIR}/patches/noop-a.diff").freeze PATCH_B_CONTENTS = File.read("#{TEST_FIXTURE_DIR}/patches/noop-b.diff").freeze APPLY_A = "noop-a.diff" APPLY_B = "noop-b.diff" APPLY_C = "noop-c.diff" + APPLY_D = "noop-d.diff" # rubocop:enable RSpec/LeakyConstantDeclaration,Lint/ConstantDefinitionInBlock url TESTBALL_URL @@ -39,6 +41,18 @@ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stabl end end + matcher :be_patched_with_homebrew_prefix do + match do |formula| + formula.brew do + formula.patch + s = File.read("libexec/NOOP") + expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected" + expect(s).not_to include("HOMEBREW_PREFIX"), "libexec/NOOP was not patched as expected" + expect(s).to include(HOMEBREW_PREFIX.to_s), "libexec/NOOP was not patched as expected" + end + end + end + matcher :have_its_resource_patched do match do |formula| formula.brew do @@ -226,6 +240,17 @@ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stabl end f.brew { |formula, _staging| formula.patch } - end.to raise_error(BuildError) + end.to raise_error(Errno::ENOENT) + end + + specify "patch_dsl_with_homebrew_prefix" do + expect( + formula do + patch do + url PATCH_URL_D + sha256 PATCH_D_SHA256 + end + end, + ).to be_patched_with_homebrew_prefix end end diff --git a/Library/Homebrew/test/support/fixtures/patches/noop-d.diff b/Library/Homebrew/test/support/fixtures/patches/noop-d.diff new file mode 100644 index 0000000000000..d83a684fe5d1e --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/patches/noop-d.diff @@ -0,0 +1,10 @@ +diff --git a/libexec/NOOP b/libexec/NOOP +index bfdda4c..e08d8f4 100755 +--- a/libexec/NOOP ++++ b/libexec/NOOP +@@ -1,2 +1,2 @@ + #!/bin/bash +-echo NOOP +\ No newline at end of file ++echo HOMEBREW_PREFIX +\ No newline at end of file diff --git a/Library/Homebrew/test/support/lib/startup/config.rb b/Library/Homebrew/test/support/lib/startup/config.rb index 8bbba31ea374c..0b64947dd9609 100644 --- a/Library/Homebrew/test/support/lib/startup/config.rb +++ b/Library/Homebrew/test/support/lib/startup/config.rb @@ -47,5 +47,6 @@ TESTBALL_PATCHES_SHA256 = "799c2d551ac5c3a5759bea7796631a7906a6a24435b52261a317133a0bfb34d9" PATCH_A_SHA256 = "83404f4936d3257e65f176c4ffb5a5b8d6edd644a21c8d8dcc73e22a6d28fcfa" PATCH_B_SHA256 = "57958271bb802a59452d0816e0670d16c8b70bdf6530bcf6f78726489ad89b90" +PATCH_D_SHA256 = "29946529088576919b0a56146c346e63692832ab3568cc34fed647c3e4dc2072" TEST_SHA256 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md index e784152cd031d..a4073ab4ae8f7 100644 --- a/docs/Formula-Cookbook.md +++ b/docs/Formula-Cookbook.md @@ -639,7 +639,7 @@ Patches can also be embedded by passing a string. This makes it possible to prov patch :p0, "..." ``` -In embedded patches, the string "HOMEBREW\_PREFIX" is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. +In patches, the string "HOMEBREW\_PREFIX" is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. ### Creating the diff From 13a26d55170e5e50245b7462d55ab94871880453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kryger?= Date: Wed, 23 Oct 2024 16:26:14 +0100 Subject: [PATCH 2/5] Use patch arguments directly Co-authored-by: Mike McQuaid --- Library/Homebrew/patch.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 0894262ac8097..510f4e0f9a216 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -140,8 +140,7 @@ def apply patch_files.each do |patch_file| ohai "Applying #{patch_file}" patch_file = patch_dir/patch_file - args = %W[-g 0 -f -#{strip}] - Utils.safe_popen_write("patch", *args) do |p| + Utils.safe_popen_write("patch", "-g", "0", "-f", "-#{strip}") do |p| File.foreach(patch_file) do |line| data = line.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX) p.write(data) From ff03947ba0aab28c8fadfef70d34c6b6f49408ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kryger?= Date: Wed, 23 Oct 2024 16:51:01 +0100 Subject: [PATCH 3/5] Use @@HOMEBREW_PREFIX@@ for replacements in external patches --- Library/Homebrew/patch.rb | 2 +- Library/Homebrew/test/patching_spec.rb | 2 +- Library/Homebrew/test/support/fixtures/patches/noop-d.diff | 2 +- Library/Homebrew/test/support/lib/startup/config.rb | 2 +- docs/Formula-Cookbook.md | 4 +++- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb index 510f4e0f9a216..488982bf8eaec 100644 --- a/Library/Homebrew/patch.rb +++ b/Library/Homebrew/patch.rb @@ -142,7 +142,7 @@ def apply patch_file = patch_dir/patch_file Utils.safe_popen_write("patch", "-g", "0", "-f", "-#{strip}") do |p| File.foreach(patch_file) do |line| - data = line.gsub("HOMEBREW_PREFIX", HOMEBREW_PREFIX) + data = line.gsub("@@HOMEBREW_PREFIX@@", HOMEBREW_PREFIX) p.write(data) end end diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb index d4314021d59b1..c4818cc250928 100644 --- a/Library/Homebrew/test/patching_spec.rb +++ b/Library/Homebrew/test/patching_spec.rb @@ -47,7 +47,7 @@ def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stabl formula.patch s = File.read("libexec/NOOP") expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected" - expect(s).not_to include("HOMEBREW_PREFIX"), "libexec/NOOP was not patched as expected" + expect(s).not_to include("@@HOMEBREW_PREFIX@@"), "libexec/NOOP was not patched as expected" expect(s).to include(HOMEBREW_PREFIX.to_s), "libexec/NOOP was not patched as expected" end end diff --git a/Library/Homebrew/test/support/fixtures/patches/noop-d.diff b/Library/Homebrew/test/support/fixtures/patches/noop-d.diff index d83a684fe5d1e..5c40b3a7eabd7 100644 --- a/Library/Homebrew/test/support/fixtures/patches/noop-d.diff +++ b/Library/Homebrew/test/support/fixtures/patches/noop-d.diff @@ -6,5 +6,5 @@ index bfdda4c..e08d8f4 100755 #!/bin/bash -echo NOOP \ No newline at end of file -+echo HOMEBREW_PREFIX ++echo @@HOMEBREW_PREFIX@@ \ No newline at end of file diff --git a/Library/Homebrew/test/support/lib/startup/config.rb b/Library/Homebrew/test/support/lib/startup/config.rb index 0b64947dd9609..a5c858723bceb 100644 --- a/Library/Homebrew/test/support/lib/startup/config.rb +++ b/Library/Homebrew/test/support/lib/startup/config.rb @@ -47,6 +47,6 @@ TESTBALL_PATCHES_SHA256 = "799c2d551ac5c3a5759bea7796631a7906a6a24435b52261a317133a0bfb34d9" PATCH_A_SHA256 = "83404f4936d3257e65f176c4ffb5a5b8d6edd644a21c8d8dcc73e22a6d28fcfa" PATCH_B_SHA256 = "57958271bb802a59452d0816e0670d16c8b70bdf6530bcf6f78726489ad89b90" -PATCH_D_SHA256 = "29946529088576919b0a56146c346e63692832ab3568cc34fed647c3e4dc2072" +PATCH_D_SHA256 = "07c72c4463339e6e2ce235f3b26e316d4940017bf4b5236e27e757a44d67636c" TEST_SHA256 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md index a4073ab4ae8f7..b62706023446d 100644 --- a/docs/Formula-Cookbook.md +++ b/docs/Formula-Cookbook.md @@ -639,7 +639,9 @@ Patches can also be embedded by passing a string. This makes it possible to prov patch :p0, "..." ``` -In patches, the string "HOMEBREW\_PREFIX" is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. +In embedded patches, the string "HOMEBREW\_PREFIX" is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. + +In external patches, the string "@@HOMEBREW\_PREFIX@@" is replaced with the value of the constant `HOMEBREW_PREFIX` before the patch is applied. ### Creating the diff From f31e93a73aab025e60a4a798031c73327cef45cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kryger?= Date: Thu, 24 Oct 2024 12:49:31 +0100 Subject: [PATCH 4/5] Disable audit_result in inreplace This is to allow migration of existing users of @@HOMEBREW_PREFIX@@ tag in external patches. Once the automatic replacement of the tag is in stable branch and existing users are fixed (inreplace calls removed), this commit can be reverted. --- Library/Homebrew/test/utils/inreplace_spec.rb | 2 +- Library/Homebrew/utils/inreplace.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/test/utils/inreplace_spec.rb b/Library/Homebrew/test/utils/inreplace_spec.rb index a6b0a044b5d54..ba1e825a35397 100644 --- a/Library/Homebrew/test/utils/inreplace_spec.rb +++ b/Library/Homebrew/test/utils/inreplace_spec.rb @@ -25,7 +25,7 @@ it "raises error if there is nothing to replace" do expect do described_class.inreplace file.path, "d", "f" - end.to raise_error(Utils::Inreplace::Error) + end.not_to raise_error(Utils::Inreplace::Error) end it "raises error if there is nothing to replace in block form" do diff --git a/Library/Homebrew/utils/inreplace.rb b/Library/Homebrew/utils/inreplace.rb index a7e3e9bddf6ff..504fa6748c003 100644 --- a/Library/Homebrew/utils/inreplace.rb +++ b/Library/Homebrew/utils/inreplace.rb @@ -50,7 +50,7 @@ def initialize(errors) block: T.nilable(T.proc.params(s: StringInreplaceExtension).void), ).void } - def self.inreplace(paths, before = nil, after = nil, audit_result: true, &block) + def self.inreplace(paths, before = nil, after = nil, audit_result: false, &block) paths = Array(paths) after &&= after.to_s before = before.to_s if before.is_a?(Pathname) From 2225af5bef50cc47a3f4e0f22a3bdf333e6b139b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Kryger?= Date: Fri, 25 Oct 2024 15:26:03 +0100 Subject: [PATCH 5/5] Revert "Disable audit_result in inreplace" This reverts commit f31e93a73aab025e60a4a798031c73327cef45cb. --- Library/Homebrew/test/utils/inreplace_spec.rb | 2 +- Library/Homebrew/utils/inreplace.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/test/utils/inreplace_spec.rb b/Library/Homebrew/test/utils/inreplace_spec.rb index ba1e825a35397..a6b0a044b5d54 100644 --- a/Library/Homebrew/test/utils/inreplace_spec.rb +++ b/Library/Homebrew/test/utils/inreplace_spec.rb @@ -25,7 +25,7 @@ it "raises error if there is nothing to replace" do expect do described_class.inreplace file.path, "d", "f" - end.not_to raise_error(Utils::Inreplace::Error) + end.to raise_error(Utils::Inreplace::Error) end it "raises error if there is nothing to replace in block form" do diff --git a/Library/Homebrew/utils/inreplace.rb b/Library/Homebrew/utils/inreplace.rb index 504fa6748c003..a7e3e9bddf6ff 100644 --- a/Library/Homebrew/utils/inreplace.rb +++ b/Library/Homebrew/utils/inreplace.rb @@ -50,7 +50,7 @@ def initialize(errors) block: T.nilable(T.proc.params(s: StringInreplaceExtension).void), ).void } - def self.inreplace(paths, before = nil, after = nil, audit_result: false, &block) + def self.inreplace(paths, before = nil, after = nil, audit_result: true, &block) paths = Array(paths) after &&= after.to_s before = before.to_s if before.is_a?(Pathname)