aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Library/Homebrew/exceptions.rb3
-rw-r--r--Library/Homebrew/patch.rb28
-rw-r--r--Library/Homebrew/resource.rb15
-rw-r--r--Library/Homebrew/test/lib/config.rb3
-rw-r--r--Library/Homebrew/test/patches/noop-c.diff9
-rw-r--r--Library/Homebrew/test/tarballs/testball-0.1-patches.tgzbin0 -> 368 bytes
-rw-r--r--Library/Homebrew/test/test_patch.rb25
-rw-r--r--Library/Homebrew/test/test_patching.rb124
8 files changed, 197 insertions, 10 deletions
diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb
index 6f2fb849c..36fd927db 100644
--- a/Library/Homebrew/exceptions.rb
+++ b/Library/Homebrew/exceptions.rb
@@ -441,6 +441,9 @@ class DuplicateResourceError < ArgumentError
end
end
+# raised when a single patch file is not found and apply hasn't been specified
+class MissingApplyError < RuntimeError ; end
+
class BottleVersionMismatchError < RuntimeError
def initialize(bottle_file, bottle_version, formula, formula_version)
super <<-EOS.undent
diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb
index 3c5bd42ea..ebfb8e347 100644
--- a/Library/Homebrew/patch.rb
+++ b/Library/Homebrew/patch.rb
@@ -112,7 +112,7 @@ class ExternalPatch
def initialize(strip, &block)
@strip = strip
- @resource = Resource.new("patch", &block)
+ @resource = Resource::Patch.new(&block)
end
def external?
@@ -127,9 +127,25 @@ class ExternalPatch
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 }
+ patch_dir = Pathname.pwd
+ if patch_files.empty?
+ children = patch_dir.children
+ if (children.count == 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
@@ -141,6 +157,10 @@ class ExternalPatch
resource.fetch
end
+ def patch_files
+ resource.patch_files
+ end
+
def verify_download_integrity(fn)
resource.verify_download_integrity(fn)
end
diff --git a/Library/Homebrew/resource.rb b/Library/Homebrew/resource.rb
index bc5d62aee..a15788fb3 100644
--- a/Library/Homebrew/resource.rb
+++ b/Library/Homebrew/resource.rb
@@ -165,4 +165,19 @@ class Resource
super(target/name)
end
end
+
+ class Patch < Resource
+ attr_reader :patch_files
+
+ def initialize(&block)
+ @patch_files = []
+ super "patch", &block
+ end
+
+ def apply(*paths)
+ paths.flatten!
+ @patch_files.concat(paths)
+ @patch_files.uniq!
+ end
+ end
end
diff --git a/Library/Homebrew/test/lib/config.rb b/Library/Homebrew/test/lib/config.rb
index 3f72a5764..39c4ae27f 100644
--- a/Library/Homebrew/test/lib/config.rb
+++ b/Library/Homebrew/test/lib/config.rb
@@ -21,3 +21,6 @@ HOMEBREW_LOGS = HOMEBREW_PREFIX.parent+"logs"
TESTBALL_SHA1 = "be478fd8a80fe7f29196d6400326ac91dad68c37"
TESTBALL_SHA256 = "91e3f7930c98d7ccfb288e115ed52d06b0e5bc16fec7dce8bdda86530027067b"
+TESTBALL_PATCHES_SHA256 = "799c2d551ac5c3a5759bea7796631a7906a6a24435b52261a317133a0bfb34d9"
+PATCH_A_SHA256 = "83404f4936d3257e65f176c4ffb5a5b8d6edd644a21c8d8dcc73e22a6d28fcfa"
+PATCH_B_SHA256 = "57958271bb802a59452d0816e0670d16c8b70bdf6530bcf6f78726489ad89b90"
diff --git a/Library/Homebrew/test/patches/noop-c.diff b/Library/Homebrew/test/patches/noop-c.diff
new file mode 100644
index 000000000..6d0de5b7b
--- /dev/null
+++ b/Library/Homebrew/test/patches/noop-c.diff
@@ -0,0 +1,9 @@
+diff --git a/libexec/NOOP b/libexec/NOOP
+index e08d8f4..3ebfb9d 100755
+--- a/libexec/NOOP
++++ b/libexec/NOOP
+@@ -1,2 +1,2 @@
+ #!/bin/bash
+-echo ABCD
+\ No newline at end of file
++echo 1234
diff --git a/Library/Homebrew/test/tarballs/testball-0.1-patches.tgz b/Library/Homebrew/test/tarballs/testball-0.1-patches.tgz
new file mode 100644
index 000000000..4b43f535e
--- /dev/null
+++ b/Library/Homebrew/test/tarballs/testball-0.1-patches.tgz
Binary files differ
diff --git a/Library/Homebrew/test/test_patch.rb b/Library/Homebrew/test/test_patch.rb
index 0d0033ee1..3c6743ded 100644
--- a/Library/Homebrew/test/test_patch.rb
+++ b/Library/Homebrew/test/test_patch.rb
@@ -128,3 +128,28 @@ class ExternalPatchTests < Homebrew::TestCase
assert_equal "/tmp/foo.tar.gz", @p.cached_download
end
end
+
+class ApplyPatchTests < Homebrew::TestCase
+ def test_empty_patch_files
+ patch = Patch.create(:p2, nil)
+ resource = patch.resource
+ patch_files = patch.patch_files
+ assert_kind_of Resource::Patch, resource
+ assert_equal patch_files, resource.patch_files
+ assert_equal patch_files, []
+ end
+
+ def test_resource_patch_apply_method
+ patch = Patch.create(:p2, nil)
+ resource = patch.resource
+ patch_files = patch.patch_files
+ resource.apply("patch1.diff")
+ assert_equal patch_files, ["patch1.diff"]
+ resource.apply("patch2.diff", "patch3.diff")
+ assert_equal patch_files, ["patch1.diff", "patch2.diff", "patch3.diff"]
+ resource.apply(["patch4.diff", "patch5.diff"])
+ assert_equal patch_files.count, 5
+ resource.apply("patch4.diff", ["patch5.diff", "patch6.diff"], "patch7.diff")
+ assert_equal patch_files.count, 7
+ end
+end
diff --git a/Library/Homebrew/test/test_patching.rb b/Library/Homebrew/test/test_patching.rb
index 3c307a43f..8a18125ef 100644
--- a/Library/Homebrew/test/test_patching.rb
+++ b/Library/Homebrew/test/test_patching.rb
@@ -2,15 +2,20 @@ require "testing_env"
require "formula"
class PatchingTests < Homebrew::TestCase
+ TESTBALL_URL = "file://#{TEST_DIRECTORY}/tarballs/testball-0.1.tbz"
+ TESTBALL_PATCHES_URL = "file://#{TEST_DIRECTORY}/tarballs/testball-0.1-patches.tgz"
PATCH_URL_A = "file://#{TEST_DIRECTORY}/patches/noop-a.diff"
PATCH_URL_B = "file://#{TEST_DIRECTORY}/patches/noop-b.diff"
PATCH_A_CONTENTS = File.read "#{TEST_DIRECTORY}/patches/noop-a.diff"
PATCH_B_CONTENTS = File.read "#{TEST_DIRECTORY}/patches/noop-b.diff"
+ APPLY_A = "noop-a.diff"
+ APPLY_B = "noop-b.diff"
+ APPLY_C = "noop-c.diff"
def formula(*args, &block)
super do
- url "file://#{TEST_DIRECTORY}/tarballs/testball-0.1.tbz"
- sha1 TESTBALL_SHA1
+ url TESTBALL_URL
+ sha256 TESTBALL_SHA256
class_eval(&block)
end
end
@@ -31,6 +36,28 @@ class PatchingTests < Homebrew::TestCase
end
end
+ def assert_sequentially_patched(formula)
+ shutup do
+ formula.brew do
+ formula.patch
+ s = File.read("libexec/NOOP")
+ refute_includes s, "NOOP", "libexec/NOOP was not patched as expected"
+ refute_includes s, "ABCD", "libexec/NOOP was not patched as expected"
+ assert_includes s, "1234", "libexec/NOOP was not patched as expected"
+ end
+ end
+ end
+
+ def assert_missing_apply_fail(formula)
+ assert_raises(MissingApplyError) do
+ shutup do
+ formula.brew do
+ formula.patch
+ end
+ end
+ end
+ end
+
def test_single_patch
assert_patched formula {
def patches
@@ -43,7 +70,27 @@ class PatchingTests < Homebrew::TestCase
assert_patched formula {
patch do
url PATCH_URL_A
- sha1 "fa8af2e803892e523fdedc6b758117c45e5749a2"
+ sha256 PATCH_A_SHA256
+ end
+ }
+ end
+
+ def test_single_patch_dsl_with_apply
+ assert_patched formula {
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
+ end
+ }
+ end
+
+ def test_single_patch_dsl_with_sequential_apply
+ assert_sequentially_patched formula {
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A, APPLY_C
end
}
end
@@ -52,7 +99,17 @@ class PatchingTests < Homebrew::TestCase
assert_patched formula {
patch :p1 do
url PATCH_URL_A
- sha1 "fa8af2e803892e523fdedc6b758117c45e5749a2"
+ sha256 PATCH_A_SHA256
+ end
+ }
+ end
+
+ def test_single_patch_dsl_with_strip_with_apply
+ assert_patched formula {
+ patch :p1 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
end
}
end
@@ -63,7 +120,21 @@ class PatchingTests < Homebrew::TestCase
formula do
patch :p0 do
url PATCH_URL_A
- sha1 "fa8af2e803892e523fdedc6b758117c45e5749a2"
+ sha256 PATCH_A_SHA256
+ end
+ end.brew(&:patch)
+ end
+ end
+ end
+
+ def test_single_patch_dsl_with_incorrect_strip_with_apply
+ assert_raises(ErrorDuringExecution) do
+ shutup do
+ formula do
+ patch :p0 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_A
end
end.brew(&:patch)
end
@@ -74,11 +145,21 @@ class PatchingTests < Homebrew::TestCase
assert_patched formula {
patch :p0 do
url PATCH_URL_B
- sha1 "3b54bd576f998ef6d6623705ee023b55062b9504"
+ sha256 PATCH_B_SHA256
end
}
end
+ def test_patch_p0_dsl_with_apply
+ assert_patched formula {
+ patch :p0 do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply APPLY_B
+ end
+ }
+ end
+
def test_patch_p0
assert_patched formula {
def patches
@@ -126,6 +207,37 @@ class PatchingTests < Homebrew::TestCase
end
}
end
+
+ def test_single_patch_missing_apply_fail
+ assert_missing_apply_fail formula {
+ def patches
+ TESTBALL_PATCHES_URL
+ end
+ }
+ end
+
+ def test_single_patch_dsl_missing_apply_fail
+ assert_missing_apply_fail formula {
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ end
+ }
+ end
+
+ def test_single_patch_dsl_with_apply_enoent_fail
+ assert_raises(ErrorDuringExecution) do
+ shutup do
+ formula do
+ patch do
+ url TESTBALL_PATCHES_URL
+ sha256 TESTBALL_PATCHES_SHA256
+ apply "patches/#{APPLY_A}"
+ end
+ end.brew(&:patch)
+ end
+ end
+ end
end
__END__