[Fix] nvm_get_default_packages: ignore CRLF line endings

A `default-packages` file saved with Windows line endings left a carriage return on every package name,
and turned each blank line into a lone `\r` entry, so `npm install -g` was given `rimraf\r` and failed.
Strip a trailing `\r` from each line before parsing it,
like `.nvmrc` parsing already tolerates.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Wei-Lun Li <b84330808@gmail.com>
This commit is contained in:
Wei-Lun Li authored and Jordan Harband committed 2026-11-02 01:47:37 +09:00
1 parent edde7ce995
commit 84b176d46d
3 files changed
+21

No files matched your search

+1
View File
@@ -6600,6 +6600,7 @@ nvm_get_default_packages() {
NVM_DEFAULT_PACKAGE_FILE="${NVM_DIR}/default-packages"
if [ -f "${NVM_DEFAULT_PACKAGE_FILE}" ]; then
command awk '
{ sub(/\r$/, "") } # Strip CRLF line endings
/^[ \t]*#/ { next } # Skip lines that begin with #
/^[ \t]*$/ { next } # Skip empty lines
/[ \t]/ && !/^[ \t]*#/ {
@@ -93,3 +93,13 @@ EXPECTED_PKGS=''
touch "${FILE}"
cleanup
setup
printf 'rimraf\r\nobject-inspect@1.0.2\r\n\r\n# commented-package\r\n\r\nstevemao/left-pad\r\n' > "${FILE}"
DEFAULT_PKGS="$(nvm_get_default_packages)"
EXPECTED_PKGS='rimraf object-inspect@1.0.2 stevemao/left-pad'
[ "${DEFAULT_PKGS}" = "${EXPECTED_PKGS}" ] || die "6: expected default packages from a CRLF file >${EXPECTED_PKGS}<; got >${DEFAULT_PKGS}<"
cleanup
@@ -11,6 +11,7 @@ die () { echo "$@" ; cleanup ; exit 1; }
# The awk command from nvm_get_default_packages
AWK_SCRIPT='
{ sub(/\r$/, "") }
/^[ \t]*#/ { next }
/^[ \t]*$/ { next }
/[ \t]/ && !/^[ \t]*#/ {
@@ -33,14 +34,21 @@ stevemao/left-pad"
EXPECTED_OUTPUT="rimraf object-inspect@1.0.2 stevemao/left-pad"
# The same input, with CRLF line endings
CRLF_INPUT='rimraf\r\nobject-inspect@1.0.2\r\n\r\n# commented-package\r\n\r\nstevemao/left-pad\r\n'
# Test with system awk
OUTPUT="$(printf '%s\n' "${TEST_INPUT}" | awk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "system awk: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
OUTPUT="$(printf %b "${CRLF_INPUT}" | awk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "system awk, CRLF: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
# Test with mawk explicitly if available
if command -v mawk > /dev/null 2>&1; then
OUTPUT="$(printf '%s\n' "${TEST_INPUT}" | mawk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "mawk: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
OUTPUT="$(printf %b "${CRLF_INPUT}" | mawk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "mawk, CRLF: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
echo "mawk test passed"
else
echo "mawk not available, skipping mawk-specific test"
@@ -50,6 +58,8 @@ fi
if command -v gawk > /dev/null 2>&1; then
OUTPUT="$(printf '%s\n' "${TEST_INPUT}" | gawk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "gawk: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
OUTPUT="$(printf %b "${CRLF_INPUT}" | gawk "${AWK_SCRIPT}")"
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "gawk, CRLF: expected >${EXPECTED_OUTPUT}<, got >${OUTPUT}<"
echo "gawk test passed"
else
echo "gawk not available, skipping gawk-specific test"