From 7a2040aac38b53fe4f1fa95b27670a0c16adb5f3 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 ++++++++- ...m install --save --lts' works as expected' | 38 +++++++++ ...ave' works with a .nvmrc in the parent dir | 54 +++++++++++++ ...e --silent --save' doesn't output anything | 41 ++++++++++ .../Running 'nvm use -w' works as expected' | 56 +++++++++++++ test/fast/Unit tests/nvm_write_nvmrc | 81 +++++++++++++++++++ 8 files changed, 306 insertions(+), 2 deletions(-) mode change 100644 => 100755 nvm.sh create mode 100755 test/fast/Unit tests/Running 'nvm install --save --lts' works as expected' create mode 100755 test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir create mode 100755 test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything create mode 100755 test/fast/Unit tests/Running 'nvm use -w' works as expected' create mode 100755 test/fast/Unit tests/nvm_write_nvmrc diff --git a/.dockerignore b/.dockerignore index fc578ccc81b..52e54284986 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 fcf59f80393..ec161d456d8 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 2e4378f2d25..400c9e4113c --- a/nvm.sh +++ b/nvm.sh @@ -2807,6 +2807,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 @@ -2912,6 +2929,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.' @@ -2920,6 +2938,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' @@ -3132,6 +3151,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 @@ -3230,6 +3251,10 @@ nvm() { SKIP_DEFAULT_PACKAGES=true shift ;; + --save | -w) + NVM_WRITE_TO_NVMRC=1 + shift + ;; *) break # stop parsing args ;; @@ -3466,6 +3491,7 @@ nvm() { else EXIT_CODE=$? fi + return $EXIT_CODE ;; "uninstall") @@ -3617,6 +3643,7 @@ nvm() { --) ;; --lts) NVM_LTS='*' ;; --lts=*) NVM_LTS="${1##--lts=}" ;; + --save | -w) NVM_WRITE_TO_NVMRC=1 ;; --*) ;; *) if [ -n "${1-}" ]; then @@ -3650,6 +3677,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 @@ -4271,6 +4302,7 @@ nvm() { nvm_get_colors nvm_set_colors nvm_print_color_code nvm_wrap_with_color_code nvm_format_help_message_colors \ nvm_echo_with_colors nvm_err_with_colors \ nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \ + 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 \ @@ -4407,7 +4439,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 @@ -4416,7 +4448,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 --lts' works as expected' b/test/fast/Unit tests/Running 'nvm install --save --lts' works as expected' new file mode 100755 index 00000000000..059eba6941d --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm install --save --lts' works as expected' @@ -0,0 +1,38 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +cleanup () { + rm -f .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 "lts/*" + +nvm install --save --lts || die "\`nvm install --save --lts\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm install --save --lts\`+ \`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 100755 index 00000000000..3d03f39a6b4 --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use --save' works with a .nvmrc in the parent dir @@ -0,0 +1,54 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION=$(nvm_version node) +echo "Using test version '$TEST_VERSION'" + +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 + 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 100755 index 00000000000..507ce2cd015 --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use --silent --save' doesn't output anything @@ -0,0 +1,41 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +TEST_VERSION=$(nvm_version node) +echo "Using test version '$TEST_VERSION'" + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +cleanup () { + rm -f .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 100755 index 00000000000..df514289194 --- /dev/null +++ b/test/fast/Unit tests/Running 'nvm use -w' works as expected' @@ -0,0 +1,56 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi + +cleanup () { + rm -f .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" +} + +TEST_VERSION="v0.9.4" +make_fake_node "$TEST_VERSION" + +# 1. install + +nvm install -w "$TEST_VERSION" || die "\`nvm install -w --lts\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm install -w --lts\`+ \`cat .nvmrc\` outputted invalid version: got '${OUTPUT}'" + +# + +cleanup +unset OUTPUT + +# 2. use + +nvm use -w "$TEST_VERSION" || die "\`nvm use -w --lts\` failed" +OUTPUT="$(cat .nvmrc)" + +nvm_is_valid_version "$(cat .nvmrc)" \ + || die "\`nvm use -w --lts\`+ \`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 100755 index 00000000000..8841f16707d --- /dev/null +++ b/test/fast/Unit tests/nvm_write_nvmrc @@ -0,0 +1,81 @@ +#!/bin/sh +\. ../../../nvm.sh +\. ../../common.sh + +set -e + +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 + 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" +} + +TEST_VERSION="v12.22.12" +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