Skip to content

Commit c9b159f

Browse files
authored
feat(builtin): add env attribute to nodejs test and binary and run_node helper (#2499)
1 parent 94a6151 commit c9b159f

File tree

5 files changed

+57
-2
lines changed

5 files changed

+57
-2
lines changed

internal/node/node.bzl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ def _nodejs_binary_impl(ctx):
174174
# runfiles helpers to use.
175175
env_vars = "export BAZEL_TARGET=%s\n" % ctx.label
176176

177+
# Add all env vars from the ctx attr
178+
for [key, value] in ctx.attr.env.items():
179+
env_vars += "export %s=%s\n" % (key, expand_location_into_runfiles(ctx, value, ctx.attr.data))
180+
177181
# While we can derive the workspace from the pwd when running locally
178182
# because it is in the execroot path `execroot/my_wksp`, on RBE the
179183
# `execroot/my_wksp` path is reduced a path such as `/w/f/b` so
@@ -448,6 +452,12 @@ nodejs_binary(
448452
mandatory = True,
449453
allow_single_file = True,
450454
),
455+
"env": attr.string_dict(
456+
doc = """Specifies additional environment variables to set when the target is executed, subject to location
457+
expansion.
458+
""",
459+
default = {},
460+
),
451461
"link_workspace_root": attr.bool(
452462
doc = """Link the workspace root to the bin_dir to support absolute requires like 'my_wksp/path/to/file'.
453463
If source files need to be required then they can be copied to the bin_dir with copy_to_bin.""",

internal/node/npm_package_bin.bzl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ _ATTRS = {
1111
"chdir": attr.string(),
1212
"configuration_env_vars": attr.string_list(default = []),
1313
"data": attr.label_list(allow_files = True, aspects = [module_mappings_aspect, node_modules_aspect]),
14+
"env": attr.string_dict(default = {}),
1415
"exit_code_out": attr.output(),
1516
"link_workspace_root": attr.bool(),
1617
"output_dir": attr.bool(),
@@ -80,6 +81,7 @@ def _impl(ctx):
8081
arguments = [args],
8182
configuration_env_vars = ctx.attr.configuration_env_vars,
8283
chdir = expand_variables(ctx, ctx.attr.chdir),
84+
env = ctx.attr.env,
8385
stdout = ctx.outputs.stdout,
8486
stderr = ctx.outputs.stderr,
8587
exit_code_out = ctx.outputs.exit_code_out,
@@ -93,7 +95,18 @@ _npm_package_bin = rule(
9395
attrs = _ATTRS,
9496
)
9597

96-
def npm_package_bin(tool = None, package = None, package_bin = None, data = [], outs = [], args = [], output_dir = False, link_workspace_root = False, chdir = None, **kwargs):
98+
def npm_package_bin(
99+
tool = None,
100+
package = None,
101+
package_bin = None,
102+
data = [],
103+
env = {},
104+
outs = [],
105+
args = [],
106+
output_dir = False,
107+
link_workspace_root = False,
108+
chdir = None,
109+
**kwargs):
97110
"""Run an arbitrary npm package binary (e.g. a program under node_modules/.bin/*) under Bazel.
98111
99112
It must produce outputs. If you just want to run a program with `bazel run`, use the nodejs_binary rule.
@@ -192,6 +205,7 @@ def npm_package_bin(tool = None, package = None, package_bin = None, data = [],
192205
args = ["/".join([".."] * _package_segments + ["$@"])],
193206
)
194207
```
208+
env: specifies additional environment variables to set when the target is executed
195209
**kwargs: additional undocumented keyword args
196210
"""
197211
if not tool:
@@ -205,6 +219,7 @@ def npm_package_bin(tool = None, package = None, package_bin = None, data = [],
205219
outs = outs,
206220
args = args,
207221
chdir = chdir,
222+
env = env,
208223
output_dir = output_dir,
209224
tool = tool,
210225
link_workspace_root = link_workspace_root,

internal/node/test/BUILD.bazel

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ jasmine_node_test(
7676
data = [
7777
":dump_build_env.json",
7878
":dump_build_env_alt.json",
79+
":dump_build_env_attr_json",
7980
],
8081
)
8182

@@ -384,6 +385,15 @@ jasmine_node_test(
384385
],
385386
)
386387

388+
nodejs_binary(
389+
name = "dump_build_env_attr",
390+
data = ["dump_build_env.js"],
391+
entry_point = "dump_build_env.js",
392+
env = {
393+
"LOC": "$(location :dump_build_env.js)",
394+
},
395+
)
396+
387397
nodejs_binary(
388398
name = "dump_build_env",
389399
entry_point = "dump_build_env.js",
@@ -409,6 +419,16 @@ npm_package_bin(
409419
tool = ":dump_build_env_alt",
410420
)
411421

422+
npm_package_bin(
423+
name = "dump_build_env_attr_json",
424+
outs = ["dump_build_env_attr.json"],
425+
args = ["$@"],
426+
env = {
427+
"FOO": "BAR",
428+
},
429+
tool = ":dump_build_env_attr",
430+
)
431+
412432
nodejs_binary(
413433
name = "test_runfiles_helper",
414434
data = [":test_runfiles_helper.golden"],

internal/node/test/env.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,10 @@ describe('launcher.sh environment', function() {
9696
]
9797
expectPathsToMatch(env['BAZEL_PATCH_ROOTS'].split(','), expectedRoots);
9898
});
99+
100+
it('should setup correct bazel environment variables from env attr', function() {
101+
const env = require(runfiles.resolvePackageRelative('dump_build_env_attr.json'));
102+
expect(env['FOO']).toBe('BAR');
103+
expect(env['LOC']).toBe('build_bazel_rules_nodejs/internal/node/test/dump_build_env.js');
104+
});
99105
});

internal/providers/node_runtime_deps_info.bzl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
"""Custom provider that mimics the Runfiles, but doesn't incur the expense of creating the runfiles symlink tree"""
1616

17+
load("//internal/common:expand_into_runfiles.bzl", "expand_location_into_runfiles")
1718
load("//internal/linker:link_node_modules.bzl", "add_arg", "write_node_modules_manifest")
1819
load("//internal/providers:external_npm_package_info.bzl", "ExternalNpmPackageInfo")
1920

@@ -115,7 +116,10 @@ def run_node(ctx, inputs, arguments, executable, chdir = None, **kwargs):
115116
if chdir:
116117
add_arg(arguments, "--bazel_node_working_dir=" + chdir)
117118

118-
env = kwargs.pop("env", {})
119+
env = dict({}, **kwargs.pop("env", {}))
120+
if hasattr(ctx.attr, "data"):
121+
for [key, value] in env.items():
122+
env[key] = expand_location_into_runfiles(ctx, value, ctx.attr.data)
119123

120124
# Always forward the COMPILATION_MODE to node process as an environment variable
121125
configuration_env_vars = kwargs.pop("configuration_env_vars", []) + ["COMPILATION_MODE"]

0 commit comments

Comments
 (0)