From f439acda4af4d22c985d02e75f8bddac1479869b Mon Sep 17 00:00:00 2001 From: Martin <16228305+maartin0@users.noreply.github.com> Date: Mon, 29 Aug 2022 16:01:36 +0100 Subject: [PATCH] [New] `nvm use`/`nvm install`: add `--save` option Fixes #2849. Co-authored-by: Martin Co-authored-by: Jordan Harband --- .dockerignore | 1 + .gitignore | 1 + nvm.sh | 36 +++++++- ...ng 'nvm install --save' works as expected' | 43 ++++++++++ ...ave' works with a .nvmrc in the parent dir | 57 ++++++++++++ ...e --silent --save' doesn't output anything | 43 ++++++++++ .../Running 'nvm use -w' works as expected' | 62 +++++++++++++ test/fast/Unit tests/nvm_write_nvmrc | 86 +++++++++++++++++++ 8 files changed, 327 insertions(+), 2 deletions(-) mode change 100644 => 100755 nvm.sh create mode 100644 test/fast/Unit tests/Running 'nvm install --save' works as expected' create mode 100644 test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir create mode 100644 test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything create mode 100644 test/fast/Unit tests/Running 'nvm use -w' works as expected' create mode 100644 test/fast/Unit tests/nvm_write_nvmrc diff --git a/.dockerignore b/.dockerignore index fc578ccc81..52e5428498 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,6 +8,7 @@ test/bak .urchin.log .urchin_stdout test/**/test_output +test/**/.nvmrc node_modules/ npm-debug.log diff --git a/.gitignore b/.gitignore index fcf59f8039..ec161d456d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ test/bak .urchin.log .urchin_stdout test/**/test_output +test/**/.nvmrc node_modules/ npm-debug.log diff --git a/nvm.sh b/nvm.sh old mode 100644 new mode 100755 index cd611cdf52..f95b95c2c5 --- a/nvm.sh +++ b/nvm.sh @@ -2911,6 +2911,23 @@ nvm_is_natural_num() { esac } +nvm_write_nvmrc() { + local VERSION_STRING + VERSION_STRING=$(nvm_version "${1-$VERSION_STRING}") + if [ "$VERSION_STRING" = '∞' ] || [ "$VERSION_STRING" = 'N/A' ]; then + return 1 + fi + echo "$VERSION_STRING" | tee "$PWD"/.nvmrc > /dev/null || { + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err "Warning: Unable to write version number ($VERSION_STRING) to .nvmrc" + fi + return 3 + } + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "Wrote version number ($VERSION_STRING) to .nvmrc" + fi +} + # Check version dir permissions nvm_check_file_permissions() { nvm_is_zsh && setopt local_options nonomatch @@ -3016,6 +3033,7 @@ nvm() { nvm_echo ' --no-progress Disable the progress bar on any downloads' nvm_echo ' --alias= After installing, set the alias specified to the version specified. (same as: nvm alias )' nvm_echo ' --default After installing, set default alias to the version specified. (same as: nvm alias default )' + nvm_echo ' --save After installing, write the specified version to .nvmrc' nvm_echo ' nvm uninstall Uninstall a version' nvm_echo ' nvm uninstall --lts Uninstall using automatic LTS (long-term support) alias `lts/*`, if available.' nvm_echo ' nvm uninstall --lts= Uninstall using automatic alias for provided LTS line, if available.' @@ -3024,6 +3042,7 @@ nvm() { nvm_echo ' --silent Silences stdout/stderr output' nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.' nvm_echo ' --lts= Uses automatic alias for provided LTS line, if available.' + nvm_echo ' --save Writes the specified version to .nvmrc.' nvm_echo ' nvm exec [] [] Run on . Uses .nvmrc if available and version is omitted.' nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm exec`:' nvm_echo ' --silent Silences stdout/stderr output' @@ -3236,6 +3255,8 @@ nvm() { local ALIAS local NVM_UPGRADE_NPM NVM_UPGRADE_NPM=0 + local NVM_WRITE_TO_NVMRC + NVM_WRITE_TO_NVMRC=0 local PROVIDED_REINSTALL_PACKAGES_FROM local REINSTALL_PACKAGES_FROM @@ -3334,6 +3355,10 @@ nvm() { SKIP_DEFAULT_PACKAGES=true shift ;; + --save | -w) + NVM_WRITE_TO_NVMRC=1 + shift + ;; *) break # stop parsing args ;; @@ -3570,6 +3595,7 @@ nvm() { else EXIT_CODE=$? fi + return $EXIT_CODE ;; "uninstall") @@ -3721,6 +3747,7 @@ nvm() { --) ;; --lts) NVM_LTS='*' ;; --lts=*) NVM_LTS="${1##--lts=}" ;; + --save | -w) NVM_WRITE_TO_NVMRC=1 ;; --*) ;; *) if [ -n "${1-}" ]; then @@ -3754,6 +3781,10 @@ nvm() { return 127 fi + if [ "${NVM_WRITE_TO_NVMRC:-0}" -eq 1 ]; then + nvm_write_nvmrc "$VERSION" + fi + if [ "_${VERSION}" = '_system' ]; then if nvm_has_system_node && nvm deactivate "${NVM_SILENT_ARG-}" >/dev/null 2>&1; then if [ "${NVM_SILENT:-0}" -ne 1 ]; then @@ -4379,6 +4410,7 @@ nvm() { nvm_echo_with_colors nvm_err_with_colors \ nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \ nvm_process_nvmrc nvm_nvmrc_invalid_msg \ + nvm_write_nvmrc \ >/dev/null 2>&1 unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \ NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS \ @@ -4515,7 +4547,7 @@ nvm_auto() { local NVM_CURRENT if [ "_${NVM_MODE}" = '_install' ]; then VERSION="$(nvm_alias default 2>/dev/null || nvm_echo)" - if [ -n "${VERSION}" ]; then + if [ -n "${VERSION}" ] && ! [ "_${VERSION}" = '_N/A' ] && nvm_is_valid_version "${VERSION}"; then nvm install "${VERSION}" >/dev/null elif nvm_rc_version >/dev/null 2>&1; then nvm install >/dev/null @@ -4524,7 +4556,7 @@ nvm_auto() { NVM_CURRENT="$(nvm_ls_current)" if [ "_${NVM_CURRENT}" = '_none' ] || [ "_${NVM_CURRENT}" = '_system' ]; then VERSION="$(nvm_resolve_local_alias default 2>/dev/null || nvm_echo)" - if [ -n "${VERSION}" ]; then + if [ -n "${VERSION}" ] && ! [ "_${VERSION}" = '_N/A' ] && nvm_is_valid_version "${VERSION}"; then nvm use --silent "${VERSION}" >/dev/null elif nvm_rc_version >/dev/null 2>&1; then nvm use --silent >/dev/null diff --git a/test/fast/Unit tests/Running 'nvm install --save' works as expected' b/test/fast/Unit tests/Running 'nvm install --save' works as expected' new file mode 100644 index 0000000000..7f6c565cee --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm install --save' works as expected' @@ -0,0 +1,43 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION="v0.2.4" + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +cleanup () { + nvm cache clear + nvm deactivate + nvm unalias default + rm -rf ${NVM_DIR}/v* .nvmrc + if [ -f .nvmrc.orig ]; then mv .nvmrc.orig .nvmrc; fi + unset -f nvm_ls_remote nvm_ls_remote_iojs +} + +die () { + echo "$@" + cleanup + exit 1 +} + +REMOTE="$PWD/mocks/nvm_ls_remote.txt" +nvm_ls_remote() { + cat "$REMOTE" +} +REMOTE_IOJS="$PWD/mocks/nvm_ls_remote_iojs.txt" +nvm_ls_remote_iojs() { + cat "$REMOTE_IOJS" +} + +make_fake_node "$TEST_VERSION" + +nvm install --save "$TEST_VERSION" || die "\`nvm install --save $TEST_VERSION\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm install --save $TEST_VERSION\`+ \`cat .nvmrc\` outputted invalid version: got '${OUTPUT}'" + +cleanup diff --git a/test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir b/test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir new file mode 100644 index 0000000000..ef8a25a91b --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir @@ -0,0 +1,57 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION="v0.2.4" + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi +if [ -f ../.nvmrc ]; then mv ../.nvmrc ../.nvmrc.orig; fi + +del_nvmrc () { + rm -f .nvmrc ../.nvmrc +} + +cleanup () { + del_nvmrc + nvm cache clear + nvm deactivate + nvm unalias default + rm -rf ${NVM_DIR}/v* + if [ -f .nvmrc.orig ]; then mv .nvmrc.orig .nvmrc; fi + if [ -f ../.nvmrc.orig ]; then mv ../.nvmrc.orig ../.nvmrc; fi + unset -f nvm_ls_remote nvm_ls_remote_iojs +} + +die () { + echo "$@" + cleanup + exit 1 +} + +REMOTE="$PWD/mocks/nvm_ls_remote.txt" +nvm_ls_remote() { + cat "$REMOTE" +} +REMOTE_IOJS="$PWD/mocks/nvm_ls_remote_iojs.txt" +nvm_ls_remote_iojs() { + cat "$REMOTE_IOJS" +} + +del_nvmrc +make_fake_node "$TEST_VERSION" + +(cd .. +nvm use --save "$TEST_VERSION" || die "\`nvm use --save $TEST_VERSION\` failed in the parent dir") +nvm use --save || die "\`nvm use --save\` failed" + +[ -f ../.nvmrc ] && [ -f .nvmrc ] || die "expected two .nvmrc files to be generated" + +OUTPUT=$(cat .nvmrc) +EXPECTED_OUTPUT="$(cat ../.nvmrc)" + +[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] \ + || die "invalid \`nvm use --save \` output: expected '$EXPECTED_OUTPUT'; got '$OUTPUT'" + +cleanup diff --git a/test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything b/test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything new file mode 100644 index 0000000000..0df4251422 --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything @@ -0,0 +1,43 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION="v0.2.4" + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +cleanup () { + nvm cache clear + nvm deactivate + nvm unalias default + rm -rf ${NVM_DIR}/v* .nvmrc + if [ -f .nvmrc.orig ]; then mv .nvmrc.orig .nvmrc; fi + unset -f nvm_ls_remote nvm_ls_remote_iojs +} + +die () { + echo "$@" + cleanup + exit 1 +} + +REMOTE="$PWD/mocks/nvm_ls_remote.txt" +nvm_ls_remote() { + cat "$REMOTE" +} +REMOTE_IOJS="$PWD/mocks/nvm_ls_remote_iojs.txt" +nvm_ls_remote_iojs() { + cat "$REMOTE_IOJS" +} + +make_fake_node "$TEST_VERSION" + +OUTPUT=$(nvm use --save --silent "$TEST_VERSION" || die "\`nvm use --save --silent $TEST_VERSION\` failed") +EXPECTED_OUTPUT="" + +[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] \ + || die "\`nvm use --save --silent $TEST_VERSION\` output was not silenced to '$EXPECTED_OUTPUT'; got '$OUTPUT'" + +cleanup diff --git a/test/fast/Unit tests/Running 'nvm use -w' works as expected' b/test/fast/Unit tests/Running 'nvm use -w' works as expected' new file mode 100644 index 0000000000..afa5835987 --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use -w' works as expected' @@ -0,0 +1,62 @@ +#!/bin/sh +\. ../../../nvm.sh + +set -e + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +TEST_VERSION="v0.2.4" + +cleanup () { + nvm cache clear + nvm deactivate + nvm unalias default + rm -rf ${NVM_DIR}/v* .nvmrc + if [ -f .nvmrc.orig ]; then mv .nvmrc.orig .nvmrc; fi + unset -f nvm_ls_remote nvm_ls_remote_iojs +} + +die () { + echo "$@" + cleanup + exit 1 +} + +nvm deactivate 2>/dev/null || die 'unable to deactivate' + +\. ../../common.sh + +REMOTE="$PWD/mocks/nvm_ls_remote.txt" +nvm_ls_remote() { + cat "$REMOTE" +} +REMOTE_IOJS="$PWD/mocks/nvm_ls_remote_iojs.txt" +nvm_ls_remote_iojs() { + cat "$REMOTE_IOJS" +} + +make_fake_node "$TEST_VERSION" + +# 1. install + +nvm install -w "$TEST_VERSION" || die "\`nvm install -w $TEST_VERSION\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm install -w $TEST_VERSION\`+ \`cat .nvmrc\` outputted invalid version: got '${OUTPUT}'" + +# + +unset OUTPUT + +# 2. use + +nvm use -w "$TEST_VERSION" || die "\`nvm use -w $TEST_VERSION\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm use -w $TEST_VERSION\`+ \`cat .nvmrc\` outputted invalid version: got '${OUTPUT}'" + +# + +cleanup diff --git a/test/fast/Unit tests/nvm_write_nvmrc b/test/fast/Unit tests/nvm_write_nvmrc new file mode 100644 index 0000000000..9e0d7343e8 --- /dev/null +++ b/test/fast/Unit tests/nvm_write_nvmrc @@ -0,0 +1,86 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION="v0.2.4" + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +del_nvmrc () { + rm -f .nvmrc +} + +del_alias () { + nvm unalias test >/dev/null 2>&1 +} + +cleanup () { + del_nvmrc + del_alias + nvm cache clear + nvm deactivate + nvm unalias default + rm -rf ${NVM_DIR}/v* + if [ -f .nvmrc.orig ]; then mv .nvmrc.orig .nvmrc; fi + unset -f nvm_ls_remote nvm_ls_remote_iojs +} + +die () { + echo "$@" + cleanup + exit 1 +} + +REMOTE="$PWD/mocks/nvm_ls_remote.txt" +nvm_ls_remote() { + cat "$REMOTE" +} +REMOTE_IOJS="$PWD/mocks/nvm_ls_remote_iojs.txt" +nvm_ls_remote_iojs() { + cat "$REMOTE_IOJS" +} + +make_fake_node "$TEST_VERSION" + +test_version () { + del_nvmrc + VERSION_STRING=${1-} + make_fake_node "$VERSION_STRING" + + nvm_write_nvmrc $VERSION_STRING || die "\`nvm_write_nvmrc ${VERSION_STRING}\` failed" + OUTPUT="$(cat .nvmrc)" + + nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm install --save ${VERSION_STRING}\`+ \`cat .nvmrc\` outputted invalid version: got '${OUTPUT}'" +} + +# 1. + +test_version "$TEST_VERSION" || die + +# 2. with an alias +del_alias +nvm alias test "$TEST_VERSION" +test_version test || die + +# 3. fails with invalid permissions +del_nvmrc +touch .nvmrc +chmod 0 .nvmrc +nvm_write_nvmrc $TEST_VERSION 2>/dev/null && die "\`nvm_write_nvmrc $TEST_VERSION\` did not fail with invalid permissions" +del_nvmrc + +# 4. respects NVM_SILENT=1 +export NVM_SILENT=1 +[ "$(nvm_write_nvmrc $TEST_VERSION)" = "" ] || die "\`nvm_write_nvmrc $TEST_VERSION\` was not silenced by NVM_SILENT=1" +unset NVM_SILENT + +# 5. fails with an invalid version number +TEST_VERSION="not_a_node_version" +nvm_write_nvmrc $TEST_VERSION 2>/dev/null && die "\`nvm_write_nvmrc $TEST_VERSION\` did not fail" + +# + +cleanup