@@ -8,26 +8,44 @@ _ATTRS = {
88 "outs" : attr .output_list (),
99 "args" : attr .string_list (mandatory = True ),
1010 "data" : attr .label_list (allow_files = True , aspects = [module_mappings_aspect ]),
11+ "out_dir" : attr .string (),
1112 "tool" : attr .label (
1213 executable = True ,
1314 cfg = "host" ,
1415 mandatory = True ,
1516 ),
1617}
1718
19+ # Need a custom expand_location function
20+ # because the out_dir is a tree artifact
21+ # so we weren't able to give it a label
22+ def _expand_location (ctx , s ):
23+ s = s .replace ("$@" , "/" .join ([ctx .bin_dir .path , ctx .label .package , ctx .attr .out_dir ]))
24+ return ctx .expand_location (s , targets = ctx .attr .data )
25+
1826def _impl (ctx ):
27+ if ctx .attr .out_dir and ctx .attr .outs :
28+ fail ("Only one of out_dir and outs may be specified" )
29+ if not ctx .attr .out_dir and not ctx .attr .outs :
30+ fail ("One of out_dir and outs must be specified" )
31+
1932 args = ctx .actions .args ()
2033 inputs = ctx .files .data [:]
21- outputs = ctx .outputs .outs
34+ outputs = []
35+ if ctx .attr .out_dir :
36+ outputs = [ctx .actions .declare_directory (ctx .attr .out_dir )]
37+ else :
38+ outputs = ctx .outputs .outs
2239 register_node_modules_linker (ctx , args , inputs )
2340 for a in ctx .attr .args :
24- args .add (ctx . expand_location ( a , targets = ctx . attr . data ))
41+ args .add (_expand_location ( ctx , a ))
2542 ctx .actions .run (
2643 executable = ctx .executable .tool ,
2744 inputs = inputs ,
2845 outputs = outputs ,
2946 arguments = [args ],
3047 )
48+ return [DefaultInfo (files = depset (outputs ))]
3149
3250_npm_package_bin = rule (
3351 _impl ,
@@ -45,17 +63,22 @@ def npm_package_bin(tool = None, package = None, package_bin = None, **kwargs):
4563 https://docs.bazel.build/versions/master/skylark/macros.html#full-example
4664
4765 Args:
48- data: identical to [genrule.srcs](https://docs.bazel.build/versions/master/be/general.html#genrule.srcs)
66+ data: similar to [genrule.srcs](https://docs.bazel.build/versions/master/be/general.html#genrule.srcs)
4967 may also include targets that produce or reference npm packages which are needed by the tool
50- outs: identical to [genrule.outs](https://docs.bazel.build/versions/master/be/general.html#genrule.outs)
68+ outs: similar to [genrule.outs](https://docs.bazel.build/versions/master/be/general.html#genrule.outs)
69+ out_dir: use this instead of `outs` if you want the output to be a directory
70+ Exactly one of `outs`, `out_dir` may be used.
71+ If you output a directory, there can only be one output.
5172 args: Command-line arguments to the tool.
5273
5374 Subject to 'Make variable' substitution.
5475 Can use $(location) expansion. See https://docs.bazel.build/versions/master/be/make-variables.html
76+ You may also refer to the location of the out_dir with the special `$@` replacement, like genrule.
5577
5678 package: an npm package whose binary to run, like "terser". Assumes your node_modules are installed in a workspace called "npm"
5779 package_bin: the "bin" entry from `package` that should be run. By default package_bin is the same string as `package`
58- tool: a label for a binary to run, like `@npm//terser/bin:terser`. This is the longer form of package/package_bin
80+ tool: a label for a binary to run, like `@npm//terser/bin:terser`. This is the longer form of package/package_bin.
81+ Note that you can also refer to a binary in your local workspace.
5982 """
6083 if not tool :
6184 if not package :
0 commit comments