Skip to content

Commit

Permalink
Fix Bash runfiles_current_repository for tools
Browse files Browse the repository at this point in the history
Shell scripts invoked as tools in actions are usually invoked with relative paths starting with `bazel-out`, which resulted in them being misclassified as from the main repo.

Closes bazelbuild#17279.

PiperOrigin-RevId: 503968803
Change-Id: Idec5d4ce576f0e5b0c8297128cc33ac928d5b04b
  • Loading branch information
fmeum authored and copybara-github committed Jan 23, 2023
1 parent fcb0077 commit 9a7aa21
Show file tree
Hide file tree
Showing 2 changed files with 213 additions and 1 deletion.
212 changes: 212 additions & 0 deletions src/test/shell/bazel/bazel_rules_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1035,4 +1035,216 @@ function test_bash_runfiles_current_repository_test_nobuild_runfile_links() {
expect_log "in external/other_repo/pkg/library2.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_action_binary_main_repo() {
touch MODULE.bazel

mkdir -p pkg
cat > pkg/BUILD.bazel <<'EOF'
genrule(
name = "gen",
outs = ["out"],
tools = [":binary"],
cmd = "$(location :binary) && touch $@",
)
sh_binary(
name = "binary",
srcs = ["binary.sh"],
deps = [
"@bazel_tools//tools/bash/runfiles",
],
visibility = ["//visibility:public"],
)
EOF

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)'"
EOF
chmod +x pkg/binary.sh

bazel build --enable_bzlmod //pkg:gen &>"$TEST_log" || fail "Build should succeed"
expect_log "in pkg/binary.sh: ''"
}

function test_bash_runfiles_current_repository_action_generated_binary_main_repo() {
touch MODULE.bazel

mkdir -p pkg
cat > pkg/BUILD.bazel <<'EOF'
genrule(
name = "gen",
outs = ["out"],
tools = [":binary"],
cmd = "$(location :binary) && touch $@",
)
genrule(
name = "copy_binary",
outs = ["gen_binary.sh"],
srcs = ["binary.sh"],
cmd = "cp $(location binary.sh) $@",
)
sh_binary(
name = "binary",
srcs = ["binary.sh"],
deps = [
"@bazel_tools//tools/bash/runfiles",
],
visibility = ["//visibility:public"],
)
EOF

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 copy of pkg/gen_binary.sh: '$(runfiles_current_repository)'"
EOF
chmod +x pkg/binary.sh

bazel build --enable_bzlmod //pkg:gen &>"$TEST_log" || fail "Build should succeed"
expect_log "in copy of pkg/gen_binary.sh: ''"
}

function test_bash_runfiles_current_repository_action_binary_external_repo() {
touch MODULE.bazel

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

mkdir -p pkg
cat > pkg/BUILD.bazel <<'EOF'
genrule(
name = "gen",
outs = ["out"],
tools = ["@other_repo//pkg:binary"],
cmd = "$(location @other_repo//pkg:binary) && touch $@",
)
EOF

mkdir -p other_repo
touch other_repo/WORKSPACE

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

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)'"
EOF
chmod +x other_repo/pkg/binary.sh

bazel build --enable_bzlmod //pkg:gen &>"$TEST_log" || fail "Build should succeed"
expect_log "in external/other_repo/pkg/binary.sh: 'other_repo'"
}

function test_bash_runfiles_current_repository_action_generated_binary_external_repo() {
touch MODULE.bazel

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

mkdir -p pkg
cat > pkg/BUILD.bazel <<'EOF'
genrule(
name = "gen",
outs = ["out"],
tools = ["@other_repo//pkg:binary"],
cmd = "$(location @other_repo//pkg:binary) && touch $@",
)
EOF

mkdir -p other_repo
touch other_repo/WORKSPACE

mkdir -p other_repo/pkg
cat > other_repo/pkg/BUILD.bazel <<'EOF'
genrule(
name = "copy_binary",
outs = ["gen_binary.sh"],
srcs = ["binary.sh"],
cmd = "cp $(location binary.sh) $@",
)
sh_binary(
name = "binary",
srcs = ["gen_binary.sh"],
deps = [
"@bazel_tools//tools/bash/runfiles",
],
visibility = ["//visibility:public"],
)
EOF

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 copy of external/other_repo/pkg/binary.sh: '$(runfiles_current_repository)'"
EOF
chmod +x other_repo/pkg/binary.sh

bazel build --enable_bzlmod //pkg:gen &>"$TEST_log" || fail "Build should succeed"
expect_log "in copy of external/other_repo/pkg/binary.sh: 'other_repo'"
}

run_suite "rules test"
2 changes: 1 addition & 1 deletion tools/bash/runfiles/runfiles.bash
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ function runfiles_current_repository() {
# The only shell script that is not executed from the runfiles directory (if it is populated)
# is the sh_binary entrypoint. Parse its path under the execroot, using the last match to
# allow for nested execroots (e.g. in Bazel integration tests).
local -r repository=$(echo "$normalized_caller_path" | __runfiles_maybe_grep -E -o '/bazel-out/[^/]+/bin/external/[^/]+/' | tail -1 | rev | cut -d / -f 2 | rev)
local -r repository=$(echo "$normalized_caller_path" | __runfiles_maybe_grep -E -o '(^|/)bazel-out/[^/]+/bin/external/[^/]+/' | tail -1 | rev | cut -d / -f 2 | rev)
if [[ -n "$repository" ]]; then
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
echo >&2 "INFO[runfiles.bash]: runfiles_current_repository($idx): ($normalized_caller_path) lies in repository ($repository)"
Expand Down

0 comments on commit 9a7aa21

Please sign in to comment.