mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-09-16 00:00:06 +08:00
[Fix] zsh: restore nomatch and markdirs rather than clobbering them
`unsetopt local_options nomatch` unsets both named options, so LOCAL_OPTIONS is off by the time the function returns and the `nomatch` change escapes into the caller's shell: one `nvm ls` or `nvm alias` leaves NO_MATCH off for the rest of the session, after which an unmatched glob is silently passed through as a literal. `setopt local_options nonomatch`, already used in `nvm_check_file_permissions`, restores on return. The `markdirs` line also cancelled the snapshot taken for `shwordsplit` on the line above it; that one is latent, as `nvm_ls` is only ever called inside a command substitution.
This commit is contained in:
@@ -1389,7 +1389,7 @@ nvm_list_aliases() {
|
|||||||
NVM_HAS_COLORS=1
|
NVM_HAS_COLORS=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
nvm_is_zsh && unsetopt local_options nomatch
|
nvm_is_zsh && setopt local_options nonomatch
|
||||||
(
|
(
|
||||||
local ALIAS_PATH
|
local ALIAS_PATH
|
||||||
for ALIAS_PATH in "${NVM_ALIAS_DIR}/${ALIAS}"*; do
|
for ALIAS_PATH in "${NVM_ALIAS_DIR}/${ALIAS}"*; do
|
||||||
@@ -1685,7 +1685,7 @@ nvm_ls() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
nvm_is_zsh && setopt local_options shwordsplit
|
nvm_is_zsh && setopt local_options shwordsplit
|
||||||
nvm_is_zsh && unsetopt local_options markdirs
|
nvm_is_zsh && setopt local_options nomarkdirs
|
||||||
|
|
||||||
local NVM_DIRS_TO_SEARCH1
|
local NVM_DIRS_TO_SEARCH1
|
||||||
NVM_DIRS_TO_SEARCH1=''
|
NVM_DIRS_TO_SEARCH1=''
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
rm -rf "${TEST_DIR-}"
|
||||||
|
unset TEST_DIR NVM_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
\. ../../common.sh
|
||||||
|
|
||||||
|
# `local_options` is zsh-only, so no other shell can regress this
|
||||||
|
[ -n "${ZSH_VERSION-}" ] || exit 0
|
||||||
|
|
||||||
|
# an isolated NVM_DIR with a single known version, so that ambient versions
|
||||||
|
# and aliases can not affect any assertions. `alias/lts` is deliberately absent:
|
||||||
|
# globbing it is why `nvm_list_aliases` has to suppress `nomatch` at all.
|
||||||
|
TEST_DIR="${PWD}/nvm_zsh_options_tmp"
|
||||||
|
mkdir -p "${TEST_DIR}/alias" "${TEST_DIR}/versions/node/v24.13.0/bin" || die 'failed to create test dirs'
|
||||||
|
make_echo "${TEST_DIR}/versions/node/v24.13.0/bin/node" 'v24.13.0' || die 'failed to create test node binary'
|
||||||
|
echo '24' > "${TEST_DIR}/alias/default" || die 'failed to create default alias'
|
||||||
|
NVM_DIR="${TEST_DIR}"
|
||||||
|
|
||||||
|
setopt nomatch
|
||||||
|
unsetopt markdirs
|
||||||
|
unsetopt shwordsplit
|
||||||
|
|
||||||
|
nvm_list_aliases >/dev/null 2>&1
|
||||||
|
[[ -o nomatch ]] || die 'nvm_list_aliases left nomatch unset'
|
||||||
|
|
||||||
|
nvm alias >/dev/null 2>&1
|
||||||
|
[[ -o nomatch ]] || die '"nvm alias" left nomatch unset'
|
||||||
|
|
||||||
|
nvm ls >/dev/null 2>&1
|
||||||
|
[[ -o nomatch ]] || die '"nvm ls" left nomatch unset'
|
||||||
|
|
||||||
|
# called directly rather than in a command substitution, so that anything
|
||||||
|
# `nvm_ls` fails to restore is visible here
|
||||||
|
nvm_ls 24 >/dev/null 2>&1
|
||||||
|
[[ -o markdirs ]] && die 'nvm_ls left markdirs set'
|
||||||
|
[[ -o shwordsplit ]] && die 'nvm_ls left shwordsplit set'
|
||||||
|
|
||||||
|
# and the inverse: a caller that wants these on has to get them back
|
||||||
|
setopt markdirs
|
||||||
|
setopt shwordsplit
|
||||||
|
|
||||||
|
nvm_ls 24 >/dev/null 2>&1
|
||||||
|
[[ -o markdirs ]] || die 'nvm_ls left markdirs unset'
|
||||||
|
[[ -o shwordsplit ]] || die 'nvm_ls left shwordsplit unset'
|
||||||
|
|
||||||
|
cleanup
|
||||||
Reference in New Issue
Block a user