mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-07-18 12:58:21 +08:00
[Fix] use command to bypass curl/wget shell functions and aliases
zsh (and interactive bash with `expand_aliases`) bakes a preexisting `curl` alias into nvm's function bodies at source time, and shell functions named `curl`/`wget` shadow the binaries at call time - either one breaks downloads. Prefixing invocations with `command` bypasses both: here, `nvm_download`'s dispatch, `nvm_curl_version`, `nvm_curl_libz_support`, and the wget branch of `nvm_get_latest`; the remaining bare `curl` invocations in `nvm_get_latest` and the install script are prefixed in a followup commit. The tests that previously mocked curl/wget as shell functions now install fake executables on PATH instead, via a shared `make_fake_curl` helper in `test/common.sh`, and a new test asserts the bypass. Refs #2923
This commit is contained in:
+1
-1
@@ -119,7 +119,7 @@ nvm_download() {
|
|||||||
-e 's/-o /-O /' \
|
-e 's/-o /-O /' \
|
||||||
-e 's/-C - /-c /')
|
-e 's/-C - /-c /')
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
eval wget $ARGS
|
eval command wget $ARGS
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ nvm_has_colors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nvm_curl_libz_support() {
|
nvm_curl_libz_support() {
|
||||||
curl -V 2>/dev/null | nvm_grep "^Features:" | nvm_grep -q "libz"
|
command curl -V 2>/dev/null | nvm_grep "^Features:" | nvm_grep -q "libz"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_curl_use_compression() {
|
nvm_curl_use_compression() {
|
||||||
@@ -103,7 +103,7 @@ nvm_get_latest() {
|
|||||||
fi
|
fi
|
||||||
NVM_LATEST_URL="$(curl ${CURL_COMPRESSED_FLAG:-} -q -w "%{url_effective}\\n" -L -s -S https://latest.nvm.sh -o /dev/null)"
|
NVM_LATEST_URL="$(curl ${CURL_COMPRESSED_FLAG:-} -q -w "%{url_effective}\\n" -L -s -S https://latest.nvm.sh -o /dev/null)"
|
||||||
elif nvm_has "wget"; then
|
elif nvm_has "wget"; then
|
||||||
NVM_LATEST_URL="$(wget -q https://latest.nvm.sh --server-response -O /dev/null 2>&1 | command awk '/^ Location: /{DEST=$2} END{ print DEST }')"
|
NVM_LATEST_URL="$(command wget -q https://latest.nvm.sh --server-response -O /dev/null 2>&1 | command awk '/^ Location: /{DEST=$2} END{ print DEST }')"
|
||||||
else
|
else
|
||||||
nvm_err 'nvm needs curl or wget to proceed.'
|
nvm_err 'nvm needs curl or wget to proceed.'
|
||||||
return 1
|
return 1
|
||||||
@@ -170,7 +170,7 @@ nvm_download() {
|
|||||||
set -- "$@" --header "Authorization: ${sanitized_header}"
|
set -- "$@" --header "Authorization: ${sanitized_header}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
"${NVM_DOWNLOADER}" "$@"
|
command "${NVM_DOWNLOADER}" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_sanitize_auth_header() {
|
nvm_sanitize_auth_header() {
|
||||||
@@ -649,7 +649,7 @@ nvm_clang_version() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nvm_curl_version() {
|
nvm_curl_version() {
|
||||||
curl -V | command awk '{ if ($1 == "curl") print $2 }' | command sed 's/-.*$//g'
|
command curl -V | command awk '{ if ($1 == "curl") print $2 }' | command sed 's/-.*$//g'
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_version_greater() {
|
nvm_version_greater() {
|
||||||
|
|||||||
@@ -50,6 +50,39 @@ make_echo() {
|
|||||||
chmod a+x "$1"
|
chmod a+x "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# `command curl` bypasses shell functions and aliases, so tests that mock curl
|
||||||
|
# must provide an actual executable on the PATH: this creates one in the given
|
||||||
|
# directory. Invoked as `curl -V`, it prints ${VERSION_MESSAGE} (exported here
|
||||||
|
# on the mock's behalf); any other invocation runs the body given as the
|
||||||
|
# second argument, or fails.
|
||||||
|
make_fake_curl() {
|
||||||
|
local FAKE_BIN_DIR
|
||||||
|
FAKE_BIN_DIR="${1-}"
|
||||||
|
[ -n "${FAKE_BIN_DIR}" ] || return 1
|
||||||
|
|
||||||
|
local FAKE_CURL_BODY
|
||||||
|
FAKE_CURL_BODY="${2-}"
|
||||||
|
if [ -z "${FAKE_CURL_BODY}" ]; then
|
||||||
|
FAKE_CURL_BODY='echo >&2 "This fake curl only takes one parameter, -V"
|
||||||
|
exit 1'
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${FAKE_BIN_DIR}" || return 2
|
||||||
|
|
||||||
|
{
|
||||||
|
echo '#!/bin/sh'
|
||||||
|
echo 'if [ "$#" -eq 1 ] && [ "$1" = "-V" ]; then'
|
||||||
|
echo ' echo "${VERSION_MESSAGE}"'
|
||||||
|
echo ' exit 0'
|
||||||
|
echo 'fi'
|
||||||
|
printf '%s\n' "${FAKE_CURL_BODY}"
|
||||||
|
} > "${FAKE_BIN_DIR}/curl"
|
||||||
|
chmod +x "${FAKE_BIN_DIR}/curl"
|
||||||
|
|
||||||
|
# the fake curl reads VERSION_MESSAGE from the environment
|
||||||
|
export VERSION_MESSAGE
|
||||||
|
}
|
||||||
|
|
||||||
make_fake_node() {
|
make_fake_node() {
|
||||||
local VERSION
|
local VERSION
|
||||||
VERSION="${1-}"
|
VERSION="${1-}"
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="$PWD/nvm_curl_libz_support-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
unset -f curl
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
die() { cleanup; echo "$@" ; exit 1; }
|
die() { cleanup; echo "$@" ; exit 1; }
|
||||||
@@ -9,32 +13,28 @@ die() { cleanup; echo "$@" ; exit 1; }
|
|||||||
: nvm.sh
|
: nvm.sh
|
||||||
\. ../../../nvm.sh
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
curl() {
|
\. ../../common.sh
|
||||||
# curl with libz feature
|
|
||||||
if [ $# -ne 1 ] || [ "$1" != "-V" ]; then
|
OLDPATH="$PATH"
|
||||||
die "This fake curl only takes one parameter -V"
|
|
||||||
fi
|
make_fake_curl "$TEST_BIN"
|
||||||
echo "
|
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
|
# curl with libz feature
|
||||||
|
VERSION_MESSAGE="
|
||||||
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
|
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
|
||||||
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
||||||
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets"
|
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets"
|
||||||
}
|
|
||||||
|
|
||||||
nvm_curl_libz_support || die "nvm_curl_libz_support should return 0"
|
nvm_curl_libz_support || die "nvm_curl_libz_support should return 0"
|
||||||
|
|
||||||
unset -f curl
|
# curl without libz feature
|
||||||
|
VERSION_MESSAGE="
|
||||||
curl() {
|
|
||||||
# curl without libz feature
|
|
||||||
if [ "$#" -ne 1 ] || [ "$1" != "-V" ]; then
|
|
||||||
die "This fake curl only takes one parameter -V"
|
|
||||||
fi
|
|
||||||
echo "
|
|
||||||
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.32
|
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.32
|
||||||
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
||||||
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL TLS-SRP UnixSockets"
|
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL TLS-SRP UnixSockets"
|
||||||
}
|
|
||||||
|
|
||||||
! nvm_curl_libz_support || die "nvm_curl_libz_support should return 1"
|
! nvm_curl_libz_support || die "nvm_curl_libz_support should return 1"
|
||||||
|
|
||||||
unset -f curl
|
cleanup
|
||||||
|
|||||||
@@ -1,18 +1,25 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="$PWD/nvm_curl_use_compression-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
|
||||||
cleanup () {
|
cleanup () {
|
||||||
unset -f die
|
unset -f die
|
||||||
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
die () { echo -e "$@" ; cleanup ; exit 1; }
|
die () { echo -e "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
NVM_ENV=testing \. ../../../nvm.sh
|
NVM_ENV=testing \. ../../../nvm.sh
|
||||||
|
|
||||||
curl() {
|
\. ../../common.sh
|
||||||
if [ "$1" = "-V" ]; then
|
|
||||||
echo "${VERSION_MESSAGE}"
|
OLDPATH="$PATH"
|
||||||
fi
|
|
||||||
}
|
make_fake_curl "$TEST_BIN"
|
||||||
|
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
CURL_VERSION_ON_ARCHLINUX_WITH_LIBZ="curl 7.54.0 (x86_64-pc-linux-gnu) libcurl/7.54.0 OpenSSL/1.1.0f zlib/1.2.11 libpsl/0.17.0 (+libicu/59.1) libssh2/1.8.0 nghttp2/1.22.0
|
CURL_VERSION_ON_ARCHLINUX_WITH_LIBZ="curl 7.54.0 (x86_64-pc-linux-gnu) libcurl/7.54.0 OpenSSL/1.1.0f zlib/1.2.11 libpsl/0.17.0 (+libicu/59.1) libssh2/1.8.0 nghttp2/1.22.0
|
||||||
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
|
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="$PWD/nvm_curl_version-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
|
||||||
cleanup () {
|
cleanup () {
|
||||||
unset -f die
|
unset -f die cleanup assert_version_is
|
||||||
unset -f curl
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
die () { echo -e "$@" ; cleanup ; exit 1; }
|
die () { echo -e "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
NVM_ENV=testing \. ../../../nvm.sh
|
NVM_ENV=testing \. ../../../nvm.sh
|
||||||
|
|
||||||
curl() {
|
\. ../../common.sh
|
||||||
if [ "$1" = "-V" ]; then
|
|
||||||
echo "${VERSION_MESSAGE}"
|
OLDPATH="$PATH"
|
||||||
fi
|
|
||||||
}
|
make_fake_curl "$TEST_BIN"
|
||||||
|
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
assert_version_is() {
|
assert_version_is() {
|
||||||
if [ "${1}" != "${2}" ]; then
|
if [ "${1}" != "${2}" ]; then
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="$PWD/shadowed-curl-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
ARGV_LOG="$WORK/argv.log"
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
unset -f die cleanup curl wget
|
||||||
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
NVM_ENV=testing \. ../../../nvm.sh
|
||||||
|
|
||||||
|
\. ../../common.sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
|
||||||
|
# real-looking curl on PATH; calling the shadowing shell function below instead is a failure
|
||||||
|
make_fake_curl "$TEST_BIN" ': > "$ARGV_LOG"
|
||||||
|
for a in "$@"; do printf "%s\n" "$a" >> "$ARGV_LOG"; done'
|
||||||
|
|
||||||
|
VERSION_MESSAGE="curl 7.99.0 (fake)
|
||||||
|
Features: libz"
|
||||||
|
|
||||||
|
export ARGV_LOG
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
|
# shadowing shell functions, like aliases baked into a user's shell, must be
|
||||||
|
# bypassed in favor of the executables on PATH (https://github.com/nvm-sh/nvm/issues/2923)
|
||||||
|
curl() {
|
||||||
|
echo 'curl 0.0.0-shadowed'
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
wget() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$(nvm_curl_version)" = '7.99.0' ] || die "nvm_curl_version used the shadowing curl function; got $(nvm_curl_version)"
|
||||||
|
|
||||||
|
nvm_curl_libz_support || die 'nvm_curl_libz_support used the shadowing curl function'
|
||||||
|
|
||||||
|
nvm_download -s 'http://example.com/' -o /dev/null || die 'nvm_download used the shadowing curl function and failed'
|
||||||
|
grep -Fxq 'http://example.com/' "$ARGV_LOG" || die "nvm_download did not invoke the curl executable; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
cleanup
|
||||||
@@ -2,37 +2,45 @@
|
|||||||
|
|
||||||
die () { echo "$@" ; cleanup ; exit 1; }
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
WORK="$PWD/nvm_get_latest-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
unset -f curl wget nvm_has
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
\. ../../../nvm.sh
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
\. ../../common.sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
|
||||||
EXPECTED_VERSION="v12.3.456"
|
EXPECTED_VERSION="v12.3.456"
|
||||||
URL="https://github.com/nvm-sh/nvm/releases/tag/$EXPECTED_VERSION"
|
URL="https://github.com/nvm-sh/nvm/releases/tag/$EXPECTED_VERSION"
|
||||||
EXPECTED_CURL_ARGS="--compressed -q -w %{url_effective}\n -L -s -S https://latest.nvm.sh -o /dev/null"
|
EXPECTED_CURL_ARGS="--compressed -q -w %{url_effective}\n -L -s -S https://latest.nvm.sh -o /dev/null"
|
||||||
EXPECTED_WGET_ARGS="-q https://latest.nvm.sh --server-response -O /dev/null"
|
EXPECTED_WGET_ARGS="-q https://latest.nvm.sh --server-response -O /dev/null"
|
||||||
|
export URL EXPECTED_CURL_ARGS EXPECTED_WGET_ARGS
|
||||||
|
|
||||||
curl() {
|
VERSION_MESSAGE="
|
||||||
if [ $# -eq 1 ] && [ "$1" = "-V" ]; then
|
|
||||||
echo "
|
|
||||||
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
|
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
|
||||||
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
|
||||||
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets"
|
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets"
|
||||||
elif [ "_$*" != "_$EXPECTED_CURL_ARGS" ]; then
|
|
||||||
echo >&2 "expected args ($EXPECTED_CURL_ARGS), got ($*)"
|
# fake curl/wget: `command curl` bypasses shell functions, so the mocks must be executables on PATH
|
||||||
return 1
|
make_fake_curl "$TEST_BIN" 'if [ "_$*" != "_$EXPECTED_CURL_ARGS" ]; then
|
||||||
else
|
echo >&2 "expected args ($EXPECTED_CURL_ARGS), got ($*)"
|
||||||
echo $URL
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
echo "$URL"'
|
||||||
wget() {
|
|
||||||
if [ "_$*" != "_$EXPECTED_WGET_ARGS" ]; then
|
cat > "$TEST_BIN/wget" <<'OUTER'
|
||||||
echo >&2 "expected args ($EXPECTED_WGET_ARGS), got ($*)"
|
#!/bin/sh
|
||||||
return 1
|
if [ "_$*" != "_$EXPECTED_WGET_ARGS" ]; then
|
||||||
else
|
echo >&2 "expected args ($EXPECTED_WGET_ARGS), got ($*)"
|
||||||
local WGET_CONTENTS
|
exit 1
|
||||||
WGET_CONTENTS="
|
fi
|
||||||
|
cat >&2 <<CONTENTS
|
||||||
HTTP/1.1 301 Moved Permanently
|
HTTP/1.1 301 Moved Permanently
|
||||||
Location: https://github.com/nvm-sh/nvm/releases/latest
|
Location: https://github.com/nvm-sh/nvm/releases/latest
|
||||||
Content-Type: text/html; charset=utf-8
|
Content-Type: text/html; charset=utf-8
|
||||||
@@ -82,15 +90,11 @@ wget() {
|
|||||||
X-Content-Type-Options: nosniff
|
X-Content-Type-Options: nosniff
|
||||||
Vary: Accept-Encoding
|
Vary: Accept-Encoding
|
||||||
X-Served-By: 926b734ea1992f8ee1f88ab967a93dac
|
X-Served-By: 926b734ea1992f8ee1f88ab967a93dac
|
||||||
"
|
CONTENTS
|
||||||
"$WGET_CONTENTS" | while read line
|
OUTER
|
||||||
do
|
chmod +x "$TEST_BIN/wget"
|
||||||
>&2 echo "$line"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
\. ../../common.sh
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
try nvm_get_latest
|
try nvm_get_latest
|
||||||
[ "_$CAPTURED_STDOUT" = "_$EXPECTED_VERSION" ] \
|
[ "_$CAPTURED_STDOUT" = "_$EXPECTED_VERSION" ] \
|
||||||
|
|||||||
@@ -2,20 +2,26 @@
|
|||||||
|
|
||||||
die () { echo "$@" ; cleanup ; exit 1; }
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
WORK="$PWD/nvm_get_latest_failed_redirect-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
unset -f curl wget
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
\. ../../../nvm.sh
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
\. ../../common.sh
|
\. ../../common.sh
|
||||||
|
|
||||||
curl() {
|
OLDPATH="$PATH"
|
||||||
return 1
|
|
||||||
}
|
# fake curl/wget: `command curl` bypasses shell functions, so the mocks must be executables on PATH
|
||||||
wget() {
|
make_fake_curl "$TEST_BIN" 'exit 1'
|
||||||
return 1
|
printf '#!/bin/sh\nexit 1\n' > "$TEST_BIN/wget"
|
||||||
}
|
chmod +x "$TEST_BIN/wget"
|
||||||
|
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
try_err nvm_get_latest
|
try_err nvm_get_latest
|
||||||
[ "_$CAPTURED_STDERR" = "_https://latest.nvm.sh did not redirect to the latest release on GitHub" ] \
|
[ "_$CAPTURED_STDERR" = "_https://latest.nvm.sh did not redirect to the latest release on GitHub" ] \
|
||||||
|
|||||||
Reference in New Issue
Block a user