Skip to content

Commit

Permalink
external repos: add a Skylark library for common tasks
Browse files Browse the repository at this point in the history
...thus avoiding having them several times for the various repository
rules, each with slightly different behavior and bugs.

Change-Id: I6cec0c0dd0901453458903e226ceb2098a93cdd8
PiperOrigin-RevId: 187306904
  • Loading branch information
aehlig authored and Copybara-Service committed Feb 28, 2018
1 parent 2065d30 commit a22a287
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/test/shell/bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ sh_test(
size = "medium",
srcs = ["external_patching_test.sh"],
data = [":test-deps"],
shard_count = 3,
)

sh_test(
Expand Down
123 changes: 123 additions & 0 deletions src/test/shell/bazel/external_patching_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,129 @@ EOF
expect_not_log "BAD"
}

test_override_buildfile_git() {
## Verify that the BUILD file of an external repository can be overriden
## via the git_repository rule.
EXTREPODIR=`pwd`
export GIT_CONFIG_NOSYSTEM=YES

mkdir withbuild
(cd withbuild && git init)
cat > withbuild/BUILD.bazel <<'EOF'
genrule(
name="target",
srcs=["file.txt"],
outs=["target.txt"],
cmd="cp $< $@ && echo BAD >> $@",
visibility=["//visibility:public"],
)
EOF
cat > withbuild/file.txt <<'EOF'
from external repo
EOF
(cd withbuild
git add .
git commit --author="A U Thor <author@example.com>" -m 'initial commit'
git tag mytag)

mkdir main
cd main
cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
new_git_repository(
name="withbuild",
remote="file://${EXTREPODIR}/withbuild/.git",
tag="mytag",
build_file="@//:ext.BUILD",
)
EOF
cat > BUILD <<'EOF'
genrule(
name = "local",
outs = ["local.txt"],
srcs = ["@withbuild//:target"],
cmd = "cp $< $@",
)
EOF
cat > ext.BUILD <<'EOF'
genrule(
name="target",
srcs=["file.txt"],
outs=["target.txt"],
cmd="cp $< $@ && echo GOOD >> $@",
visibility=["//visibility:public"],
)
EOF

bazel build //:local || fail "Expected success"

cat `bazel info bazel-genfiles`/local.txt > "${TEST_log}"
expect_log "from external repo"
expect_log "GOOD"
expect_not_log "BAD"
}

test_override_buildfilecontents_git() {
## Verify that the BUILD file of an external repository can be overriden
## via specified content in the git_repository rule.
EXTREPODIR=`pwd`
export GIT_CONFIG_NOSYSTEM=YES

mkdir withbuild
(cd withbuild && git init)
cat > withbuild/BUILD.bazel <<'EOF'
genrule(
name="target",
srcs=["file.txt"],
outs=["target.txt"],
cmd="cp $< $@ && echo BAD >> $@",
visibility=["//visibility:public"],
)
EOF
cat > withbuild/file.txt <<'EOF'
from external repo
EOF
(cd withbuild
git add .
git commit --author="A U Thor <author@example.com>" -m 'initial commit'
git tag mytag)

mkdir main
cd main
cat > WORKSPACE <<EOF
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
new_git_repository(
name="withbuild",
remote="file://${EXTREPODIR}/withbuild/.git",
tag="mytag",
build_file_content="""
genrule(
name="target",
srcs=["file.txt"],
outs=["target.txt"],
cmd="cp \$< \$@ && echo GOOD >> \$@",
visibility=["//visibility:public"],
)
""",
)
EOF
cat > BUILD <<'EOF'
genrule(
name = "local",
outs = ["local.txt"],
srcs = ["@withbuild//:target"],
cmd = "cp $< $@",
)
EOF

bazel build //:local || fail "Expected success"

cat `bazel info bazel-genfiles`/local.txt > "${TEST_log}"
expect_log "from external repo"
expect_log "GOOD"
expect_not_log "BAD"
}

test_build_file_build_bazel() {
## Verify that the BUILD file of an external repository can be overriden
## via the http_archive rule.
Expand Down
8 changes: 3 additions & 5 deletions tools/build_defs/repo/git.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# limitations under the License.
"""Rules for cloning external git repositories."""

load("@bazel_tools//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile")

def _clone_or_update(ctx):
if ((not ctx.attr.tag and not ctx.attr.commit) or
(ctx.attr.tag and ctx.attr.commit)):
Expand Down Expand Up @@ -83,11 +85,7 @@ def _new_git_repository_implementation(ctx):
(ctx.attr.build_file and ctx.attr.build_file_content)):
fail('Exactly one of build_file and build_file_content must be provided.')
_clone_or_update(ctx)
ctx.file('WORKSPACE', 'workspace(name = \'{name}\')\n'.format(name=ctx.name))
if ctx.attr.build_file:
ctx.symlink(ctx.attr.build_file, 'BUILD.bazel')
else:
ctx.file('BUILD.bazel', ctx.attr.build_file_content)
workspace_and_buildfile(ctx)

def _git_repository_implementation(ctx):
_clone_or_update(ctx)
Expand Down
13 changes: 3 additions & 10 deletions tools/build_defs/repo/http.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ These rules are improved versions of the native http rules and will eventually
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"
Expand Down Expand Up @@ -73,16 +75,7 @@ def _http_archive_impl(ctx):
ctx.download_and_extract(all_urls, "", ctx.attr.sha256, ctx.attr.type,
ctx.attr.strip_prefix)
_patch(ctx)
ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name=ctx.name))
if ctx.attr.build_file:
bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
ctx.execute([bash_exe, "-c", "rm -f BUILD BUILD.bazel"])
ctx.symlink(ctx.attr.build_file, "BUILD")
elif ctx.attr.build_file_content:
bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
ctx.execute([bash_exe, "-c", "rm -f BUILD.bazel"])
ctx.file("BUILD", ctx.attr.build_file_content)

workspace_and_buildfile(ctx)

_HTTP_FILE_BUILD = """
package(default_visibility = ["//visibility:public"])
Expand Down
53 changes: 53 additions & 0 deletions tools/build_defs/repo/utils.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utils for manipulating external repositories, once fetched.
### Setup
These utility are intended to be used by other repository rules. They
can be loaded as follows.
```python
load(
"@bazel_tools//tools/build_defs/repo:utils.bzl",
"workspace_and_buildfile",
)
```
"""

def workspace_and_buildfile(ctx):
"""Utility function for writing WORKSPACE and, if requested, a BUILD file.
It assumes the paramters name, build_file, and build_file_contents to be
present in ctx.attr, the latter two possibly with value None.
Args:
ctx: The repository context of the repository rule calling this utility
function.
"""
if ctx.attr.build_file and ctx.attr.build_file_content:
ctx.fail("Only one of build_file and build_file_content can be provided.")

ctx.file("WORKSPACE", "workspace(name = \"{name}\")\n".format(name=ctx.name))

if ctx.attr.build_file:
bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
ctx.execute([bash_exe, "-c", "rm -f BUILD BUILD.bazel"])
ctx.symlink(ctx.attr.build_file, "BUILD")
elif ctx.attr.build_file_content:
bash_exe = ctx.os.environ["BAZEL_SH"] if "BAZEL_SH" in ctx.os.environ else "bash"
ctx.execute([bash_exe, "-c", "rm -f BUILD.bazel"])
ctx.file("BUILD", ctx.attr.build_file_content)


0 comments on commit a22a287

Please sign in to comment.