From 87b2a647f29e3ef5bf7114c113b0a9a26970ea4a Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Tue, 4 Feb 2020 16:23:02 -0800 Subject: [PATCH] feat(builtin): add environment attribute to yarn_install & npm_install (#1596) This allows you to specify a dict of environment variables for Bazel to set before calling yarn and npm in the yarn_install and npm_install repository rules respectively. Also set BAZEL_YARN_INSTALL to "1" and BAZEL_NPM_INSTALL to "1" respectively (unless they are set to another value by the environment attribute). --- WORKSPACE | 18 +++++++++++++++ internal/npm_install/npm_install.bzl | 28 +++++++++++++++++++++-- internal/npm_install/test/postinstall.js | 14 ++++++++++++ package.json | 3 ++- tools/fine_grained_deps_npm/package.json | 3 +++ tools/fine_grained_deps_yarn/package.json | 3 +++ 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 internal/npm_install/test/postinstall.js diff --git a/WORKSPACE b/WORKSPACE index 3bd9b5a41c..be95dcab8a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -68,6 +68,12 @@ load("@build_bazel_rules_nodejs//:index.bzl", "npm_install", "yarn_install") yarn_install( name = "npm", + data = [ + "//internal/npm_install/test:postinstall.js", + ], + environment = { + "SOME_USER_ENV": "yarn is great!", + }, # The @npm//:node_modules_filegroup generated by manual_build_file_contents # is used in the //packages/typescript/test/reference_types_directive:tsconfig_types # test. For now we're still supporting node_modules as a filegroup tho this may @@ -192,6 +198,12 @@ local_repository( yarn_install( name = "fine_grained_deps_yarn", + data = [ + "//internal/npm_install/test:postinstall.js", + ], + environment = { + "SOME_USER_ENV": "yarn is great!", + }, included_files = [ "", ".js", @@ -206,6 +218,12 @@ yarn_install( npm_install( name = "fine_grained_deps_npm", + data = [ + "//internal/npm_install/test:postinstall.js", + ], + environment = { + "SOME_USER_ENV": "npm is cool!", + }, included_files = [ "", ".js", diff --git a/internal/npm_install/npm_install.bzl b/internal/npm_install/npm_install.bzl index 55d5afbe9e..8526bfdd80 100644 --- a/internal/npm_install/npm_install.bzl +++ b/internal/npm_install/npm_install.bzl @@ -70,6 +70,10 @@ If symlink_node_modules is True, this attribute is ignored since the dependency manager will run in the package.json location. """, ), + "environment": attr.string_dict( + doc = """Environment variables to set before calling the package manager.""", + default = {}, + ), "included_files": attr.string_list( doc = """List of file extensions to be included in the npm package targets. @@ -263,11 +267,17 @@ cd "{root}" && "{npm}" {npm_args} if result.return_code: fail("pre_process_package_json.js failed: \nSTDOUT:\n%s\nSTDERR:\n%s" % (result.stdout, result.stderr)) + env = dict(repository_ctx.attr.environment) + env_key = "BAZEL_NPM_INSTALL" + if env_key not in env.keys(): + env[env_key] = "1" + repository_ctx.report_progress("Running npm install on %s" % repository_ctx.attr.package_json) result = repository_ctx.execute( [repository_ctx.path("_npm.cmd" if is_windows_host else "_npm.sh")], timeout = repository_ctx.attr.timeout, quiet = repository_ctx.attr.quiet, + environment = env, ) if result.return_code: @@ -303,7 +313,11 @@ See npm CLI docs https://docs.npmjs.com/cli/install.html for complete list of su allow_single_file = True, ), }), - doc = "Runs npm install during workspace setup.", + doc = """Runs npm install during workspace setup. + +This rule will set the environment variable `BAZEL_NPM_INSTALL` to '1' (unless it +set to another value in the environment attribute). Scripts may use to this to +check if yarn is being run by the `npm_install` repository rule.""", implementation = _npm_install_impl, ) @@ -390,11 +404,17 @@ cd "{root}" && "{yarn}" {yarn_args} if result.return_code: fail("pre_process_package_json.js failed: \nSTDOUT:\n%s\nSTDERR:\n%s" % (result.stdout, result.stderr)) + env = dict(repository_ctx.attr.environment) + env_key = "BAZEL_YARN_INSTALL" + if env_key not in env.keys(): + env[env_key] = "1" + repository_ctx.report_progress("Running yarn install on %s" % repository_ctx.attr.package_json) result = repository_ctx.execute( [repository_ctx.path("_yarn.cmd" if is_windows_host else "_yarn.sh")], timeout = repository_ctx.attr.timeout, quiet = repository_ctx.attr.quiet, + environment = env, ) if result.return_code: fail("yarn_install failed: %s (%s)" % (result.stdout, result.stderr)) @@ -435,6 +455,10 @@ to yarn so that the local cache is contained within the external repository. allow_single_file = True, ), }), - doc = "Runs yarn install during workspace setup.", + doc = """Runs yarn install during workspace setup. + +This rule will set the environment variable `BAZEL_YARN_INSTALL` to '1' (unless it +set to another value in the environment attribute). Scripts may use to this to +check if yarn is being run by the `yarn_install` repository rule.""", implementation = _yarn_install_impl, ) diff --git a/internal/npm_install/test/postinstall.js b/internal/npm_install/test/postinstall.js new file mode 100644 index 0000000000..fb071b924c --- /dev/null +++ b/internal/npm_install/test/postinstall.js @@ -0,0 +1,14 @@ +// This script is called by postinstall steps of yarn_install & npm_install rules in the root +// WORKSPACE. It tests that the environment attribute sets environment variables as expected. + +const expectedYarn = 'yarn is great!'; +if (process.env['BAZEL_YARN_INSTALL'] === '1' && process.env['SOME_USER_ENV'] !== expectedYarn) { + throw `Expected SOME_USER_ENV environment variable to be set to '${ + expectedYarn}' by yarn_install but got '${process.env['SOME_USER_ENV']}'`; +} + +const expectedNpm = 'npm is cool!'; +if (process.env['BAZEL_NPM_INSTALL'] === '1' && process.env['SOME_USER_ENV'] !== expectedNpm) { + throw `Expected SOME_USER_ENV environment variable to be set to '${ + expectedNpm}' by npm_install but got '${process.env['SOME_USER_ENV']}'`; +} diff --git a/package.json b/package.json index 034e8da21c..84e727a206 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,8 @@ "format": "git-clang-format", "format-all": "clang-format --glob='{internal/**/,examples/**/}*.{js,ts}' -i", "stardoc": "bazel build //docs && cp -f dist/bin/docs/*.md docs", - "version": "conventional-changelog -p angular -i CHANGELOG.md -s && node ./scripts/on-version.js && bazel build //:release && node ./scripts/on-release.js && git stage index.bzl docs/install.md packages/create/index.js README.md CHANGELOG.md e2e/*/WORKSPACE examples/*/WORKSPACE" + "version": "conventional-changelog -p angular -i CHANGELOG.md -s && node ./scripts/on-version.js && bazel build //:release && node ./scripts/on-release.js && git stage index.bzl docs/install.md packages/create/index.js README.md CHANGELOG.md e2e/*/WORKSPACE examples/*/WORKSPACE", + "postinstall": "node internal/npm_install/test/postinstall.js" }, "husky": { "hooks": { diff --git a/tools/fine_grained_deps_npm/package.json b/tools/fine_grained_deps_npm/package.json index a9f4f0a0ef..a57c6deba8 100644 --- a/tools/fine_grained_deps_npm/package.json +++ b/tools/fine_grained_deps_npm/package.json @@ -12,5 +12,8 @@ "http-server": "github:alexeagle/http-server#97205e945b69091606ed83aa0c8489e9ce65d282", "klaw": "1.3.1", "rxjs": "6.5.0" + }, + "scripts": { + "postinstall": "node internal/npm_install/test/postinstall.js" } } diff --git a/tools/fine_grained_deps_yarn/package.json b/tools/fine_grained_deps_yarn/package.json index a9f4f0a0ef..a57c6deba8 100644 --- a/tools/fine_grained_deps_yarn/package.json +++ b/tools/fine_grained_deps_yarn/package.json @@ -12,5 +12,8 @@ "http-server": "github:alexeagle/http-server#97205e945b69091606ed83aa0c8489e9ce65d282", "klaw": "1.3.1", "rxjs": "6.5.0" + }, + "scripts": { + "postinstall": "node internal/npm_install/test/postinstall.js" } }