@@ -21,20 +21,31 @@ _ATTRS = {
2121# because the output_dir is a tree artifact
2222# so we weren't able to give it a label
2323def _expand_location (ctx , s ):
24- outdir_segments = [ctx .bin_dir .path , ctx .label .package ]
24+ rule_dir = [ctx .bin_dir .path , ctx .label .package ]
25+
2526 if ctx .attr .output_dir :
26- # We'll write into a newly created directory named after the rule
27- outdir_segments .append (ctx .attr .name )
27+ if s .find ("$@" ) != - 1 :
28+ fail ("""$@ substitution may only be used with output_dir=False.
29+ Upgrading rules_nodejs? Maybe you need to switch from $@ to $(@D)
30+ See https://github.com/bazelbuild/rules_nodejs/releases/tag/0.42.0""" )
2831
29- if not ctx .attr .output_dir :
32+ # We'll write into a newly created directory named after the rule
33+ output_dir = [ctx .bin_dir .path , ctx .label .package , ctx .attr .name ]
34+ else :
3035 if s .find ("$@" ) != - 1 and len (ctx .outputs .outs ) > 1 :
3136 fail ("""$@ substitution may only be used with a single out
3237 Upgrading rules_nodejs? Maybe you need to switch from $@ to $(RULEDIR)
3338 See https://github.com/bazelbuild/rules_nodejs/releases/tag/0.42.0""" )
3439 s = s .replace ("$@" , ctx .outputs .outs [0 ].path )
40+ if len (ctx .outputs .outs ) == 1 :
41+ output_dir = ctx .outputs .outs [0 ].dirname .split ("/" )
42+ else :
43+ output_dir = rule_dir [:]
3544
3645 # The list comprehension removes empty segments like if we are in the root package
37- s = s .replace ("$(RULEDIR)" , "/" .join ([o for o in outdir_segments if o ]))
46+ s = s .replace ("$(@D)" , "/" .join ([o for o in output_dir if o ]))
47+ s = s .replace ("$(RULEDIR)" , "/" .join ([o for o in rule_dir if o ]))
48+
3849 return ctx .expand_location (s , targets = ctx .attr .data )
3950
4051def _inputs (ctx ):
@@ -104,7 +115,11 @@ def npm_package_bin(tool = None, package = None, package_bin = None, data = [],
104115 Can use $(location) expansion. See https://docs.bazel.build/versions/master/be/make-variables.html
105116 Like genrule, you may also use some syntax sugar for locations:
106117 - `$@`: if you have only one output file, the location of the output
107- - `$(RULEDIR)`: the output directory of the rule, corresponding with its package
118+ - `$(@D)`: The output directory. If output_dir=False and there is only one file name in outs, this expands to the directory
119+ containing that file. If there are multiple files, this instead expands to the package's root directory in the genfiles
120+ tree, even if all generated files belong to the same subdirectory! If output_dir=True then this corresponds
121+ to the output directory which is the $(RULEDIR)/{target_name}.
122+ - `$(RULEDIR)`: the root output directory of the rule, corresponding with its package
108123 (can be used with output_dir=True or False)
109124
110125 package: an npm package whose binary to run, like "terser". Assumes your node_modules are installed in a workspace called "npm"
0 commit comments