diff --git a/nvm.sh b/nvm.sh index fef2673a..dc9b5a53 100755 --- a/nvm.sh +++ b/nvm.sh @@ -2079,7 +2079,14 @@ nvm_ls() { v*) NVM_PATTERN_STARTS_WITH_V=true ;; *) NVM_PATTERN_STARTS_WITH_V=false ;; esac - if [ $NVM_PATTERN_STARTS_WITH_V = true ] && [ "_$(nvm_num_version_groups "${PATTERN}")" = "_3" ]; then + local NVM_PATTERN_IS_PRERELEASE + case "${PATTERN}" in + v*-*) NVM_PATTERN_IS_PRERELEASE=true ;; + *) NVM_PATTERN_IS_PRERELEASE=false ;; + esac + if [ $NVM_PATTERN_IS_PRERELEASE = true ] && nvm_is_version_installed "${PATTERN}"; then + VERSIONS="${PATTERN}" + elif [ $NVM_PATTERN_STARTS_WITH_V = true ] && [ $NVM_PATTERN_IS_PRERELEASE = false ] && [ "_$(nvm_num_version_groups "${PATTERN}")" = "_3" ]; then if nvm_is_version_installed "${PATTERN}"; then VERSIONS="${PATTERN}" elif nvm_is_version_installed "$(nvm_add_iojs_prefix "${PATTERN}")"; then @@ -2147,6 +2154,12 @@ nvm_ls() { else SEARCH_PATTERN="$(nvm_echo "${PATTERN}" | command sed 's/[[\.*^$#]/\\&/g')" fi + # a partial prerelease must end at a `.`, so `v24.0.0-rc.1` does not match `v24.0.0-rc.10` + local NVM_PRERELEASE_PATTERN + NVM_PRERELEASE_PATTERN='' + case "${PATTERN}" in + *-*) NVM_PRERELEASE_PATTERN="${PATTERN}" ;; + esac if [ -n "${NVM_DIRS_TO_SEARCH1}${NVM_DIRS_TO_SEARCH2}${NVM_DIRS_TO_SEARCH3}" ]; then VERSIONS="$(command find "${NVM_DIRS_TO_SEARCH1}"/* "${NVM_DIRS_TO_SEARCH2}"/* "${NVM_DIRS_TO_SEARCH3}"/* -name . -o -type d -prune -o -path "${PATTERN}*" \ | command sed -e " @@ -2163,6 +2176,14 @@ nvm_ls() { | command sed -e 's#\(.*\)\.\([^\.]\{1,\}\)$#\2-\1#;' \ -e "s#^${NVM_NODE_PREFIX}-##;" \ )" + if [ -n "${NVM_PRERELEASE_PATTERN}" ] && [ -n "${VERSIONS}" ]; then + VERSIONS="$(nvm_echo "${VERSIONS}" | command awk -v pattern="${NVM_PRERELEASE_PATTERN}" '{ + position = index($0, pattern); + if (!position) { next } + rest = substr($0, position + length(pattern)); + if (rest == "" || substr(rest, 1, 1) == ".") { print } + }')" + fi fi fi diff --git a/test/fast/Unit tests/nvm_ls matches a prerelease only at a dot b/test/fast/Unit tests/nvm_ls matches a prerelease only at a dot new file mode 100755 index 00000000..52f1f685 --- /dev/null +++ b/test/fast/Unit tests/nvm_ls matches a prerelease only at a dot @@ -0,0 +1,41 @@ +#!/bin/sh + +ORIG_NVM_DIR="${NVM_DIR}" +TMP_DIR='' + +cleanup () { + case "${TMP_DIR}" in + /*) rm -rf "${TMP_DIR}" ;; + esac + NVM_DIR="${ORIG_NVM_DIR}" + export NVM_DIR +} + +die () { echo "$@" ; cleanup ; exit 1; } + +: nvm.sh +\. ../../../nvm.sh + +\. ../../common.sh + +TMP_DIR="$(mktemp -d)" +NVM_DIR="${TMP_DIR}/nvm" +export NVM_DIR + +for VERSION in v24.0.0-rc.10 v24.0.0-rc.2 v24.0.0-rc.1; do + mkdir -p "${NVM_DIR}/versions/node/${VERSION}/bin" || die "fake node ${VERSION} could not be made" + make_echo "${NVM_DIR}/versions/node/${VERSION}/bin/node" "${VERSION}" +done + +for PATTERN in v24.0.0-rc.1 24.0.0-rc.1; do + OUTPUT="$(nvm_ls "${PATTERN}" | tr '\n' ' ')" + [ "_${OUTPUT}" = '_v24.0.0-rc.1 ' ] || die "nvm_ls ${PATTERN} should not match v24.0.0-rc.10; got >${OUTPUT}<" + [ "_$(nvm_version "${PATTERN}")" = '_v24.0.0-rc.1' ] || die "nvm_version ${PATTERN} should be v24.0.0-rc.1; got >$(nvm_version "${PATTERN}")<" +done + +OUTPUT="$(nvm_ls v24.0.0-rc | tr '\n' ' ')" +[ "_${OUTPUT}" = '_v24.0.0-rc.1 v24.0.0-rc.2 v24.0.0-rc.10 ' ] || die "nvm_ls v24.0.0-rc should match every rc; got >${OUTPUT}<" + +[ "_$(nvm_ls v24.0.0-rc.3)" = '_N/A' ] || die "nvm_ls v24.0.0-rc.3 should be N/A; got >$(nvm_ls v24.0.0-rc.3)<" + +cleanup