Skip to content

Commit d245d09

Browse files
authored
refactor(builtin): add args to yarn_install & npm_install (#1462)
BREAKING CHANGE: `args` in yarn_install and npm_install can be used to pass arbitrary arguments so we removed the following attributes: * prod_only from yarn_install and npm_install; should be replaced by args = ["--prod"] and args = ["--production"] respectively * frozen_lockfile from yarn_install; should be replaced by args = ["--frozen-lockfile"] * network_timeout from yanr_install; should be replaced by args = ["--network_timeout", "<time in ms>"]
1 parent f0ffff7 commit d245d09

8 files changed

Lines changed: 54 additions & 37 deletions

File tree

e2e/packages/WORKSPACE

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ node_repositories()
1717

1818
npm_install(
1919
name = "e2e_packages_npm_install",
20+
args = ["--production"],
2021
data = ["//:postinstall.js"],
2122
package_json = "//:npm1/package.json",
2223
package_lock_json = "//:npm1/package-lock.json",
23-
# Just here as a smoke test for this attribute
24-
prod_only = True,
2524
symlink_node_modules = False,
2625
)
2726

2827
npm_install(
2928
name = "e2e_packages_npm_install_duplicate_for_determinism_testing",
29+
args = ["--production"],
3030
data = ["//:postinstall.js"],
3131
package_json = "//:npm2/package.json",
3232
package_lock_json = "//:npm2/package-lock.json",
@@ -35,6 +35,7 @@ npm_install(
3535

3636
yarn_install(
3737
name = "e2e_packages_yarn_install",
38+
args = ["--prod"],
3839
data = ["//:postinstall.js"],
3940
package_json = "//:yarn1/package.json",
4041
symlink_node_modules = False,
@@ -43,6 +44,7 @@ yarn_install(
4344

4445
yarn_install(
4546
name = "e2e_packages_yarn_install_duplicate_for_determinism_testing",
47+
args = ["--prod"],
4648
data = ["//:postinstall.js"],
4749
package_json = "//:yarn2/package.json",
4850
symlink_node_modules = False,

e2e/packages/npm1/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"jsesc": "~1.2.0",
55
"jasmine": "2.8.0"
66
},
7+
"devDependencies": {
8+
"tmp": "0.1.0"
9+
},
710
"scripts": {
811
"postinstall": "node ./postinstall.js"
912
}

e2e/packages/npm2/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"jsesc": "~1.2.0",
55
"jasmine": "2.8.0"
66
},
7+
"devDependencies": {
8+
"tmp": "0.1.0"
9+
},
710
"scripts": {
811
"postinstall": "node ./postinstall.js"
912
}

e2e/packages/npm_determinism.spec.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ const packageJsonPath2 = packageJsonPath.replace(
88
'/e2e_packages_npm_install_duplicate_for_determinism_testing/', '/e2e_packages_npm_install/');
99
const packageJson2 = JSON.parse(fs.readFileSync(packageJsonPath2));
1010

11+
try {
12+
require.resolve('tmp');
13+
console.error(
14+
'expected tmp to not be installed by npm as --production was passed via args in npm_install');
15+
process.exitCode = 1;
16+
} catch (_) {
17+
}
1118

1219
if (packageJsonPath === packageJsonPath2) {
1320
console.error('expected different json paths');

e2e/packages/yarn1/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"jsesc": "~1.2.0",
55
"jasmine": "2.8.0"
66
},
7+
"devDependencies": {
8+
"tmp": "0.1.0"
9+
},
710
"scripts": {
811
"postinstall": "node ./postinstall.js"
912
}

e2e/packages/yarn2/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"jsesc": "~1.2.0",
55
"jasmine": "2.8.0"
66
},
7+
"devDependencies": {
8+
"tmp": "0.1.0"
9+
},
710
"scripts": {
811
"postinstall": "node ./postinstall.js"
912
}

e2e/packages/yarn_determinism.spec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ const packageJsonPath2 = packageJsonPath.replace(
88
'/e2e_packages_yarn_install_duplicate_for_determinism_testing/', '/e2e_packages_yarn_install/');
99
const packageJson2 = JSON.parse(fs.readFileSync(packageJsonPath2));
1010

11+
try {
12+
require.resolve('tmp');
13+
console.error(
14+
'expected tmp to not be installed by yarn as --prod was passed via args in yarn_install');
15+
process.exitCode = 1;
16+
} catch (_) {
17+
}
18+
1119
if (packageJsonPath === packageJsonPath2) {
1220
console.error('expected different json paths');
1321
process.exitCode = 1;

internal/npm_install/npm_install.bzl

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ load("//internal/common:os_name.bzl", "is_windows_os")
2626
load("//internal/node:node_labels.bzl", "get_node_label", "get_npm_label", "get_yarn_label")
2727

2828
COMMON_ATTRIBUTES = dict(dict(), **{
29+
"timeout": attr.int(
30+
default = 3600,
31+
doc = """Maximum duration of the package manager execution in seconds.""",
32+
),
2933
"always_hide_bazel_files": attr.bool(
3034
doc = """Always hide Bazel build files such as `BUILD` and BUILD.bazel` by prefixing them with `_`.
3135
@@ -101,10 +105,6 @@ fine grained npm dependencies.
101105
mandatory = True,
102106
allow_single_file = True,
103107
),
104-
"prod_only": attr.bool(
105-
default = False,
106-
doc = "Don't install devDependencies",
107-
),
108108
"quiet": attr.bool(
109109
default = True,
110110
doc = "If stdout and stderr should be printed to the terminal.",
@@ -207,10 +207,7 @@ def _npm_install_impl(repository_ctx):
207207
is_windows_host = is_windows_os(repository_ctx)
208208
node = repository_ctx.path(get_node_label(repository_ctx))
209209
npm = get_npm_label(repository_ctx)
210-
npm_args = ["install"]
211-
212-
if repository_ctx.attr.prod_only:
213-
npm_args.append("--production")
210+
npm_args = ["install"] + repository_ctx.attr.args
214211

215212
# If symlink_node_modules is true then run the package manager
216213
# in the package.json folder; otherwise, run it in the root of
@@ -294,10 +291,11 @@ cd "{root}" && "{npm}" {npm_args}
294291

295292
npm_install = repository_rule(
296293
attrs = dict(COMMON_ATTRIBUTES, **{
297-
"timeout": attr.int(
298-
default = 3600,
299-
doc = """Maximum duration of the command "npm install" in seconds
300-
(default is 3600 seconds).""",
294+
"args": attr.string_list(
295+
doc = """Arguments passed to npm install.
296+
297+
See npm CLI docs https://docs.npmjs.com/cli/install.html for complete list of supported arguments.""",
298+
default = [],
301299
),
302300
"package_lock_json": attr.label(
303301
mandatory = True,
@@ -345,15 +343,8 @@ def _yarn_install_impl(repository_ctx):
345343
repository_ctx.path(yarn),
346344
"--cwd",
347345
root,
348-
"--network-timeout",
349-
str(repository_ctx.attr.network_timeout * 1000), # in ms
350346
]
351347

352-
if repository_ctx.attr.frozen_lockfile:
353-
args.append("--frozen-lockfile")
354-
355-
if repository_ctx.attr.prod_only:
356-
args.append("--prod")
357348
if not repository_ctx.attr.use_global_yarn_cache:
358349
args.extend(["--cache-folder", repository_ctx.path("_yarn_cache")])
359350
else:
@@ -365,6 +356,8 @@ def _yarn_install_impl(repository_ctx):
365356
# artifacts somewhere, so we rely on yarn to be correct.
366357
args.extend(["--mutex", "network"])
367358

359+
args.extend(repository_ctx.attr.args)
360+
368361
repository_ctx.report_progress("Running yarn install on %s" % repository_ctx.attr.package_json)
369362
result = repository_ctx.execute(
370363
args,
@@ -381,23 +374,11 @@ def _yarn_install_impl(repository_ctx):
381374

382375
yarn_install = repository_rule(
383376
attrs = dict(COMMON_ATTRIBUTES, **{
384-
"timeout": attr.int(
385-
default = 3600,
386-
doc = """Maximum duration of the command "yarn install" in seconds
387-
(default is 3600 seconds).""",
388-
),
389-
"frozen_lockfile": attr.bool(
390-
default = False,
391-
doc = """Passes the --frozen-lockfile flag to prevent updating yarn.lock.
377+
"args": attr.string_list(
378+
doc = """Arguments passed to yarn install.
392379
393-
Note that enabling this option will require that you run yarn outside of Bazel
394-
when making changes to package.json.
395-
""",
396-
),
397-
"network_timeout": attr.int(
398-
default = 300,
399-
doc = """Maximum duration of a network request made by yarn in seconds
400-
(default is 300 seconds).""",
380+
See yarn CLI docs https://yarnpkg.com/en/docs/cli/install for complete list of supported arguments.""",
381+
default = [],
401382
),
402383
"use_global_yarn_cache": attr.bool(
403384
default = True,
@@ -406,8 +387,15 @@ when making changes to package.json.
406387
The cache lets you avoid downloading packages multiple times.
407388
However, it can introduce non-hermeticity, and the yarn cache can
408389
have bugs.
390+
409391
Disabling this attribute causes every run of yarn to have a unique
410392
cache_directory.
393+
394+
If True, this rule will pass `--mutex network` to yarn to ensure that
395+
the global cache can be shared by parallelized yarn_install rules.
396+
397+
If False, this rule will pass `--cache-folder /path/to/external/repository/__yarn_cache`
398+
to yarn so that the local cache is contained within the external repository.
411399
""",
412400
),
413401
"yarn_lock": attr.label(

0 commit comments

Comments
 (0)