[New] allow .nvmrc files to support comments

In theory, `npx nvmrc` can now be used to validate an `.nvmrc` file that `nvm` will support. Allowances have been made for future extensibility, and aliases may no longer contain a `#`.

Fixes #3336. Closes #2288.

Co-authored-by: Jordan Harband <ljharb@gmail.com>
Co-authored-by: Yash Singh <saiansh2525@gmail.com>
This commit is contained in:
Jordan Harband
2024-06-07 10:13:00 -07:00
parent 95081f0bc2
commit 29dce5edfd
8 changed files with 278 additions and 3 deletions

View File

@@ -101,3 +101,105 @@ watch() {
kill %2;
return $EXIT_CODE
}
parse_json() {
local json
json="$1"
local key
key=""
local value
value=""
local output
output=""
local in_key
in_key=0
local in_value
in_value=0
local in_string
in_string=0
local escaped
escaped=0
local buffer
buffer=""
local char
local len
len=${#json}
local arr_index
arr_index=0
local in_array
in_array=0
for ((i = 0; i < len; i++)); do
char="${json:i:1}"
if [ "$in_string" -eq 1 ]; then
if [ "$escaped" -eq 1 ]; then
buffer="$buffer$char"
escaped=0
elif [ "$char" = "\\" ]; then
escaped=1
elif [ "$char" = "\"" ]; then
in_string=0
if [ "$in_key" -eq 1 ]; then
key="$buffer"
buffer=""
in_key=0
elif [ "$in_value" -eq 1 ]; then
value="$buffer"
buffer=""
output="$output$key=\"$value\"\n"
in_value=0
elif [ "$in_array" -eq 1 ]; then
value="$buffer"
buffer=""
output="$output$arr_index=\"$value\"\n"
arr_index=$((arr_index + 1))
fi
else
buffer="$buffer$char"
fi
continue
fi
case "$char" in
"\"")
in_string=1
buffer=""
if [ "$in_value" -eq 0 ] && [ "$in_array" -eq 0 ]; then
in_key=1
fi
;;
":")
in_value=1
;;
",")
if [ "$in_value" -eq 1 ]; then
in_value=0
fi
;;
"[")
in_array=1
;;
"]")
in_array=0
;;
"{" | "}")
;;
*)
if [ "$in_value" -eq 1 ] && [ "$char" != " " ] && [ "$char" != "\n" ] && [ "$char" != "\t" ]; then
buffer="$buffer$char"
fi
;;
esac
done
printf "%b" "$output"
}
extract_value() {
local key
key="$1"
local parsed
parsed="$2"
echo "$parsed" | grep "^$key=" | cut -d'=' -f2 | tr -d '"'
}

View File

@@ -0,0 +1,26 @@
#!/bin/sh
\. ../../../nvm.sh
die () { echo "$@" ; exit 1; }
OUTPUT="$(nvm alias foo#bar baz 2>&1)"
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
EXIT_CODE="$(nvm alias foo#bar baz >/dev/null 2>&1 ; echo $?)"
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias with a hash should fail with code 1, got '$EXIT_CODE'"
OUTPUT="$(nvm alias foo# baz 2>&1)"
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias ending with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
EXIT_CODE="$(nvm alias foo# baz >/dev/null 2>&1 ; echo $?)"
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias ending with a hash should fail with code 1, got '$EXIT_CODE'"
OUTPUT="$(nvm alias \#bar baz 2>&1)"
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias starting with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
EXIT_CODE="$(nvm alias \#bar baz >/dev/null 2>&1 ; echo $?)"
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias starting with a hash should fail with code 1, got '$EXIT_CODE'"

View File

@@ -0,0 +1,34 @@
#!/bin/sh
die () { echo "$@" ; cleanup ; exit 1; }
cleanup() {
echo 'cleaned up'
}
\. ../../../nvm.sh
\. ../../common.sh
for f in ../../../test/fixtures/nvmrc/test/fixtures/valid/*; do
STDOUT="$(nvm_process_nvmrc $f/.nvmrc 2>/dev/null)"
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
EXPECTED="$(extract_value node "$(parse_json "$(cat "$f/expected.json")")")"
[ "${EXIT_CODE}" = "0" ] || die "$(basename "${f}"): expected exit code of 0 but got ${EXIT_CODE}"
[ "${STDOUT}" = "${EXPECTED}" ] || die "$(basename "${f}"): expected STDOUT of \`${EXPECTED}\` but got \`${STDOUT}\`"
done
for f in ../../../test/fixtures/nvmrc/test/fixtures/invalid/*; do
STDOUT="$(nvm_process_nvmrc $f/.nvmrc 2>/dev/null)"
STDERR="$(nvm_process_nvmrc $f/.nvmrc 2>&1 >/dev/null | awk '{if(NR > 8) print $0}' | strip_colors)"
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
EXPECTED="$(parse_json "$(cat "$f/expected.json")" | sed 's/^[0-9]*="//;s/"$//')"
[ "${EXIT_CODE}" != "0" ] || die "$(basename "${f}"): expected exit code of 'not 0' but got ${EXIT_CODE}"
[ "${STDERR}" = "${EXPECTED}" ] || die "$(basename "${f}"): expected STDERR of \`${EXPECTED}\` but got \`${STDERR}\`"
done

1
test/fixtures/nvmrc vendored Submodule

Submodule test/fixtures/nvmrc added at 0d325aa903