Skip to content

Commit 13ff6d9

Browse files
fmeumcopybara-github
authored andcommitted
Fix Bash rlocation failure with stricter Bash options
When run in the context of the bazel-skylib unit test setup, the new repo mapping logic in the Bash runfiles library failed due to a non-matching grep in a pipe. Fix this by using a wrapper around grep throughout that does not exit with exit code 1 if there is no match. Fixes bazelbuild/bazel-skylib#411 (comment) Closes bazelbuild#16755. PiperOrigin-RevId: 488749744 Change-Id: I087b03d9e95ba27a409c551bdc27d0027919a0fe
1 parent 2a471a2 commit 13ff6d9

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

tools/bash/runfiles/runfiles.bash

+11-5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ msys*|mingw*|cygwin*)
105105
;;
106106
esac
107107

108+
# Does not exit with a non-zero exit code if no match is found.
109+
function __runfiles_maybe_grep() {
110+
grep "$@" || test $? = 1;
111+
}
112+
export -f __runfiles_maybe_grep
113+
108114
# Prints to stdout the runtime location of a data-dependency.
109115
# The optional second argument can be used to specify the canonical name of the
110116
# repository whose repository mapping should be used to resolve the repository
@@ -145,7 +151,7 @@ function rlocation() {
145151
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
146152
echo >&2 "INFO[runfiles.bash]: rlocation($1): looking up canonical name for ($target_repo_apparent_name) from ($source_repo) in ($RUNFILES_REPO_MAPPING)"
147153
fi
148-
local -r target_repo=$(grep -m1 "^$source_repo,$target_repo_apparent_name," "$RUNFILES_REPO_MAPPING" | cut -d , -f 3)
154+
local -r target_repo=$(__runfiles_maybe_grep -m1 "^$source_repo,$target_repo_apparent_name," "$RUNFILES_REPO_MAPPING" | cut -d , -f 3)
149155
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
150156
echo >&2 "INFO[runfiles.bash]: rlocation($1): canonical name of target repo is ($target_repo)"
151157
fi
@@ -225,7 +231,7 @@ function runfiles_current_repository() {
225231
# uses / as the path separator even on Windows.
226232
local -r normalized_caller_path="$(echo "$caller_path" | sed 's|\\\\*|/|g')"
227233
local -r escaped_caller_path="$(echo "$normalized_caller_path" | sed 's/[^-A-Za-z0-9_/]/\\&/g')"
228-
rlocation_path=$(grep -m1 "^[^ ]* ${escaped_caller_path}$" "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 1)
234+
rlocation_path=$(__runfiles_maybe_grep -m1 "^[^ ]* ${escaped_caller_path}$" "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 1)
229235
if [[ -z "$rlocation_path" ]]; then
230236
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
231237
echo >&2 "INFO[runfiles.bash]: runfiles_current_repository($idx): ($normalized_caller_path) is not the target of an entry in the runfiles manifest ($RUNFILES_MANIFEST_FILE)"
@@ -254,7 +260,7 @@ function runfiles_current_repository() {
254260
# The only shell script that is not executed from the runfiles directory (if it is populated)
255261
# is the sh_binary entrypoint. Parse its path under the execroot, using the last match to
256262
# allow for nested execroots (e.g. in Bazel integration tests).
257-
local -r repository=$(echo "$normalized_caller_path" | grep -E -o '/execroot/[^/]+/bazel-out/[^/]+/bin/external/[^/]+/' | tail -1 | rev | cut -d / -f 2 | rev)
263+
local -r repository=$(echo "$normalized_caller_path" | __runfiles_maybe_grep -E -o '/execroot/[^/]+/bazel-out/[^/]+/bin/external/[^/]+/' | tail -1 | rev | cut -d / -f 2 | rev)
258264
if [[ -n "$repository" ]]; then
259265
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
260266
echo >&2 "INFO[runfiles.bash]: runfiles_current_repository($idx): ($normalized_caller_path) lies in repository ($repository)"
@@ -305,7 +311,7 @@ function runfiles_rlocation_checked() {
305311
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
306312
echo >&2 "INFO[runfiles.bash]: rlocation($1): looking in RUNFILES_MANIFEST_FILE ($RUNFILES_MANIFEST_FILE)"
307313
fi
308-
local -r result=$(grep -m1 "^$1 " "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)
314+
local -r result=$(__runfiles_maybe_grep -m1 "^$1 " "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)
309315
if [[ -z "$result" ]]; then
310316
# If path references a runfile that lies under a directory that itself
311317
# is a runfile, then only the directory is listed in the manifest. Look
@@ -318,7 +324,7 @@ function runfiles_rlocation_checked() {
318324
new_prefix="${prefix%/*}"
319325
[[ "$new_prefix" == "$prefix" ]] && break
320326
prefix="$new_prefix"
321-
prefix_result=$(grep -m1 "^$prefix " "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)
327+
prefix_result=$(__runfiles_maybe_grep -m1 "^$prefix " "${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)
322328
[[ -z "$prefix_result" ]] && continue
323329
local -r candidate="${prefix_result}${1#"${prefix}"}"
324330
if [[ -e "$candidate" ]]; then

0 commit comments

Comments
 (0)