Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ npm/private/test/subs/package.json=-897547334
npm/private/test/vendored/is-odd/package.json=1041695223
npm/private/test/vendored/lodash-4.17.21.tgz=-1206623349
npm/private/test/vendored/semver-max/package.json=578664053
package.json=1856600154
pnpm-lock.yaml=-923227665
package.json=564790136
pnpm-lock.yaml=-1392643421
pnpm-workspace.yaml=1041196754
21 changes: 20 additions & 1 deletion .aspect/workflows/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ workspaces:
without: true
- bazel-9:
without: true
- bazel-9-no-execroot-entry-point:
without: true
e2e/pnpm_lockfiles:
icon: pnpm
tasks: *e2e_tasks
Expand All @@ -117,7 +119,17 @@ workspaces:
tasks: *e2e_tasks
e2e/repo_mapping:
icon: js
tasks: *e2e_tasks
tasks:
- test:
queue: aspect-medium
- format:
without: true
- buildifier:
without: true
# aspect_rules_js is given a different name in this repo, so we
# cannot use a flag beginning with --@aspect_rules_js//.
- bazel-9-no-execroot-entry-point:
without: true
e2e/output_paths:
icon: js
tasks: *e2e_tasks
Expand Down Expand Up @@ -167,6 +179,13 @@ tasks:
# TODO: change this back to 9.x once this bug is fixed:
# https://github.com/bazelbuild/bazel/issues/29393
USE_BAZEL_VERSION: '9.0.2'
- test:
name: Bazel 9 (no execroot entry point)
id: bazel-9-no-execroot-entry-point
bazel:
flags: ['--test_tag_filters=-skip-on-bazel9', '--@aspect_rules_js//js:use_execroot_entry_point=False']
env:
USE_BAZEL_VERSION: '9.0.2'
- format:
queue: aspect-medium
- buildifier:
Expand Down
2 changes: 2 additions & 0 deletions contrib/nextjs/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ def nextjs_build(name, config, srcs, next_js_binary, data = [], **kwargs):
chdir = native.package_name(),
mnemonic = "NextJs",
progress_message = "Compile Next.js app %{label}",
use_execroot_entry_point = True,
Comment thread
acozzette marked this conversation as resolved.
Outdated
**kwargs
)

Expand Down Expand Up @@ -327,6 +328,7 @@ def nextjs_standalone_build(name, config, srcs, next_js_binary, data = [], **kwa
chdir = native.package_name(),
mnemonic = "NextJs",
progress_message = "Compile Next.js standalone app %{label}",
use_execroot_entry_point = True,
**kwargs
)

Expand Down
14 changes: 14 additions & 0 deletions js/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
"Public API"

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")

# This flag controls the default behavior of the use_execroot_entry_point flag
# on js_run_binary.
bool_flag(
name = "use_execroot_entry_point",
build_setting_default = True,
visibility = ["//visibility:public"],
)

config_setting(
name = "_use_execroot_entry_point_true",
flag_values = {"use_execroot_entry_point": "True"},
)

bzl_library(
name = "defs",
Expand Down
36 changes: 28 additions & 8 deletions js/private/js_run_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def js_run_binary(
stderr = None,
exit_code_out = None,
silent_on_success = True,
use_execroot_entry_point = True,
use_execroot_entry_point = None,
copy_srcs_to_bin = True,
include_sources = True,
include_types = False,
Expand Down Expand Up @@ -149,6 +149,9 @@ def js_run_binary(
needed by the binary are available in the execroot output tree. This requirement can be turned off with by
setting `allow_execroot_entry_point_with_no_copy_data_to_bin` to True.

If `None` (the default), the behavior is controlled by the `//js:use_execroot_entry_point` build flag,
which defaults to `True`.

copy_srcs_to_bin: When True, all srcs files are copied to the output tree that are not already there.

include_sources: see `js_info_files` documentation
Expand Down Expand Up @@ -356,10 +359,10 @@ See https://github.com/aspect-build/rules_js/tree/main/docs#using-binaries-publi
name = bazel_lib_utils.to_label(name),
))

# Configure run from execroot
if use_execroot_entry_point:
fixed_env["JS_BINARY__USE_EXECROOT_ENTRY_POINT"] = "1"

# Configure run from execroot.
# When use_execroot_entry_point is None, behavior is controlled by the //js:use_execroot_entry_point flag.
execroot_extra_srcs = []
if use_execroot_entry_point != False:
# hoist all runfiles to srcs when running from execroot
js_runfiles_lib_name = "{}_runfiles_lib".format(name)
_js_library(
Expand All @@ -380,16 +383,33 @@ See https://github.com/aspect-build/rules_js/tree/main/docs#using-binaries-publi
# Always propagate the testonly attribute
testonly = kwargs.get("testonly", False),
)
extra_srcs.append(":{}".format(js_runfiles_name))

if use_execroot_entry_point == True:
fixed_env["JS_BINARY__USE_EXECROOT_ENTRY_POINT"] = "1"
execroot_extra_srcs = [":{}".format(js_runfiles_name)]
else:
# None: use the flag to decide at analysis time
execroot_extra_srcs = select({
Label("//js:_use_execroot_entry_point_true"): [":{}".format(js_runfiles_name)],
"//conditions:default": [],
})

if allow_execroot_entry_point_with_no_copy_data_to_bin:
fixed_env["JS_BINARY__ALLOW_EXECROOT_ENTRY_POINT_WITH_NO_COPY_DATA_TO_BIN"] = "1"

# When use_execroot_entry_point is None, the env var is resolved at analysis time via the flag.
# We use a select() only for the conditional portion and merge with | outside of it, so that
# a user-supplied env that is itself a select() remains valid on the right-hand side.
execroot_env = select({
Label("//js:_use_execroot_entry_point_true"): {"JS_BINARY__USE_EXECROOT_ENTRY_POINT": "1"},
"//conditions:default": {},
}) if use_execroot_entry_point == None else {}

_run_binary(
name = name,
tool = tool,
env = fixed_env | env,
srcs = srcs + extra_srcs,
env = fixed_env | execroot_env | env,
srcs = srcs + extra_srcs + execroot_extra_srcs,
outs = outs + extra_outs,
out_dirs = out_dirs,
args = args,
Expand Down
11 changes: 10 additions & 1 deletion js/private/js_run_devserver.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def js_run_devserver(
tool = None,
command = None,
grant_sandbox_write_permissions = False,
use_execroot_entry_point = True,
use_execroot_entry_point = None,
allow_execroot_entry_point_with_no_copy_data_to_bin = False,
**kwargs):
"""Runs a devserver via binary target or command.
Expand Down Expand Up @@ -253,6 +253,9 @@ def js_run_devserver(
needed by the binary are available in the execroot output tree. This requirement can be turned off with by
setting `allow_execroot_entry_point_with_no_copy_data_to_bin` to True.

If `None` (the default), the behavior is controlled by the `//js:use_execroot_entry_point` build flag,
which defaults to `True`.

allow_execroot_entry_point_with_no_copy_data_to_bin: Turn off validation that the `js_binary` tool
has `copy_data_to_bin` set to True when `use_execroot_entry_point` is set to True.

Expand All @@ -267,6 +270,12 @@ def js_run_devserver(
if kwargs.get("entry_point", None):
fail("`entry_point` is set implicitly by `js_run_devserver` and cannot be overridden.")

if use_execroot_entry_point == None:
use_execroot_entry_point = select({
Label("//js:_use_execroot_entry_point_true"): True,
"//conditions:default": False,
})

# Allow the js_run_devserver rule to execute to be overridden for tests
rule_to_execute = kwargs.pop("rule_to_execute", _js_run_devserver)

Expand Down
5 changes: 5 additions & 0 deletions js/private/test/data/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ js_test(
# TEST: js_test(data = js_run_binary(srcs)) ---------------
js_run_binary(
name = "run-write-srcs",
srcs = ["data.json"],
outs = ["rb0.json"],
args = [
"rb0.json",
Expand All @@ -178,6 +179,7 @@ js_test(
# TEST: js_test(data = js_run_binary(srcs = js_library(srcs))) ----------------
js_run_binary(
name = "run-write-js_library-srcs",
srcs = ["data.json"],
outs = ["rb1.json"],
args = [
"rb1.json",
Expand Down Expand Up @@ -210,6 +212,7 @@ js_binary(

js_run_binary(
name = "run-write-js_library-data",
srcs = ["data.json"],
outs = ["rb2.json"],
args = [
"rb2.json",
Expand All @@ -235,6 +238,7 @@ js_test(
# TEST: js_test(data = js_run_binary(srcs = genrule())) -----------------------
js_run_binary(
name = "run-write-generated",
srcs = ["data-generated.json"],
outs = ["rb3.json"],
args = [
"rb3.json",
Expand All @@ -260,6 +264,7 @@ js_test(
# TEST: js_test(data = js_run_binary(srcs = genrule(srcs = filegroup))) -------
js_run_binary(
name = "run-write-generated-copied",
srcs = ["data-copied.json"],
outs = ["rb4.json"],
args = [
"rb4.json",
Expand Down
143 changes: 143 additions & 0 deletions js/private/test/js_run_binary/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
load("@bazel_lib//lib:diff_test.bzl", "diff_test")
load("@bazel_lib//lib:testing.bzl", "assert_contains")
load("@bazel_lib//lib:transitions.bzl", "platform_transition_filegroup")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("//js:defs.bzl", "js_binary", "js_run_binary")

# We want to verify that a js_binary's data dependencies are found only in the
# runfiles when use_execroot_entry_point = False. To do this we use
# find_cfg_probe.mjs to tell us whether cfg_probe.txt landed in just the
# runfiles or somewhere else.
write_file(
name = "gen_cfg_probe",
out = "cfg_probe.txt",
content = ["probe"],
)

js_binary(
name = "find_cfg_probe",
data = [
":cfg_probe.txt",
"//:node_modules/@bazel/runfiles",
],
entry_point = "find_cfg_probe.mjs",
fixed_args = ["$(rlocationpath :cfg_probe.txt)"],
)

js_run_binary(
name = "runfiles_location",
stdout = "runfiles_location.txt",
tool = ":find_cfg_probe",
use_execroot_entry_point = False,
)

assert_contains(
name = "runfiles_test",
actual = ":runfiles_location.txt",
expected = "RUNFILES_ONLY",
)

# With use_execroot_entry_point = True, the tool's data dependencies are built
# in the target configuration and we should find them in the target bin
# directory, the same place a genrule would put its srcs.
js_run_binary(
name = "target_cfg_location",
stdout = "target_cfg_location.txt",
tool = ":find_cfg_probe",
use_execroot_entry_point = True,
)

genrule(
name = "expected_target_cfg_location",
srcs = [":cfg_probe.txt"],
outs = ["expected_target_cfg_location.txt"],
cmd = "echo $(execpath :cfg_probe.txt) > $@",
)

diff_test(
name = "target_cfg_test",
file1 = ":target_cfg_location.txt",
file2 = ":expected_target_cfg_location.txt",
)

# Verify that dependencies passed via the srcs parameter are always built for
# the target platform, unlike the tool parameter and its dependencies.
# We use a select() on the OS to produce a platform-specific file, then
# transition to three different target platforms and assert the contents match.
write_file(
name = "gen_os_name",
out = "os_name.txt",
content = select({
"@platforms//os:linux": ["linux"],
"@platforms//os:macos": ["macos"],
"@platforms//os:windows": ["windows"],
"//conditions:default": ["other"],
}),
tags = ["manual"],
)

platform(
name = "linux",
constraint_values = ["@platforms//os:linux"],
)

platform(
name = "macos",
constraint_values = ["@platforms//os:macos"],
)

platform(
name = "windows",
constraint_values = ["@platforms//os:windows"],
)

js_binary(
name = "read_file",
entry_point = "read_file.mjs",
)

js_run_binary(
name = "gen_target_os",
srcs = [":os_name.txt"],
args = ["$(rootpath :os_name.txt)"],
stdout = "target_os.txt",
tags = ["manual"],
tool = ":read_file",
use_execroot_entry_point = False,
)

platform_transition_filegroup(
name = "target_os_linux",
srcs = [":gen_target_os"],
target_platform = ":linux",
)

platform_transition_filegroup(
name = "target_os_macos",
srcs = [":gen_target_os"],
target_platform = ":macos",
)

platform_transition_filegroup(
name = "target_os_windows",
srcs = [":gen_target_os"],
target_platform = ":windows",
)

assert_contains(
name = "linux_target_platform_test",
actual = ":target_os_linux",
expected = "linux",
)

assert_contains(
name = "macos_target_platform_test",
actual = ":target_os_macos",
expected = "macos",
)

assert_contains(
name = "windows_target_platform_test",
actual = ":target_os_windows",
expected = "windows",
)
Loading
Loading