diff --git a/internal/node/launcher.sh b/internal/node/launcher.sh index df7ce89f..e6ce6176 100755 --- a/internal/node/launcher.sh +++ b/internal/node/launcher.sh @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Capture initial env var state, sans some shell vars +readarray -d '' INIT_ENV_ARGS < <(env -0 -u SHLVL -u _ -u PWD) + # --- begin runfiles.bash initialization v2 --- # Copy-pasted from the Bazel Bash runfiles library v2. set -uo pipefail; f=build_bazel_rules_nodejs/third_party/github.com/bazelbuild/bazel/tools/bash/runfiles/runfiles.bash @@ -92,6 +95,9 @@ export RUNFILES TEMPLATED_env_vars +# Metadata for recreation of node_modules symlinks if required +export NM_SYMLINKS="$(mktemp -d)/nm-symlinks.json" + # Note: for debugging it is useful to see what files are actually present # This redirects to stderr so it doesn't interfere with Bazel's worker protocol # find . -name thingImLookingFor 1>&2 @@ -390,14 +396,35 @@ if [[ -n "$NODE_WORKING_DIR" ]]; then fi set +e +# Prepare NodeJS args plus a cleaned environment +spawn_args=( + --ignore-environment + # Expose `NM_SYMLINKS` so persistent workers can recreate side effects if required + ${NM_SYMLINKS+"NM_SYMLINKS=${NM_SYMLINKS}"} + "${INIT_ENV_ARGS[@]}" + # Arguments for child NodeJS processes + ${NODE_REPOSITORY_ARGS+"NODE_REPOSITORY_ARGS=${NODE_REPOSITORY_ARGS}"} + # For coverage support + ${NODE_V8_COVERAGE+"NODE_V8_COVERAGE=${NODE_V8_COVERAGE}"} + # For NodeJS patches + ${RUNFILES_DIR+"RUNFILES_DIR=${RUNFILES_DIR}"} + ${RUNFILES+"RUNFILES=${RUNFILES}"} + ${BAZEL_PATCH_ROOTS+"BAZEL_PATCH_ROOTS=${BAZEL_PATCH_ROOTS}"} + "${node}" + ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} + ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} + "${MAIN}" + ${ARGS[@]+"${ARGS[@]}"} +) + if [[ -n "${STDOUT_CAPTURE}" ]] && [[ -n "${STDERR_CAPTURE}" ]]; then - "${node}" ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} "${MAIN}" ${ARGS[@]+"${ARGS[@]}"} <&0 >$STDOUT_CAPTURE 2>$STDERR_CAPTURE & + env "${spawn_args[@]}" <&0 >$STDOUT_CAPTURE 2>$STDERR_CAPTURE & elif [[ -n "${STDOUT_CAPTURE}" ]]; then - "${node}" ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} "${MAIN}" ${ARGS[@]+"${ARGS[@]}"} <&0 >$STDOUT_CAPTURE & + env "${spawn_args[@]}" <&0 >$STDOUT_CAPTURE & elif [[ -n "${STDERR_CAPTURE}" ]]; then - "${node}" ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} "${MAIN}" ${ARGS[@]+"${ARGS[@]}"} <&0 2>$STDERR_CAPTURE & + env "${spawn_args[@]}" <&0 2>$STDERR_CAPTURE & else - "${node}" ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} "${MAIN}" ${ARGS[@]+"${ARGS[@]}"} <&0 & + env "${spawn_args[@]}" <&0 & fi readonly child=$! diff --git a/internal/node/node.bzl b/internal/node/node.bzl index 46f28400..e6b7389e 100755 --- a/internal/node/node.bzl +++ b/internal/node/node.bzl @@ -191,10 +191,7 @@ def _nodejs_binary_impl(ctx): _write_loader_script(ctx) - # Provide the target name as an environment variable avaiable to all actions for the - # runfiles helpers to use. - env_vars = "export BAZEL_TARGET=%s\n" % ctx.label - env_vars += """export NM_SYMLINKS="$(mktemp -d)/nm-symlinks.json"\n""" + env_vars = "" # Add all env vars from the ctx attr for [key, value] in ctx.attr.env.items(): diff --git a/internal/pkg_npm/pkg_npm.bzl b/internal/pkg_npm/pkg_npm.bzl index 56c758a4..ea8ca6cd 100755 --- a/internal/pkg_npm/pkg_npm.bzl +++ b/internal/pkg_npm/pkg_npm.bzl @@ -258,6 +258,9 @@ def create_package(ctx, deps_files, nested_packages): inputs = inputs, outputs = [package_dir], arguments = [args], + # Without this, `PATH` is unset and OS specified defaults are used. + # e.g. Bash 3.2 on macoS Sonoma (via `/bin:/usr/bin`) + use_default_shell_env = True, ) _create_npm_scripts(ctx) @@ -290,6 +293,9 @@ def _create_npm_scripts(ctx): "no-remote-exec": "", "no-sandbox": "", }, + # Without this, `PATH` is unset and OS specified defaults are used. + # e.g. Bash 3.2 on macoS Sonoma (via `/bin:/usr/bin`) + use_default_shell_env = True, ) def _pkg_npm(ctx):