From 0a215a4e5c7d2f7fc6bf63afd25360a6975ec6cc Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 14 Feb 2023 20:26:53 +0100 Subject: [PATCH] Support change-dir before calling a command (#14) Changes the bash script generated by `command` to look up the target executable in the runfiles. Closes #13 --- command.bzl | 12 +++++++++++- tests/BUILD | 16 ++++++++++++++++ tests/test.sh | 2 ++ tests/validate-chdir-location.sh | 31 +++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100755 tests/validate-chdir-location.sh diff --git a/command.bzl b/command.bzl index 4b893cc..24d49d1 100644 --- a/command.bzl +++ b/command.bzl @@ -15,6 +15,16 @@ _force_opt = transition( outputs = ["//command_line_option:compilation_mode"], ) +def _rlocation_path(ctx, file): + """Produce the rlocation lookup path for the given file. + + See https://github.com/bazelbuild/bazel-skylib/issues/303. + """ + if file.short_path.startswith("../"): + return file.short_path[3:] + else: + return ctx.workspace_name + "/" + file.short_path + def _command_impl(ctx): runfiles = ctx.runfiles().merge(ctx.attr._bash_runfiles[DefaultInfo].default_runfiles) @@ -40,7 +50,7 @@ def _command_impl(ctx): "%s" % shell.quote(ctx.expand_location(v, targets = expansion_targets)) for v in ctx.attr.arguments ] - command_exec = " ".join(["exec ./%s" % shell.quote(executable.short_path)] + str_args + ['"$@"\n']) + command_exec = " ".join(["exec $(rlocation %s)" % shell.quote(_rlocation_path(ctx, executable))] + str_args + ['"$@"\n']) out_file = ctx.actions.declare_file(ctx.label.name + ".bash") ctx.actions.write( diff --git a/tests/BUILD b/tests/BUILD index 75c8665..9374b53 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -21,6 +21,21 @@ command( command = "validate_args", ) +sh_binary( + name = "validate_chdir_location", + srcs = ["validate-chdir-location.sh"], + deps = ["@bazel_tools//tools/bash/runfiles"], +) + +command( + name = "validate_chdir_location_cmd", + # Note, from Bazel 6.1.0 upwards this can be replaced by $(rlocationpath ...). + # See https://github.com/bazelbuild/bazel/pull/16653. + arguments = ["rules_multirun/$(rootpath :hello)"], + command = "validate_chdir_location", + data = [":hello"], +) + sh_binary( name = "validate_env", srcs = ["validate-env.sh"], @@ -67,6 +82,7 @@ sh_test( ":multirun_serial", ":multirun_serial_no_print", ":validate_args_cmd", + ":validate_chdir_location_cmd", ":validate_env_cmd", ], deps = ["@bazel_tools//tools/bash/runfiles"], diff --git a/tests/test.sh b/tests/test.sh index cbd671a..93b77a3 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -23,6 +23,8 @@ fi script=$(rlocation rules_multirun/tests/validate_args_cmd.bash) $script +script=$(rlocation rules_multirun/tests/validate_chdir_location_cmd.bash) +$script script=$(rlocation rules_multirun/tests/validate_env_cmd.bash) $script diff --git a/tests/validate-chdir-location.sh b/tests/validate-chdir-location.sh new file mode 100755 index 0000000..ba924de --- /dev/null +++ b/tests/validate-chdir-location.sh @@ -0,0 +1,31 @@ +#!/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 --- + +set -euo pipefail + +WORKDIR="$(mktemp -d)" +trap 'rm -rf -- "$WORKDIR"' EXIT +cd "$WORKDIR" + +if [[ $# != 1 ]]; then + echo "error: expected one argument, got $#" + exit 1 +fi + +hello="$(rlocation "$1")" +output="$($hello)" + +if [[ "$output" != hello ]]; then + echo "error: expected '$hello' to print 'hello', got '$output'" + exit 1 +fi