Skip to content

Commit

Permalink
Add boolean to run from workspace root (#4)
Browse files Browse the repository at this point in the history
This is common for tools like linters. Doing the cd themselves is fine, but for some other tools you consume, this allows you to avoid a shim just to do this. For example if you run `flake8` from source, you either have to write a shim or do something like this.
  • Loading branch information
keith authored Nov 27, 2024
1 parent 6c9ed33 commit 0380bbc
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
9 changes: 8 additions & 1 deletion command.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ def _command_impl(ctx):
"%s" % shell.quote(ctx.expand_location(v, targets = expansion_targets))
for v in ctx.attr.arguments
]
cd_command = ""
if ctx.attr.run_from_workspace_root:
cd_command = 'cd "$BUILD_WORKSPACE_DIRECTORY"'
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(
output = out_file,
content = "\n".join([RUNFILES_PREFIX] + str_env + [command_exec]),
content = "\n".join([RUNFILES_PREFIX] + str_env + [cd_command, command_exec]),
is_executable = True,
)

Expand Down Expand Up @@ -106,6 +109,10 @@ def command_with_transition(cfg, allowlist = None, doc = None):
"description": attr.string(
doc = "A string describing the command printed during multiruns",
),
"run_from_workspace_root": attr.bool(
default = False,
doc = "If true, the command will be run from the workspace root instead of the execution root",
),
"_bash_runfiles": attr.label(
default = Label("@bazel_tools//tools/bash/runfiles"),
),
Expand Down
6 changes: 4 additions & 2 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ useful for running multiple linters or formatters with a single command.
<pre>
load("@rules_multirun//:defs.bzl", "command")

command(<a href="#command-name">name</a>, <a href="#command-data">data</a>, <a href="#command-arguments">arguments</a>, <a href="#command-command">command</a>, <a href="#command-description">description</a>, <a href="#command-environment">environment</a>)
command(<a href="#command-name">name</a>, <a href="#command-data">data</a>, <a href="#command-arguments">arguments</a>, <a href="#command-command">command</a>, <a href="#command-description">description</a>, <a href="#command-environment">environment</a>, <a href="#command-run_from_workspace_root">run_from_workspace_root</a>)
</pre>

A command is a wrapper rule for some other target that can be run like a
Expand Down Expand Up @@ -58,6 +58,7 @@ command(
| <a id="command-command"></a>command | Target to run | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="command-description"></a>description | A string describing the command printed during multiruns | String | optional | `""` |
| <a id="command-environment"></a>environment | Dictionary of environment variables. Subject to $(location) expansion. See https://docs.bazel.build/versions/master/skylark/lib/ctx.html#expand_location | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
| <a id="command-run_from_workspace_root"></a>run_from_workspace_root | If true, the command will be run from the workspace root instead of the execution root | Boolean | optional | `False` |


<a id="command_force_opt"></a>
Expand All @@ -67,7 +68,7 @@ command(
<pre>
load("@rules_multirun//:defs.bzl", "command_force_opt")

command_force_opt(<a href="#command_force_opt-name">name</a>, <a href="#command_force_opt-data">data</a>, <a href="#command_force_opt-arguments">arguments</a>, <a href="#command_force_opt-command">command</a>, <a href="#command_force_opt-description">description</a>, <a href="#command_force_opt-environment">environment</a>)
command_force_opt(<a href="#command_force_opt-name">name</a>, <a href="#command_force_opt-data">data</a>, <a href="#command_force_opt-arguments">arguments</a>, <a href="#command_force_opt-command">command</a>, <a href="#command_force_opt-description">description</a>, <a href="#command_force_opt-environment">environment</a>, <a href="#command_force_opt-run_from_workspace_root">run_from_workspace_root</a>)
</pre>

A command that forces the compilation mode of the dependent targets to opt. This can be useful if your tools have improved performance if built with optimizations. See the documentation for command for more examples. If you'd like to always use this variation you can import this directly and rename it for convenience like:
Expand All @@ -87,6 +88,7 @@ load("@rules_multirun//:defs.bzl", "multirun", command = "command_force_opt")
| <a id="command_force_opt-command"></a>command | Target to run | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="command_force_opt-description"></a>description | A string describing the command printed during multiruns | String | optional | `""` |
| <a id="command_force_opt-environment"></a>environment | Dictionary of environment variables. Subject to $(location) expansion. See https://docs.bazel.build/versions/master/skylark/lib/ctx.html#expand_location | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | `{}` |
| <a id="command_force_opt-run_from_workspace_root"></a>run_from_workspace_root | If true, the command will be run from the workspace root instead of the execution root | Boolean | optional | `False` |


<a id="multirun"></a>
Expand Down
23 changes: 23 additions & 0 deletions tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,32 @@ multirun(
print_command = False,
)

sh_binary(
name = "default_pwd",
srcs = ["default-pwd.sh"],
)

command(
name = "default_pwd_cmd",
command = ":default_pwd",
)

sh_binary(
name = "workspace_pwd",
srcs = ["workspace-pwd.sh"],
)

command(
name = "workspace_pwd_cmd",
command = ":workspace_pwd",
run_from_workspace_root = True,
)

sh_test(
name = "test",
srcs = ["test.sh"],
data = [
":default_pwd_cmd",
":echo_and_fail_cmd",
":hello",
":hello2",
Expand All @@ -251,6 +273,7 @@ sh_test(
":validate_args_cmd_description",
":validate_chdir_location_cmd",
":validate_env_cmd",
":workspace_pwd_cmd",
],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
8 changes: 8 additions & 0 deletions tests/default-pwd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

set -euo pipefail

if [[ "$PWD" -ef "$BUILD_WORKSPACE_DIRECTORY" ]]; then
echo "error: expected to run from default pwd" >&2
exit 1
fi
7 changes: 7 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,10 @@ for expectation in "${expectations[@]}"; do
exit 1
fi
done

# Fake the 'bazel run' env var for tests
export BUILD_WORKSPACE_DIRECTORY=/tmp
script=$(rlocation rules_multirun/tests/default_pwd_cmd.bash)
$script
script=$(rlocation rules_multirun/tests/workspace_pwd_cmd.bash)
$script
8 changes: 8 additions & 0 deletions tests/workspace-pwd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

set -euo pipefail

if [[ ! "$PWD" -ef "$BUILD_WORKSPACE_DIRECTORY" ]]; then
echo "error: expected to run from workspace root" >&2
exit 1
fi

0 comments on commit 0380bbc

Please sign in to comment.