From fa38a4b5e3cd905c24e5e9fcde385d75542812c6 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 31 Jul 2024 12:50:58 +0700 Subject: [PATCH] chore(common): work around nvm being a function on linux, mac On Linux, macOS, nvm is only provided as a bash function, which means it is not available to the script unless nvm.sh is `source`d. Unfortunately, this is fragile -- variable usage, function names, etc. can all interfere with each other between build.sh and nvm.sh (for example, the `$VERSION` variable). So we have a wrapper script on those platforms to do our nvm invocation. Relates-to: nvm-sh/nvm#3257 --- resources/build/_builder_nvm.sh | 32 +++++++++++++++++++++++++++++++ resources/shellHelperFunctions.sh | 20 +++++++------------ 2 files changed, 39 insertions(+), 13 deletions(-) create mode 100755 resources/build/_builder_nvm.sh diff --git a/resources/build/_builder_nvm.sh b/resources/build/_builder_nvm.sh new file mode 100755 index 00000000000..47f89d9d8dc --- /dev/null +++ b/resources/build/_builder_nvm.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +set -e +set -u + +if [[ $# -lt 1 ]]; then + echo "This script is called by shellHelperFunctions.sh, _select_node_version_with_nvm()" + echo "during build.sh configure steps. It is not intended to be called directly, as it" + echo "is a wrapper for nvm." + exit 99 +fi + +REQUIRED_NODE_VERSION="$1" + +# +# nvm on macos and linux is a shell function. `source`ing it into our scripts is +# fragile because it uses some of the same variable names that we do. Safest way +# to work around this is to load it in a clean subshell and run it there. +# +# See also https://github.com/nvm-sh/nvm/issues/3257 (among others) +# + +type -t nvm >/dev/null || { + source "$NVM_DIR/nvm.sh" + type -t nvm >/dev/null || { + echo "Failed to find nvm" + exit 1 + } +} + +nvm install "$REQUIRED_NODE_VERSION" +nvm use "$REQUIRED_NODE_VERSION" diff --git a/resources/shellHelperFunctions.sh b/resources/shellHelperFunctions.sh index 7494fe6e1cf..e397812a23d 100755 --- a/resources/shellHelperFunctions.sh +++ b/resources/shellHelperFunctions.sh @@ -266,20 +266,15 @@ verify_npm_setup() { # Use nvm to select a node version according to package.json # This is typically run only on CI environments _select_node_version_with_nvm() { - type -t nvm >/dev/null || { - if [[ $BUILDER_OS != win ]]; then - # nvm on linux and macos is a shell function; we need to load it - source "$NVM_DIR/nvm.sh" - fi - type -t nvm >/dev/null || { - builder_die "Build environment setup error detected: nvm could not be found" - } - } - local REQUIRED_NODE_VERSION="$("$JQ" -r '.engines.node' "$KEYMAN_ROOT/package.json")" - try_multiple_times nvm install "$REQUIRED_NODE_VERSION" - nvm use "$REQUIRED_NODE_VERSION" + if [[ $BUILDER_OS != win ]]; then + # launch nvm in a clean subshell, see _builder_nvm.sh for details + env -i bash "$KEYMAN_ROOT/resources/build/_builder_nvm.sh" "$REQUIRED_NODE_VERSION" + else + nvm install "$REQUIRED_NODE_VERSION" + nvm use "$REQUIRED_NODE_VERSION" + fi local CURRENT_NODE_VERSION="$(node --version)" @@ -287,7 +282,6 @@ _select_node_version_with_nvm() { # https://github.com/coreybutler/nvm-windows/issues/738 # note the 'v' prefix that node emits (and npm doesn't!) if [[ "$CURRENT_NODE_VERSION" != "v$REQUIRED_NODE_VERSION" ]]; then - # builder_die "Attempted to select node.js version $REQUIRED_NODE_VERSION but found $CURRENT_NODE_VERSION instead" fi }