diff --git a/docs/Built-ins.md b/docs/Built-ins.md
index 464fbfb9e7..dea0826d6d 100755
--- a/docs/Built-ins.md
+++ b/docs/Built-ins.md
@@ -19,8 +19,8 @@ This is necessary to bootstrap Bazel to run the package manager to download othe
node_repositories(name, node_download_auth, node_repositories, node_urls, node_version,
- package_json, preserve_symlinks, repo_mapping, vendored_node, vendored_yarn,
- yarn_download_auth, yarn_repositories, yarn_urls, yarn_version)
+ package_json, preserve_symlinks, repo_mapping, use_nvmrc, vendored_node,
+ vendored_yarn, yarn_download_auth, yarn_repositories, yarn_urls, yarn_version)
To be run in user's WORKSPACE to install rules_nodejs dependencies.
@@ -195,6 +195,14 @@ Defaults to `True`
(*Dictionary: String -> String, mandatory*): A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).
+
use_nvmrc
+
+(*Label*): the local path of the .nvmrc file containing the version of node
+
+If set then also set node_version to the version found in the .nvmrc file.
+
+Defaults to `None`
+
vendored_node
(*Label*): the local path to a pre-installed NodeJS runtime.
diff --git a/internal/node/node_repositories.bzl b/internal/node/node_repositories.bzl
index 3e09c602fb..1401a03984 100644
--- a/internal/node/node_repositories.bzl
+++ b/internal/node/node_repositories.bzl
@@ -177,6 +177,13 @@ and `{filename}` with the matching entry from the `node_repositories` attribute.
default = _DEFAULT_NODE_VERSION,
doc = "the specific version of NodeJS to install or, if vendored_node is specified, the vendored version of node",
),
+ "use_nvmrc": attr.label(
+ allow_single_file = True,
+ default = None,
+ doc = """the local path of the .nvmrc file containing the version of node
+
+If set then also set node_version to the version found in the .nvmrc file.""",
+ ),
"package_json": attr.label_list(
doc = """(ADVANCED, not recommended)
a list of labels, which indicate the package.json files that will be installed
@@ -281,6 +288,11 @@ def _download_node(repository_ctx):
node_version = repository_ctx.attr.node_version
+ if repository_ctx.attr.use_nvmrc:
+ node_version = str(repository_ctx.read(repository_ctx.attr.use_nvmrc)).strip()
+
+ _verify_version_is_valid(node_version)
+
# Skip the download if we know it will fail
if not node_exists_for_os(node_version, host_os):
return
@@ -813,3 +825,8 @@ def node_repositories(**kwargs):
def _maybe(repo_rule, name, **kwargs):
if name not in native.existing_rules():
repo_rule(name = name, **kwargs)
+
+def _verify_version_is_valid(version):
+ major, minor, patch = (version.split(".") + [None, None, None])[:3]
+ if not major.isdigit() or not minor.isdigit() or not patch.isdigit():
+ fail("Invalid node version: %s" % version)