Skip to content
Closed
13 changes: 5 additions & 8 deletions docs/use_execroot_entry_point.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ bin.rspack(
fixed_args = [
"build",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :rspack_config)",
"$(rlocation :rspack_config)",
],
use_execroot_entry_point = False,
)
Expand All @@ -128,10 +128,7 @@ Key points:
`__dirname`, for specifying the output path. This is key, because the config
file (and therefore `__dirname`) will be in the runfiles directory and not
the output tree.
- We refer to `"$$RUNFILES_DIR/$(rlocationpath :rspack_config)"` in
`fixed_args`. `$(rlocationpath ...)` is evaluated at analysis time and
determines the path to the config file within the runfiles directory. This
argument must go in `fixed_args` rather than `args`, to allow `$RUNFILES_DIR`
to be evaluated at run time. Note the double dollar sign (`$$`) to prevent
the `js_binary` implementation from attempting to evaluate that variable at
analysis time.
- We refer to `"$(rlocation :rspack_config)"` in `fixed_args`. The `js_binary`
implementation expands this to the absolute path to the config file in the
runfiles directory. Note that this must go in `fixed_args` rather than
`args`.
2 changes: 1 addition & 1 deletion examples/rspack/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ bin.rspack(
fixed_args = [
"build",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :rspack_config)",
"$(rlocation :rspack_config)",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we are adding a magic $(rlocation) util in addition to the "standard" $() utils. Where/who defines those "standard" ones? Are they native bazel?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this is our own magic one. The standard ones are native Bazel in ctx.expand_location(): https://bazel.build/rules/lib/builtins/ctx#expand_location

],
use_execroot_entry_point = False,
)
Expand Down
2 changes: 1 addition & 1 deletion examples/vite3/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ vite_bin.vite(
fixed_args = [
"build",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :vite-config)",
"$(rlocation :vite-config)",
],
out_dirs = ["build"],
)
Expand Down
2 changes: 1 addition & 1 deletion examples/vite6/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ vite_bin.vite(
fixed_args = [
"build",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :vite-config)",
"$(rlocation :vite-config)",
],
out_dirs = ["build"],
)
Expand Down
2 changes: 1 addition & 1 deletion examples/webpack_cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ bin.webpack_cli(
data = [":webpack-config"],
fixed_args = [
"--config",
"$$RUNFILES_DIR/$(rlocationpath :webpack-config)",
"$(rlocation :webpack-config)",
],
log_level = "debug",
)
Expand Down
2 changes: 2 additions & 0 deletions js/libs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ load(
"//js/private:js_helpers.bzl",
_LOG_LEVELS = "LOG_LEVELS",
_envs_for_log_level = "envs_for_log_level",
_expand_rlocation_refs = "expand_rlocation_refs",
_gather_files_from_js_infos = "gather_files_from_js_infos",
_gather_npm_package_store_infos = "gather_npm_package_store_infos",
_gather_npm_sources = "gather_npm_sources",
Expand All @@ -25,6 +26,7 @@ js_library_lib = _js_library_lib

js_lib_helpers = struct(
envs_for_log_level = _envs_for_log_level,
expand_rlocation_refs = _expand_rlocation_refs,
gather_files_from_js_infos = _gather_files_from_js_infos,
gather_npm_sources = _gather_npm_sources,
gather_npm_package_store_infos = _gather_npm_package_store_infos,
Expand Down
2 changes: 1 addition & 1 deletion js/private/coverage/bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ rollup_bin.rollup(
fixed_args = [
"c8.js",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :config)",
"$(rlocation :config)",
"--format",
"cjs",
"--file",
Expand Down
2 changes: 1 addition & 1 deletion js/private/devserver/src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rollup_bin.rollup(
fixed_args = [
"js_run_devserver.mjs",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :config)",
"$(rlocation :config)",
"--format",
"es",
"--file",
Expand Down
19 changes: 13 additions & 6 deletions js/private/js_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ load("@bazel_lib//lib:directory_path.bzl", "DirectoryPathInfo")
load("@bazel_lib//lib:expand_make_vars.bzl", "expand_locations", "expand_variables")
load("@bazel_lib//lib:windows_utils.bzl", "create_windows_native_launcher_script")
load(":bash.bzl", "BASH_INITIALIZE_RUNFILES")
load(":js_helpers.bzl", "LOG_LEVELS", "envs_for_log_level", "gather_files_from_js_infos", "gather_runfiles")
load(":js_helpers.bzl", "LOG_LEVELS", "envs_for_log_level", "expand_rlocation_refs", "gather_files_from_js_infos", "gather_runfiles")

_ATTRS = {
"chdir": attr.string(
Expand Down Expand Up @@ -78,8 +78,9 @@ _ATTRS = {
),
"expand_args": attr.bool(
default = True,
doc = """Enables [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables)
and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution for `fixed_args`.
doc = """Enables [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables),
["Make variable"](https://bazel.build/reference/be/make-variables), and our own custom `$(rlocation)`
substitution for `fixed_args`.

This comes at some analysis-time cost even for a set of args that does not have any expansions.""",
),
Expand All @@ -94,8 +95,14 @@ _ATTRS = {
doc = """Fixed command line arguments to pass to the Node.js when this
binary target is executed.

Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables)
and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution if `expand_args` is set to True.
Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables),
["Make variable"](https://bazel.build/reference/be/make-variables), and `$(rlocation)` substitution
if `expand_args` is set to True.

The `$(rlocation :label)` syntax is unique to `js_binary` and expands to the
absolute path to `:label` in the runfiles. This is supported only in `fixed_args`,
because part of the evaluation has to occur at run time, inside the wrapper
script.

Unlike the built-in `args`, which are only passed to the target when it is
executed either by the `bazel run` command or as a test, `fixed_args` are baked
Expand Down Expand Up @@ -374,7 +381,7 @@ def _bash_launcher(ctx, nodeinfo, entry_point_path, log_prefix_rule_set, log_pre
node_options.append(_NODE_OPTION.format(value = "--preserve-symlinks-main"))

if ctx.attr.expand_args:
fixed_args = [expand_variables(ctx, expand_locations(ctx, fixed_arg, ctx.attr.data)) for fixed_arg in fixed_args]
fixed_args = [expand_variables(ctx, expand_locations(ctx, expand_rlocation_refs(fixed_arg), ctx.attr.data)) for fixed_arg in fixed_args]

toolchain_files = []
if is_windows:
Expand Down
30 changes: 30 additions & 0 deletions js/private/js_helpers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,36 @@ def gather_runfiles(
for target in deps
])

def expand_rlocation_refs(value):
"""Pre-processes $(rlocation <label>) into $$RUNFILES_DIR/$(rlocationpath <label>).

After this transformation, the standard expand_locations/expand_variables chain
resolves the rlocationpath and converts $$ to a literal $.
"""
result = []
remaining = value
prefix = "$(rlocation "
for _ in range(len(value)):
idx = remaining.find(prefix)
if idx == -1:
break
result.append(remaining[:idx])
remaining = remaining[idx + len(prefix):]

# Parentheses are allowed in Bazel target names and could therefore

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can they!? I thought we exclusively escaped them in rules_js because they can't....

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, surprisingly they are explicitly allowed according to the documentation here: https://bazel.build/concepts/labels#target-names

# theoretically appear in a label. We just look for the first closing
# parenthesis without handling that possibility, as this is what Bazel
# itself does:
# https://github.com/bazelbuild/bazel/blob/b4f16d988ddebc1891d7af57622ec5aff149a838/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java#L179
end = remaining.find(")")
Comment thread
acozzette marked this conversation as resolved.
if end == -1:
fail("Unclosed $(rlocation ...) in: " + value)
label_str = remaining[:end]
result.append("$$RUNFILES_DIR/$(rlocationpath " + label_str + ")")
Comment thread
jbedard marked this conversation as resolved.
remaining = remaining[end + 1:]
result.append(remaining)
return "".join(result)

LOG_LEVELS = {
"fatal": 1,
"error": 2,
Expand Down
3 changes: 3 additions & 0 deletions js/private/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("@bazel_lib//lib:write_source_files.bzl", "write_source_files")
load("@bazel_lib_host//:defs.bzl", "host")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("//js:defs.bzl", "js_binary", "js_library", "js_test")
load(":js_helpers_test.bzl", "js_helpers_test_suite")
load(":js_library_test.bzl", "js_library_test_suite")
load(":run_environment_info_test.bzl", "run_environment_info_test_suite")

Expand Down Expand Up @@ -39,6 +40,8 @@ write_source_files(
},
)

js_helpers_test_suite(name = "js_helpers_test")

js_library_test_suite(name = "js_library_test")

run_environment_info_test_suite(name = "run_environment_info_tests")
Expand Down
61 changes: 61 additions & 0 deletions js/private/test/js_helpers_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Tests for js_helpers utility functions"""

load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load("//js/private:js_helpers.bzl", "expand_rlocation_refs")

def _no_rlocation_refs_test(ctx):
env = unittest.begin(ctx)
asserts.equals(env, "build", expand_rlocation_refs("build"))
return unittest.end(env)

def _single_rlocation_ref_test(ctx):
env = unittest.begin(ctx)
asserts.equals(
env,
"$$RUNFILES_DIR/$(rlocationpath :rspack_config)",
expand_rlocation_refs("$(rlocation :rspack_config)"),
)
return unittest.end(env)

def _rlocation_ref_with_surrounding_text_test(ctx):
env = unittest.begin(ctx)
asserts.equals(
env,
"--config=$$RUNFILES_DIR/$(rlocationpath :my_config)",
expand_rlocation_refs("--config=$(rlocation :my_config)"),
)
return unittest.end(env)

def _multiple_rlocation_refs_test(ctx):
env = unittest.begin(ctx)
asserts.equals(
env,
"$$RUNFILES_DIR/$(rlocationpath :foo):$$RUNFILES_DIR/$(rlocationpath :bar)",
expand_rlocation_refs("$(rlocation :foo):$(rlocation :bar)"),
)
return unittest.end(env)

def _absolute_label_rlocation_ref_test(ctx):
env = unittest.begin(ctx)
asserts.equals(
env,
"$$RUNFILES_DIR/$(rlocationpath //some/pkg:target)",
expand_rlocation_refs("$(rlocation //some/pkg:target)"),
)
return unittest.end(env)

no_rlocation_refs_test = unittest.make(_no_rlocation_refs_test)
single_rlocation_ref_test = unittest.make(_single_rlocation_ref_test)
rlocation_ref_with_surrounding_text_test = unittest.make(_rlocation_ref_with_surrounding_text_test)
multiple_rlocation_refs_test = unittest.make(_multiple_rlocation_refs_test)
absolute_label_rlocation_ref_test = unittest.make(_absolute_label_rlocation_ref_test)

def js_helpers_test_suite(name):
unittest.suite(
name,
no_rlocation_refs_test,
single_rlocation_ref_test,
rlocation_ref_with_surrounding_text_test,
multiple_rlocation_refs_test,
absolute_label_rlocation_ref_test,
)
2 changes: 1 addition & 1 deletion js/private/test/node-patches/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ babel_bin.babel(
data = [":babel_config"],
fixed_args = [
"--config-file",
"$$RUNFILES_DIR/$(rlocationpath :babel_config)",
"$(rlocation :babel_config)",
"--extensions",
".mjs",
"--out-file-extension",
Expand Down
2 changes: 1 addition & 1 deletion js/private/worker/src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ rollup_bin.rollup(
fixed_args = [
"index.ts",
"--config",
"$$RUNFILES_DIR/$(rlocationpath :config)",
"$(rlocation :config)",
"--format",
"cjs",
"--file",
Expand Down
2 changes: 1 addition & 1 deletion npm/private/lifecycle/src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rollup_bin.rollup(
fixed_args = [
"lifecycle-hooks.js",
"--config",
"$$RUNFILES_DIR/$(rlocationpath //npm/private/lifecycle:rollup_config)",
"$(rlocation //npm/private/lifecycle:rollup_config)",
"--format",
"cjs",
"--file",
Expand Down
Loading