@@ -11,6 +11,7 @@ ShBinariesInfo = provider(
1111 doc = "The description of a sh_binaries target." ,
1212 fields = {
1313 "executables" : "dict of File, The executables included in the bundle by name." ,
14+ "files_to_run" : "dict of FilesToRunProvider, to be passed to ctx.action.run / ctx.action.run_shell." ,
1415 "paths" : "depset of string, The directories under which the binaries can be found." ,
1516 },
1617)
@@ -21,13 +22,15 @@ def _sh_binaries_from_srcs(ctx, srcs, is_windows):
2122 executable_files = []
2223 runfiles = ctx .runfiles ()
2324 executables_dict = dict ()
25+ files_to_run_dict = dict ()
2426 executable_paths = []
2527
2628 for src in srcs :
2729 if src [DefaultInfo ].files_to_run == None or src [DefaultInfo ].files_to_run .executable == None :
2830 fail ("srcs must be executable, but '{}' is not." .format (src .label ))
2931
30- executable = src [DefaultInfo ].files_to_run .executable
32+ files_to_run = src [DefaultInfo ].files_to_run
33+ executable = files_to_run .executable
3134 name = executable .basename
3235 if is_windows :
3336 (noext , ext ) = paths .split_extension (executable .basename )
@@ -44,18 +47,21 @@ def _sh_binaries_from_srcs(ctx, srcs, is_windows):
4447 executable_files .append (executable )
4548 runfiles = runfiles .merge (src [DefaultInfo ].default_runfiles )
4649 executables_dict [name ] = executable
50+ files_to_run_dict [name ] = files_to_run
4751 executable_paths .append (executable .dirname )
4852
4953 return struct (
5054 executable_files = executable_files ,
5155 runfiles = runfiles ,
5256 executables_dict = executables_dict ,
5357 executable_paths = executable_paths ,
58+ files_to_run_dict = files_to_run_dict ,
5459 )
5560
5661def _sh_binaries_from_deps (ctx , deps ):
5762 executable_files = []
5863 runfiles = ctx .runfiles ()
64+ files_to_run_dict = dict ()
5965 executables_dict = dict ()
6066 executable_paths = []
6167
@@ -66,13 +72,15 @@ def _sh_binaries_from_deps(ctx, deps):
6672 executable_files .append (dep [DefaultInfo ].files )
6773 runfiles = runfiles .merge (dep [DefaultInfo ].default_runfiles )
6874 executables_dict .update (dep [ShBinariesInfo ].executables )
75+ files_to_run_dict .update (dep [ShBinariesInfo ].files_to_run )
6976 executable_paths .append (dep [ShBinariesInfo ].paths )
7077
7178 return struct (
7279 executable_files = executable_files ,
7380 runfiles = runfiles ,
7481 executables_dict = executables_dict ,
7582 executable_paths = executable_paths ,
83+ files_to_run_dict = files_to_run_dict ,
7684 )
7785
7886def _runfiles_from_data (ctx , data ):
@@ -91,6 +99,11 @@ def _mk_sh_binaries_info(direct, transitive):
9199 transitive .executables_dict ,
92100 direct .executables_dict ,
93101 ),
102+ files_to_run = dicts .add (
103+ # The order is important so that srcs take precedence over deps on collision.
104+ transitive .files_to_run_dict ,
105+ direct .files_to_run_dict ,
106+ ),
94107 paths = depset (
95108 direct = direct .executable_paths ,
96109 # Reverse the order so that later deps take precedence.
@@ -244,13 +257,10 @@ load("@rules_sh//sh:sh.bzl", "ShBinariesInfo")
244257
245258def _custom_rule_impl(ctx):
246259 tools = ctx.attr.tools[ShBinariesInfo]
247- (tools_inputs, tools_manifest) = ctx.resolve_tools(tools = [ctx.attr.tools])
248260
249261 # Use binary-a in a `run` action.
250262 ctx.actions.run(
251- executable = tools.executables["binary-a"], # Invoke binary-a
252- inputs = tools_inputs,
253- input_manifests = tools_manifest,
263+ executable = tools.files_to_run["binary-a"], # Invoke binary-a
254264 ...
255265 )
256266
@@ -261,11 +271,9 @@ def _custom_rule_impl(ctx):
261271 binary_b = tools.executables["binary-b"].path, # Path to binary-b
262272 ]),
263273 tools = [
264- tools.executables ["binary-a"],
265- tools.executables ["binary-b"],
274+ tools.files_to_run ["binary-a"],
275+ tools.files_to_run ["binary-b"],
266276 ],
267- inputs = tools_inputs,
268- input_manifests = tools_manifest,
269277 ...
270278 )
271279
@@ -275,11 +283,9 @@ def _custom_rule_impl(ctx):
275283 path = ":".join(tools.paths.to_list()),
276284 ),
277285 tools = [
278- tools.executables ["binary-a"],
279- tools.executables ["binary-b"],
286+ tools.files_to_run ["binary-a"],
287+ tools.files_to_run ["binary-b"],
280288 ],
281- inputs = tools_inputs,
282- input_manifests = tools_manifest,
283289 ...
284290 )
285291```
@@ -318,7 +324,6 @@ And in a custom rule as follows:
318324```bzl
319325def _custom_rule_impl(ctx):
320326 tools = ctx.attr.tools[ShBinariesInfo]
321- (tools_inputs, tools_manifest) = ctx.resolve_tools(tools = [ctx.attr.tools])
322327 # The explicit RUNFILES_DIR/RUNFILES_MANIFEST_FILE is a workaround for
323328 # https://github.com/bazelbuild/bazel/issues/15486
324329 tools_env = {
@@ -327,10 +332,8 @@ def _custom_rule_impl(ctx):
327332 }
328333
329334 ctx.actions.run(
330- executable = tools.executables ["binary-a"],
335+ executable = tools.files_to_run ["binary-a"],
331336 env = tools_env, # Pass the environment into the action.
332- inputs = tools_inputs,
333- input_manifests = tools_manifest,
334337 ...
335338 )
336339```
0 commit comments