Skip to content

Commit 08e2aeb

Browse files
authored
feat: Relax single file limit of run_in rule (#71)
This change makes `run_in` rule accept multi-file executable target by using `ctx.executable.tool`. With this change, it will be possible to wrap e.g. a `py_console_script_binary` target where there is an executable file together with a bunch of other files. As a concrete example: ```starlark load("@pip_deps//:requirements.bzl", "requirement") load("@rules_multitool//multitool:cwd.bzl", "cwd") load("@rules_python//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary") py_console_script_binary( name = "pre-commit", pkg = requirement("pre-commit"), script = "pre-commit", ) cwd( name = "cwd", tool = ":pre-commit", ) ``` Then we can do `bazel run //tools/pre-commit:cwd -- autoupdate`, otherwise we will need to have workaround like `bazel run --run_under="cd $PWD && " //tools/pre-commit -- autoupdate`
1 parent 5a84b9c commit 08e2aeb

4 files changed

Lines changed: 57 additions & 4 deletions

File tree

examples/module/.bazelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ startup --windows_enable_symlinks
1010

1111
# off by default on windows, required for this module
1212
common --enable_runfiles
13+
14+
# Don't rely on test logs being easily accessible from the test runner,
15+
# though it makes the log noisier.
16+
test --test_output=errors

examples/module/BUILD.bazel

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
load("@rules_multitool//multitool:cwd.bzl", "cwd")
2+
load("//:add_dummy_file.bzl", "add_dummy_file")
3+
14
sh_test(
25
name = "integration_test",
36
srcs = ["integration_test.sh"],
@@ -24,3 +27,22 @@ sh_test(
2427
],
2528
data = ["@multitool//tools/target-determinator:workspace_root"],
2629
)
30+
31+
add_dummy_file(
32+
name = "add_dummy_file",
33+
tool = "@multitool//tools/target-determinator",
34+
)
35+
36+
cwd(
37+
name = "add_dummy_file_cwd",
38+
tool = ":add_dummy_file",
39+
)
40+
41+
sh_test(
42+
name = "integration_test_add_dummy_file_cwd",
43+
srcs = ["integration_test.sh"],
44+
args = [
45+
"$(location :add_dummy_file_cwd)",
46+
],
47+
data = [":add_dummy_file_cwd"],
48+
)

examples/module/add_dummy_file.bzl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"rule adding a dummy file to output, for test purpose"
2+
3+
def _add_dummy_file(ctx):
4+
if ctx.executable.tool.extension == "exe":
5+
content = "@%s %%*" % ctx.executable.tool.short_path.replace("/", "\\")
6+
script = ctx.actions.declare_file(ctx.label.name + ".bat")
7+
else:
8+
content = '#!/usr/bin/env bash\nexec "%s" "$@"' % ctx.executable.tool.short_path
9+
script = ctx.actions.declare_file(ctx.label.name)
10+
ctx.actions.write(script, content, is_executable = True)
11+
12+
dummy_output_file = ctx.actions.declare_file(ctx.label.name + ".dummy")
13+
ctx.actions.write(dummy_output_file, "")
14+
15+
return [DefaultInfo(
16+
executable = script,
17+
files = depset([script, dummy_output_file]),
18+
runfiles = ctx.attr.tool[DefaultInfo].default_runfiles,
19+
)]
20+
21+
add_dummy_file = rule(
22+
implementation = _add_dummy_file,
23+
executable = True,
24+
attrs = {
25+
"tool": attr.label(mandatory = True, executable = True, cfg = "exec"),
26+
},
27+
)

multitool/private/run_in.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"run_in provides a shared implementation for cwd and workspace_root execution"
22

33
run_in_attrs = {
4-
"tool": attr.label(mandatory = True, allow_single_file = True, executable = True, cfg = "exec"),
4+
"tool": attr.label(mandatory = True, executable = True, cfg = "exec"),
55
"_template_sh": attr.label(default = "//multitool/private:run_in.template.sh", allow_single_file = True),
66
"_template_bat": attr.label(default = "//multitool/private:run_in.template.bat", allow_single_file = True),
77
}
@@ -22,8 +22,8 @@ def run_in(ctx, env_var):
2222
# This algorithm requires --enable_runfiles (enabled by default on non-windows)
2323
template = ctx.file._template_sh
2424
wrapper_name = ctx.label.name
25-
tool_short_path = ctx.file.tool.short_path
26-
if ctx.file.tool.extension == "exe":
25+
tool_short_path = ctx.executable.tool.short_path
26+
if ctx.executable.tool.extension == "exe":
2727
template = ctx.file._template_bat
2828
wrapper_name = wrapper_name + ".bat"
2929
tool_short_path = tool_short_path.replace("/", "\\")
@@ -36,4 +36,4 @@ def run_in(ctx, env_var):
3636
"{{env_var}}": env_var,
3737
},
3838
)
39-
return [DefaultInfo(executable = output, runfiles = ctx.runfiles(files = [ctx.file.tool]))]
39+
return [DefaultInfo(executable = output, runfiles = ctx.attr.tool[DefaultInfo].default_runfiles)]

0 commit comments

Comments
 (0)