[patch] show system Node.js version in nvm ls

Normalize `nvm_version` output when `nvm_ls` returns "system vX" so alias and .nvmrc resolutions treat system correctly.

Add fast tests for system alias behavior in `nvm ls`, `nvm use`, and `nvm which`.
This commit is contained in:
Peter Dave Hello
2026-01-25 18:19:50 +08:00
committed by Jordan Harband
parent b1dd81097f
commit 29a652f90f
8 changed files with 189 additions and 4 deletions

35
nvm.sh
View File

@@ -758,6 +758,11 @@ nvm_version() {
;;
esac
VERSION="$(nvm_ls "${PATTERN}" | command tail -1)"
case "${VERSION}" in
system[[:blank:]]*)
VERSION='system'
;;
esac
if [ -z "${VERSION}" ] || [ "_${VERSION}" = "_N/A" ]; then
nvm_echo "N/A"
return 3
@@ -1462,6 +1467,18 @@ nvm_ls() {
PATTERN="${PATTERN}-"
;;
*)
local ALIAS_TARGET
ALIAS_TARGET="$(nvm_resolve_alias "${PATTERN}" 2>/dev/null || nvm_echo)"
if [ "_${ALIAS_TARGET}" = '_system' ] && (nvm_has_system_iojs || nvm_has_system_node); then
local SYSTEM_VERSION
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
if [ -n "${SYSTEM_VERSION}" ]; then
nvm_echo "system ${SYSTEM_VERSION}"
else
nvm_echo "system"
fi
return
fi
if nvm_resolve_local_alias "${PATTERN}"; then
return
fi
@@ -1565,13 +1582,24 @@ nvm_ls() {
fi
if [ "${NVM_ADD_SYSTEM-}" = true ]; then
local SYSTEM_VERSION
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
case "${PATTERN}" in
'' | v)
VERSIONS="${VERSIONS}
if [ -n "${SYSTEM_VERSION}" ]; then
VERSIONS="${VERSIONS}
system ${SYSTEM_VERSION}"
else
VERSIONS="${VERSIONS}
system"
fi
;;
system)
VERSIONS="system"
if [ -n "${SYSTEM_VERSION}" ]; then
VERSIONS="system ${SYSTEM_VERSION}"
else
VERSIONS="system"
fi
;;
esac
fi
@@ -1913,6 +1941,7 @@ BEGIN {
fmt_latest_lts = has_colors && latest_lts_color ? ("\033[" latest_lts_color " (Latest LTS: %s)\033[0m") : " (Latest LTS: %s)";
fmt_old_lts = has_colors && old_lts_color ? ("\033[" old_lts_color " (LTS: %s)\033[0m") : " (LTS: %s)";
fmt_system_target = has_colors && system_color ? (" (\033[" system_color "-> %s\033[0m)") : " (-> %s)";
split(remote_versions, lines, "|");
split(installed_versions, installed, "|");
@@ -1944,6 +1973,8 @@ BEGIN {
if (cols == 1) {
formatted = sprintf(fmt_version, version);
} else if (version == "system" && cols >= 2) {
formatted = sprintf((fmt_version fmt_system_target), version, fields[2]);
} else if (cols == 2) {
formatted = sprintf((fmt_version padding fmt_old_lts), version, fields[2]);
} else if (cols == 3 && fields[3] == "*") {

View File

@@ -0,0 +1,36 @@
#!/bin/sh
set -ex
die () { echo "$@" ; cleanup ; exit 1; }
cleanup() {
rm -f "$(nvm_alias_path)/default"
if [ -n "${SYSTEM_DIR-}" ]; then
rm -rf "${SYSTEM_DIR}"
fi
if [ -n "${ORIG_PATH-}" ]; then
PATH="${ORIG_PATH}"
fi
}
\. ../../../nvm.sh
nvm_make_alias default system
ORIG_PATH="${PATH}"
SYSTEM_DIR="$(mktemp -d)"
cat > "${SYSTEM_DIR}/node" <<'EOF'
#!/bin/sh
echo v0.0.0
EOF
chmod +x "${SYSTEM_DIR}/node"
PATH="${SYSTEM_DIR}:${PATH}"
export PATH
EXPECTED_OUTPUT="$(command which node)"
set +ex # since stderr is needed
OUTPUT="$(nvm which default 2>&1)"
set -ex
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "Could not use system via alias for nvm which. Got >${OUTPUT}<, expected >${EXPECTED_OUTPUT}<"
cleanup

View File

@@ -0,0 +1,22 @@
#!/bin/sh
die () { echo "$@" ; cleanup ; exit 1; }
cleanup () {
rm -f "$(nvm_alias_path)/default"
unset -f nvm_has_system_node node
}
\. ../../../nvm.sh
\. ../../common.sh
nvm_make_alias default system
nvm_has_system_node() { return 0; }
node() { command printf 'v0.0.0'; }
OUTPUT="$(nvm ls default | strip_colors)"
echo "${OUTPUT}" | command grep -q 'system' \
|| die "Could not list system via alias. Got >${OUTPUT}<"
echo "${OUTPUT}" | command grep -q 'v0.0.0' \
|| die "Could not list system version via alias. Got >${OUTPUT}<"
cleanup

View File

@@ -39,7 +39,13 @@ iojs-v0.10.2
v0.12.9
v0.12.87"
if nvm_has_system_node || nvm_has_system_iojs; then
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
if [ -n "${SYSTEM_VERSION}" ]; then
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
system ${SYSTEM_VERSION}"
else
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
system"
fi
fi
[ "${OUTPUT-}" = "${EXPECTED_OUTPUT-}" ] || die "expected >${EXPECTED_OUTPUT}<; got >${OUTPUT}<"

View File

@@ -37,7 +37,13 @@ iojs-v0.10.2
v0.12.9
v0.12.87"
if nvm_has_system_node || nvm_has_system_iojs; then
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
if [ -n "${SYSTEM_VERSION}" ]; then
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
system ${SYSTEM_VERSION}"
else
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
system"
fi
fi
[ "${OUTPUT-}" = "${EXPECTED_OUTPUT-}" ] || die "expected >${EXPECTED_OUTPUT}<; got >${OUTPUT}<"

View File

@@ -0,0 +1,38 @@
#!/bin/sh
set -ex
die () { echo "$@" ; cleanup ; exit 1; }
cleanup () {
rm -f "$(nvm_alias_path)/default"
if [ -n "${SYSTEM_DIR-}" ]; then
rm -rf "${SYSTEM_DIR}"
fi
if [ -n "${ORIG_PATH-}" ]; then
PATH="${ORIG_PATH}"
fi
unset -f nvm_print_npm_version
}
\. ../../nvm.sh
nvm_make_alias default system
ORIG_PATH="${PATH}"
SYSTEM_VERSION="v0.0.0"
SYSTEM_DIR="$(mktemp -d)"
cat > "${SYSTEM_DIR}/node" <<EOF
#!/bin/sh
command printf '%s\n' "${SYSTEM_VERSION}"
EOF
chmod +x "${SYSTEM_DIR}/node"
PATH="${SYSTEM_DIR}:${PATH}"
nvm_print_npm_version() { command printf ' (npm v1.2.3)'; }
EXPECTED_OUTPUT="Now using system version of node: ${SYSTEM_VERSION}$(nvm_print_npm_version)"
set +ex # since stderr is needed
OUTPUT="$(nvm use default 2>&1)"
set -ex
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "Could not use system via alias. Got >${OUTPUT}<, expected >${EXPECTED_OUTPUT}<"
cleanup

View File

@@ -0,0 +1,43 @@
#!/bin/sh
set -ex
die () { echo "$@" ; cleanup ; exit 1; }
cleanup () {
rm -f .nvmrc
if [ -f .nvmrc.orig ]; then
mv .nvmrc.orig .nvmrc
fi
if [ -n "${SYSTEM_DIR-}" ]; then
rm -rf "${SYSTEM_DIR}"
fi
if [ -n "${ORIG_PATH-}" ]; then
PATH="${ORIG_PATH}"
fi
unset -f nvm_print_npm_version
}
\. ../../nvm.sh
if [ -f .nvmrc ]; then mv .nvmrc .nvmrc.orig; fi
printf 'system\n' > .nvmrc
ORIG_PATH="${PATH}"
SYSTEM_VERSION="v0.0.0"
SYSTEM_DIR="$(mktemp -d)"
cat > "${SYSTEM_DIR}/node" <<EOF
#!/bin/sh
command printf '%s\n' "${SYSTEM_VERSION}"
EOF
chmod +x "${SYSTEM_DIR}/node"
PATH="${SYSTEM_DIR}:${PATH}"
nvm_print_npm_version() { command printf ' (npm v1.2.3)'; }
NVMRC_PATH="${PWD}/.nvmrc"
EXPECTED_OUTPUT="Found '${NVMRC_PATH}' with version <system>
Now using system version of node: ${SYSTEM_VERSION}$(nvm_print_npm_version)"
set +ex # since stderr is needed
OUTPUT="$(nvm use 2>&1)"
set -ex
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "Could not use system via .nvmrc. Got >${OUTPUT}<, expected >${EXPECTED_OUTPUT}<"
cleanup

View File

@@ -34,6 +34,9 @@ nvm_ls() {
[ "_$(nvm_version node)" = "_pattern: stable" ] || die '"nvm_version node" did not pass "stable" to "nvm_ls"'
[ "_$(nvm_version node-)" = "_pattern: stable" ] || die '"nvm_version node-" did not pass "stable" to "nvm_ls"'
nvm_ls() { echo "system v20.0.0"; }
[ "_$(nvm_version system)" = "_system" ] || die '"nvm_version system" did not return "system" when "nvm_ls" returns extra columns'
nvm_ls() { echo "N/A"; }
OUTPUT="$(nvm_version foo)"
EXPECTED_OUTPUT="N/A"