Skip to content

Commit

Permalink
Make Bash runfiles library repo mapping aware (bazelbuild#16753)
Browse files Browse the repository at this point in the history
Work towards bazelbuild#16124

Closes bazelbuild#16693.

PiperOrigin-RevId: 487811689
Change-Id: Iec5ef01ae09394372b87e5cb697ceb728563d2dc
  • Loading branch information
fmeum authored Nov 15, 2022
1 parent c3e2b98 commit 0b64525
Show file tree
Hide file tree
Showing 5 changed files with 738 additions and 59 deletions.
60 changes: 60 additions & 0 deletions src/test/py/bazel/bzlmod/bazel_module_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,5 +814,65 @@ def testCppRunfilesLibraryRepoMapping(self):
allow_failure=True)
self.AssertExitCode(exit_code, 0, stderr, stdout)

def testBashRunfilesLibraryRepoMapping(self):
self.main_registry.setModuleBasePath('projects')
projects_dir = self.main_registry.projects

self.main_registry.createLocalPathModule('data', '1.0', 'data')
projects_dir.joinpath('data').mkdir(exist_ok=True)
scratchFile(projects_dir.joinpath('data', 'WORKSPACE'))
scratchFile(projects_dir.joinpath('data', 'foo.txt'), ['hello'])
scratchFile(
projects_dir.joinpath('data', 'BUILD'), ['exports_files(["foo.txt"])'])

self.main_registry.createLocalPathModule('test', '1.0', 'test',
{'data': '1.0'})
projects_dir.joinpath('test').mkdir(exist_ok=True)
scratchFile(projects_dir.joinpath('test', 'WORKSPACE'))
scratchFile(
projects_dir.joinpath('test', 'BUILD'), [
'sh_test(',
' name = "test",',
' srcs = ["test.sh"],',
' data = ["@data//:foo.txt"],',
' args = ["$(rlocationpath @data//:foo.txt)"],',
' deps = ["@bazel_tools//tools/bash/runfiles"],',
')',
])
test_script = projects_dir.joinpath('test', 'test.sh')
scratchFile(
test_script, """#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
[[ -f "$(rlocation $1)" ]] || exit 1
[[ -f "$(rlocation data/foo.txt)" ]] || exit 2
""".splitlines())
os.chmod(test_script, 0o755)

self.ScratchFile('MODULE.bazel', ['bazel_dep(name="test",version="1.0")'])
self.ScratchFile('WORKSPACE')

# Run sandboxed on Linux and macOS.
exit_code, stderr, stdout = self.RunBazel([
'test', '@test//:test', '--test_output=errors',
'--test_env=RUNFILES_LIB_DEBUG=1'
],
allow_failure=True)
self.AssertExitCode(exit_code, 0, stderr, stdout)
# Run unsandboxed on all platforms.
exit_code, stderr, stdout = self.RunBazel(
['run', '@test//:test'],
allow_failure=True,
env_add={'RUNFILES_LIB_DEBUG': '1'})
self.AssertExitCode(exit_code, 0, stderr, stdout)

if __name__ == '__main__':
unittest.main()
1 change: 1 addition & 0 deletions src/test/shell/bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ sh_test(
"@bazel_tools//tools/bash/runfiles",
],
shard_count = 3,
tags = ["requires-network"],
)

sh_test(
Expand Down
292 changes: 292 additions & 0 deletions src/test/shell/bazel/bazel_rules_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -743,4 +743,296 @@ EOF
bazel run //pkg:my_executable >$TEST_log 2>&1 || fail "Binary should have exit code 0"
}

function setup_bash_runfiles_current_repository() {
touch MODULE.bazel

cat >> WORKSPACE <<'EOF'
local_repository(
name = "other_repo",
path = "other_repo",
)
EOF

mkdir -p pkg
cat > pkg/BUILD.bazel <<'EOF'
sh_library(
name = "library",
srcs = ["library.sh"],
deps = ["@bazel_tools//tools/bash/runfiles"],
visibility = ["//visibility:public"],
)
sh_binary(
name = "binary",
srcs = ["binary.sh"],
deps = [
":library",
"@other_repo//pkg:library2",
"@bazel_tools//tools/bash/runfiles",
],
)
sh_test(
name = "test",
srcs = ["test.sh"],
deps = [
":library",
"@other_repo//pkg:library2",
"@bazel_tools//tools/bash/runfiles",
],
)
EOF

cat > pkg/library.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
function library() {
echo "in pkg/library.sh: '$(runfiles_current_repository)'"
}
export -f library
EOF
chmod +x pkg/library.sh

cat > pkg/binary.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
echo "in pkg/binary.sh: '$(runfiles_current_repository)'"
source $(rlocation _main/pkg/library.sh)
library
source $(rlocation other_repo/pkg/library2.sh)
library2
EOF
chmod +x pkg/binary.sh

cat > pkg/test.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
echo "in pkg/test.sh: '$(runfiles_current_repository)'"
source $(rlocation _main/pkg/library.sh)
library
source $(rlocation other_repo/pkg/library2.sh)
library2
EOF
chmod +x pkg/test.sh

mkdir -p other_repo
touch other_repo/WORKSPACE

mkdir -p other_repo/pkg
cat > other_repo/pkg/BUILD.bazel <<'EOF'
sh_library(
name = "library2",
srcs = ["library2.sh"],
deps = ["@bazel_tools//tools/bash/runfiles"],
visibility = ["//visibility:public"],
)
sh_binary(
name = "binary",
srcs = ["binary.sh"],
deps = [
"//pkg:library2",
"@//pkg:library",
"@bazel_tools//tools/bash/runfiles",
],
)
sh_test(
name = "test",
srcs = ["test.sh"],
deps = [
"//pkg:library2",
"@//pkg:library",
"@bazel_tools//tools/bash/runfiles",
],
)
EOF

cat > other_repo/pkg/library2.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
function library2() {
echo "in external/other_repo/pkg/library2.sh: '$(runfiles_current_repository)'"
}
export -f library2
EOF
chmod +x pkg/library.sh

cat > other_repo/pkg/binary.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
echo "in external/other_repo/pkg/binary.sh: '$(runfiles_current_repository)'"
source $(rlocation _main/pkg/library.sh)
library
source $(rlocation other_repo/pkg/library2.sh)
library2
EOF
chmod +x other_repo/pkg/binary.sh

cat > other_repo/pkg/test.sh <<'EOF'
#!/usr/bin/env bash
# --- begin runfiles.bash initialization v2 ---
# Copy-pasted from the Bazel Bash runfiles library v2.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
echo "in external/other_repo/pkg/test.sh: '$(runfiles_current_repository)'"
source $(rlocation _main/pkg/library.sh)
library
source $(rlocation other_repo/pkg/library2.sh)
library2
EOF
chmod +x other_repo/pkg/test.sh
}

function test_bash_runfiles_current_repository_binary_enable_runfiles() {
setup_bash_runfiles_current_repository

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --enable_runfiles //pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in pkg/binary.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --enable_runfiles @other_repo//pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in external/other_repo/pkg/binary.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_test_enable_runfiles() {
setup_bash_runfiles_current_repository

bazel test --enable_bzlmod --enable_runfiles --test_env=RUNFILES_LIB_DEBUG=1 \
--test_output=all //pkg:test &>"$TEST_log" || fail "Test should succeed"
expect_log "in pkg/test.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

bazel test --enable_bzlmod --enable_runfiles --test_env=RUNFILES_LIB_DEBUG=1 \
--test_output=all @other_repo//pkg:test &>"$TEST_log" || fail "Test should succeed"
expect_log "in external/other_repo/pkg/test.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_binary_noenable_runfiles() {
setup_bash_runfiles_current_repository

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --noenable_runfiles //pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in pkg/binary.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --noenable_runfiles @other_repo//pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in external/other_repo/pkg/binary.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_test_noenable_runfiles() {
setup_bash_runfiles_current_repository

bazel test --enable_bzlmod --noenable_runfiles --test_env=RUNFILES_LIB_DEBUG=1 \
--test_output=all //pkg:test &>"$TEST_log" || fail "Test should succeed"
expect_log "in pkg/test.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

bazel test --enable_bzlmod --noenable_runfiles --test_env=RUNFILES_LIB_DEBUG=1 \
--test_output=all @other_repo//pkg:test &>"$TEST_log" || fail "Test should succeed"
expect_log "in external/other_repo/pkg/test.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_binary_nobuild_runfile_links() {
setup_bash_runfiles_current_repository

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --nobuild_runfile_links //pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in pkg/binary.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

RUNFILES_LIB_DEBUG=1 bazel run --enable_bzlmod --nobuild_runfile_links @other_repo//pkg:binary \
&>"$TEST_log" || fail "Run should succeed"
expect_log "in external/other_repo/pkg/binary.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_test_nobuild_runfile_links() {
setup_bash_runfiles_current_repository

bazel test --enable_bzlmod --noenable_runfiles --nobuild_runfile_links \
--test_env=RUNFILES_LIB_DEBUG=1 --test_output=all //pkg:test \
&>"$TEST_log" || fail "Test should succeed"
expect_log "in pkg/test.sh: ''"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"

bazel test --enable_bzlmod --noenable_runfiles --nobuild_runfile_links \
--test_env=RUNFILES_LIB_DEBUG=1 --test_output=all @other_repo//pkg:test \
&>"$TEST_log" || fail "Test should succeed"
expect_log "in external/other_repo/pkg/test.sh: 'other_repo'"
expect_log "in pkg/library.sh: ''"
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

run_suite "rules test"
Loading

0 comments on commit 0b64525

Please sign in to comment.