Support patching of git repositories as well
By simply sharing the utility function. In this way, we get
feature parity between git_repository and http_archive.
Fixes #4676.
Change-Id: I99b300e42b2f267d8d04fd965f09c24f3ae54f10
PiperOrigin-RevId: 187450644
diff --git a/src/test/shell/bazel/external_patching_test.sh b/src/test/shell/bazel/external_patching_test.sh
index fe5d4f2..820b859 100755
--- a/src/test/shell/bazel/external_patching_test.sh
+++ b/src/test/shell/bazel/external_patching_test.sh
@@ -110,6 +110,92 @@
grep -q 'env' $foopath || fail "expected unpatched file"
}
+test_patch_git() {
+ EXTREPODIR=`pwd`
+ export GIT_CONFIG_NOSYSTEM=YES
+
+ mkdir extgit
+ (cd extgit && git init \
+ && git config user.email 'me@example.com' \
+ && git config user.name 'E X Ample' )
+ cat > extgit/foo.sh <<'EOF'
+#!/usr/bin/env sh
+
+echo Here be dragons...
+EOF
+ (cd extgit
+ git add .
+ git commit --author="A U Thor <author@example.com>" -m 'initial commit'
+ git tag mytag)
+
+ # Test that the patches attribute of git_repository is honored
+ mkdir main
+ cd main
+ cat > patch_foo.sh <<'EOF'
+--- foo.sh.orig 2018-01-15 10:39:20.183909147 +0100
++++ foo.sh 2018-01-15 10:43:35.331566052 +0100
+@@ -1,3 +1,3 @@
+ #!/usr/bin/env sh
+
+-echo Here be dragons...
++echo There are dragons...
+EOF
+ cat > WORKSPACE <<EOF
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
+new_git_repository(
+ name="ext",
+ remote="file://${EXTREPODIR}/extgit/.git",
+ tag="mytag",
+ build_file_content="exports_files([\"foo.sh\"])",
+ patches = ["//:patch_foo.sh"],
+ patch_cmds = ["find . -name '*.sh' -exec sed -i.orig '1s|#!/usr/bin/env sh\$|/bin/sh\$|' {} +"],
+)
+EOF
+ cat > BUILD <<'EOF'
+genrule(
+ name = "foo",
+ outs = ["foo.sh"],
+ srcs = ["@ext//:foo.sh"],
+ cmd = "cp $< $@; chmod u+x $@",
+ executable = True,
+)
+EOF
+ bazel build :foo.sh
+ foopath=`bazel info bazel-genfiles`/foo.sh
+ grep -q 'There are' $foopath || fail "expected patch to be applied"
+ grep env $foopath && fail "expected patch commands to be executed" || :
+
+ # Verify that changes to the patch files trigger enough rebuilding
+ cat > patch_foo.sh <<'EOF'
+--- foo.sh.orig 2018-01-15 10:39:20.183909147 +0100
++++ foo.sh 2018-01-15 10:43:35.331566052 +0100
+@@ -1,3 +1,3 @@
+ #!/usr/bin/env sh
+
+-echo Here be dragons...
++echo completely differently patched
+EOF
+ bazel build :foo.sh
+ foopath=`bazel info bazel-genfiles`/foo.sh
+ grep -q 'differently patched' $foopath \
+ || fail "expected the new patch to be applied"
+
+ # Verify that changes to the patches attribute trigger enough rebuilding
+ cat > WORKSPACE <<EOF
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
+new_git_repository(
+ name="ext",
+ remote="file://${EXTREPODIR}/extgit/.git",
+ tag="mytag",
+ build_file_content="exports_files([\"foo.sh\"])",
+)
+EOF
+ bazel build :foo.sh
+ foopath=`bazel info bazel-genfiles`/foo.sh
+ grep -q 'Here be' $foopath || fail "expected unpatched file"
+ grep -q 'env' $foopath || fail "expected unpatched file"
+}
+
test_override_buildfile() {
## Verify that the BUILD file of an external repository can be overriden
## via the http_archive rule.
diff --git a/tools/build_defs/repo/git.bzl b/tools/build_defs/repo/git.bzl
index f146ef6..d9cf660 100644
--- a/tools/build_defs/repo/git.bzl
+++ b/tools/build_defs/repo/git.bzl
@@ -13,7 +13,8 @@
# limitations under the License.
"""Rules for cloning external git repositories."""
-load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile", "patch")
+
def _clone_or_update(ctx):
if ((not ctx.attr.tag and not ctx.attr.commit) or
@@ -86,9 +87,11 @@
fail('Exactly one of build_file and build_file_content must be provided.')
_clone_or_update(ctx)
workspace_and_buildfile(ctx)
+ patch(ctx)
def _git_repository_implementation(ctx):
_clone_or_update(ctx)
+ patch(ctx)
_common_attrs = {
@@ -98,7 +101,10 @@
'tag': attr.string(default=''),
'init_submodules': attr.bool(default=False),
'verbose': attr.bool(default=False),
- 'strip_prefix': attr.string(default='')
+ 'strip_prefix': attr.string(default=''),
+ 'patches': attr.label_list(default=[]),
+ 'patch_tool': attr.string(default="patch"),
+ 'patch_cmds': attr.string_list(default=[]),
}
@@ -144,6 +150,11 @@
remote: The URI of the remote Git repository.
strip_prefix: A directory prefix to strip from the extracted files.
+
+ patches: A list of files that are to be applied as patches after extracting
+ the archive.
+ patch_tool: the patch(1) utility to use.
+ patch_cmds: sequence of commands to be applied after patches are applied.
"""
git_repository = repository_rule(
@@ -174,4 +185,9 @@
wall-clock time.
strip_prefix: A directory prefix to strip from the extracted files.
+
+ patches: A list of files that are to be applied as patches after extracting
+ the archive.
+ patch_tool: the patch(1) utility to use.
+ patch_cmds: sequence of commands to be applied after patches are applied.
"""
diff --git a/tools/build_defs/repo/http.bzl b/tools/build_defs/repo/http.bzl
index 2247708..e396914 100644
--- a/tools/build_defs/repo/http.bzl
+++ b/tools/build_defs/repo/http.bzl
@@ -29,23 +29,7 @@
replace the native rules.
"""
-load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile")
-
-def _patch(ctx):
- """Implementation of patching an already extracted repository"""
- bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
- for patchfile in ctx.attr.patches:
- command = "{patchtool} -p0 < {patchfile}".format(
- patchtool=ctx.attr.patch_tool,
- patchfile=ctx.path(patchfile))
- st = ctx.execute([bash_exe, "-c", command])
- if st.return_code:
- fail("Error applying patch %s:\n%s" % (str(patchfile), st.stderr))
- for cmd in ctx.attr.patch_cmds:
- st = ctx.execute([bash_exe, "-c", cmd])
- if st.return_code:
- fail("Error applying patch command %s:\n%s%s"
- % (cmd, st.stdout, st.stderr))
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile", "patch")
def _http_archive_impl(ctx):
"""Implementation of the http_archive rule."""
@@ -74,7 +58,7 @@
ctx.download_and_extract(all_urls, "", ctx.attr.sha256, ctx.attr.type,
ctx.attr.strip_prefix)
- _patch(ctx)
+ patch(ctx)
workspace_and_buildfile(ctx)
_HTTP_FILE_BUILD = """
diff --git a/tools/build_defs/repo/utils.bzl b/tools/build_defs/repo/utils.bzl
index 5f72f64..b326a82 100644
--- a/tools/build_defs/repo/utils.bzl
+++ b/tools/build_defs/repo/utils.bzl
@@ -50,4 +50,20 @@
ctx.execute([bash_exe, "-c", "rm -f BUILD.bazel"])
ctx.file("BUILD", ctx.attr.build_file_content)
+def patch(ctx):
+ """Implementation of patching an already extracted repository"""
+ bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
+ for patchfile in ctx.attr.patches:
+ command = "{patchtool} -p0 < {patchfile}".format(
+ patchtool=ctx.attr.patch_tool,
+ patchfile=ctx.path(patchfile))
+ st = ctx.execute([bash_exe, "-c", command])
+ if st.return_code:
+ fail("Error applying patch %s:\n%s" % (str(patchfile), st.stderr))
+ for cmd in ctx.attr.patch_cmds:
+ st = ctx.execute([bash_exe, "-c", cmd])
+ if st.return_code:
+ fail("Error applying patch command %s:\n%s%s"
+ % (cmd, st.stdout, st.stderr))
+