mirror of
https://github.com/nvm-sh/nvm.git
synced 2025-08-17 19:13:43 +00:00
Compare commits
10 Commits
16c8e22b9f
...
f439acda4a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f439acda4a | ||
![]() |
dd89af53f5 | ||
![]() |
bd090ef7f8 | ||
![]() |
4c7d899447 | ||
![]() |
80cb39d712 | ||
![]() |
93277112ae | ||
![]() |
762f9ef9d1 | ||
![]() |
e597bb208e | ||
![]() |
aa427ad396 | ||
![]() |
c20db2ab86 |
3
.github/workflows/latest-npm.yml
vendored
3
.github/workflows/latest-npm.yml
vendored
@ -2,6 +2,9 @@ name: 'Tests: `nvm install-latest-npm`'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
|
11
.github/workflows/lint.yml
vendored
11
.github/workflows/lint.yml
vendored
@ -2,10 +2,11 @@ name: 'Tests: linting'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
eclint:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: step-security/harden-runner@v2
|
||||
@ -23,8 +24,6 @@ jobs:
|
||||
- run: npm run eclint
|
||||
|
||||
dockerfile_lint:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: step-security/harden-runner@v2
|
||||
@ -44,8 +43,6 @@ jobs:
|
||||
- run: npm run dockerfile_lint
|
||||
|
||||
doctoc:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: step-security/harden-runner@v2
|
||||
@ -63,8 +60,6 @@ jobs:
|
||||
- run: npm run doctoc:check
|
||||
|
||||
test_naming:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: step-security/harden-runner@v2
|
||||
|
3
.github/workflows/rebase.yml
vendored
3
.github/workflows/rebase.yml
vendored
@ -2,6 +2,9 @@ name: Automatic Rebase
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
_:
|
||||
permissions:
|
||||
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@ -2,10 +2,11 @@ name: 'Tests: release process'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
release:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
|
3
.github/workflows/require-allow-edits.yml
vendored
3
.github/workflows/require-allow-edits.yml
vendored
@ -2,6 +2,9 @@ name: Require “Allow Edits”
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
_:
|
||||
permissions:
|
||||
|
9
.github/workflows/shellcheck.yml
vendored
9
.github/workflows/shellcheck.yml
vendored
@ -2,10 +2,11 @@ name: 'Tests: shellcheck'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
shellcheck_matrix:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@ -52,8 +53,4 @@ jobs:
|
||||
needs: [shellcheck_matrix]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
egress-policy: block
|
||||
- run: true
|
||||
|
5
.github/workflows/tests.yml
vendored
5
.github/workflows/tests.yml
vendored
@ -2,6 +2,9 @@ name: urchin tests
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
permissions:
|
||||
@ -49,6 +52,8 @@ jobs:
|
||||
- run: make TERM=xterm-256color TEST_SUITE="${{ matrix.suite }}" SHELL="${{ matrix.shell }}" URCHIN="$(npx which urchin)" test-${{ matrix.shell }}
|
||||
|
||||
nvm:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all test suites, all shells'
|
||||
needs: [tests]
|
||||
runs-on: ubuntu-latest
|
||||
|
3
.github/workflows/toc.yml
vendored
3
.github/workflows/toc.yml
vendored
@ -2,6 +2,9 @@ name: update readme TOC
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
_:
|
||||
permissions:
|
||||
|
3
.github/workflows/windows-npm.yml
vendored
3
.github/workflows/windows-npm.yml
vendored
@ -2,6 +2,9 @@ name: 'Tests on Windows: `nvm install`'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
NVM_INSTALL_GITHUB_REPO: ${{ github.repository }}
|
||||
NVM_INSTALL_VERSION: ${{ github.sha }}
|
||||
|
11
.travis.yml
11
.travis.yml
@ -8,6 +8,10 @@ addons:
|
||||
# - gcc-4.8
|
||||
# - g++-4.8
|
||||
|
||||
# https://gist.github.com/iedemam/9830045
|
||||
git:
|
||||
submodules: false
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
directories:
|
||||
@ -16,6 +20,11 @@ cache:
|
||||
before_install:
|
||||
- sudo sed -i 's/mozilla\/DST_Root_CA_X3.crt/!mozilla\/DST_Root_CA_X3.crt/g' /etc/ca-certificates.conf
|
||||
- sudo update-ca-certificates -f
|
||||
|
||||
# https://gist.github.com/iedemam/9830045
|
||||
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
|
||||
- git submodule update --init --recursive
|
||||
|
||||
- $SHELL --version 2> /dev/null || dpkg -s $SHELL 2> /dev/null || which $SHELL
|
||||
- curl --version
|
||||
- wget --version
|
||||
@ -23,7 +32,7 @@ before_install:
|
||||
- zsh --version
|
||||
- dpkg -s dash | grep ^Version | awk '{print $2}'
|
||||
# install python
|
||||
- pyenv install 2.7.18
|
||||
- pyenv local 2.7.18 || pyenv install 2.7.18
|
||||
- pyenv local 2.7.18 || echo 'pyenv failed'
|
||||
- python -V
|
||||
install:
|
||||
|
8
Makefile
8
Makefile
@ -40,10 +40,14 @@ list:
|
||||
# Note that preexisting NVM_* variables are unset to avoid interfering with tests, except when running the Travis tests (where NVM_DIR must be passed in and the env. is assumed to be pristine).
|
||||
.PHONY: $(SHELL_TARGETS)
|
||||
$(SHELL_TARGETS):
|
||||
@shell='$@'; shell=$${shell##*-}; which "$$shell" >/dev/null || { printf '\033[0;31m%s\033[0m\n' "WARNING: Cannot test with shell '$$shell': not found." >&2; exit 0; } && \
|
||||
@shell='$@'; shell=$${shell##*-}; \
|
||||
which "$$shell" >/dev/null || { printf '\033[0;31m%s\033[0m\n' "WARNING: Cannot test with shell '$$shell': not found." >&2; exit 0; } && \
|
||||
printf '\n\033[0;34m%s\033[0m\n' "Running tests in $$shell"; \
|
||||
[ -z "$$TRAVIS_BUILD_DIR" ] && for v in $$(set | awk -F'=' '$$1 ~ "^NVM_" { print $$1 }'); do unset $$v; done && unset v; \
|
||||
for suite in $(TEST_SUITE); do $(URCHIN) -f -s $$shell test/$$suite || exit; done
|
||||
for suite in $(TEST_SUITE); do \
|
||||
echo "Running test suite: $$suite"; \
|
||||
$(URCHIN) -f -s $$shell test/$$suite || exit; \
|
||||
done
|
||||
|
||||
# All-tests target: invokes the specified test suites for ALL shells defined in $(SHELLS).
|
||||
.PHONY: test
|
||||
|
@ -39,6 +39,7 @@
|
||||
- [Restoring PATH](#restoring-path)
|
||||
- [Set default node version](#set-default-node-version)
|
||||
- [Use a mirror of node binaries](#use-a-mirror-of-node-binaries)
|
||||
- [Pass Authorization header to mirror](#pass-authorization-header-to-mirror)
|
||||
- [.nvmrc](#nvmrc)
|
||||
- [Deeper Shell Integration](#deeper-shell-integration)
|
||||
- [Calling `nvm use` automatically in a directory with a `.nvmrc` file](#calling-nvm-use-automatically-in-a-directory-with-a-nvmrc-file)
|
||||
@ -530,6 +531,13 @@ NVM_IOJS_ORG_MIRROR=https://iojs.org/dist nvm install iojs-v1.0.3
|
||||
|
||||
`nvm use` will not, by default, create a "current" symlink. Set `$NVM_SYMLINK_CURRENT` to "true" to enable this behavior, which is sometimes useful for IDEs. Note that using `nvm` in multiple shell tabs with this environment variable enabled can cause race conditions.
|
||||
|
||||
#### Pass Authorization header to mirror
|
||||
To pass an Authorization header through to the mirror url, set `$NVM_AUTH_HEADER`
|
||||
|
||||
```sh
|
||||
NVM_AUTH_HEADER="Bearer secret-token" nvm install node
|
||||
```
|
||||
|
||||
### .nvmrc
|
||||
|
||||
You can create a `.nvmrc` file containing a node version number (or any other string that `nvm` understands; see `nvm --help` for details) in the project root directory (or any parent directory).
|
||||
|
49
nvm.sh
49
nvm.sh
@ -116,12 +116,19 @@ nvm_get_latest() {
|
||||
}
|
||||
|
||||
nvm_download() {
|
||||
local CURL_COMPRESSED_FLAG
|
||||
if nvm_has "curl"; then
|
||||
local CURL_COMPRESSED_FLAG=""
|
||||
local CURL_HEADER_FLAG=""
|
||||
|
||||
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
||||
sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")
|
||||
CURL_HEADER_FLAG="--header \"Authorization: ${sanitized_header}\""
|
||||
fi
|
||||
|
||||
if nvm_curl_use_compression; then
|
||||
CURL_COMPRESSED_FLAG="--compressed"
|
||||
fi
|
||||
curl --fail ${CURL_COMPRESSED_FLAG:-} -q "$@"
|
||||
eval "curl -q --fail ${CURL_COMPRESSED_FLAG:-} ${CURL_HEADER_FLAG:-} $*"
|
||||
elif nvm_has "wget"; then
|
||||
# Emulate curl with wget
|
||||
ARGS=$(nvm_echo "$@" | command sed -e 's/--progress-bar /--progress=bar /' \
|
||||
@ -133,11 +140,20 @@ nvm_download() {
|
||||
-e 's/-sS /-nv /' \
|
||||
-e 's/-o /-O /' \
|
||||
-e 's/-C - /-c /')
|
||||
|
||||
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
||||
ARGS="${ARGS} --header \"${NVM_AUTH_HEADER}\""
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
eval wget $ARGS
|
||||
fi
|
||||
}
|
||||
|
||||
nvm_sanitize_auth_header() {
|
||||
# Remove potentially dangerous characters
|
||||
nvm_echo "$1" | command sed 's/[^a-zA-Z0-9:;_. -]//g'
|
||||
}
|
||||
|
||||
nvm_has_system_node() {
|
||||
[ "$(nvm deactivate >/dev/null 2>&1 && command -v node)" != '' ]
|
||||
}
|
||||
@ -370,8 +386,9 @@ nvm_install_latest_npm() {
|
||||
|| { [ $NVM_IS_16_OR_ABOVE -eq 1 ] && [ $NVM_IS_16_LTS_OR_ABOVE -eq 0 ]; } \
|
||||
|| { [ $NVM_IS_17_OR_ABOVE -eq 1 ] && [ $NVM_IS_18_OR_ABOVE -eq 0 ]; } \
|
||||
; then
|
||||
nvm_echo '* `npm` `v8.x` is the last version that works on `node` `v12`, `v14.13` - `v14.16`, or `v16.0` - `v16.12`'
|
||||
$NVM_NPM_CMD install -g npm@8
|
||||
nvm_echo '* `npm` `v8.6` is the last version that works on `node` `v12`, `v14.13` - `v14.16`, or `v16.0` - `v16.12`'
|
||||
# ^8.7 breaks `npm ls` on file: deps
|
||||
$NVM_NPM_CMD install -g npm@8.6
|
||||
elif \
|
||||
[ $NVM_IS_18_17_OR_ABOVE -eq 0 ] \
|
||||
|| { [ $NVM_IS_19_OR_ABOVE -eq 1 ] && [ $NVM_IS_20_5_OR_ABOVE -eq 0 ]; } \
|
||||
@ -480,9 +497,9 @@ additionally, a single bare nvm-recognized version-ish must be present (after st
|
||||
warn_text="non-commented content parsed:
|
||||
${1}"
|
||||
|
||||
nvm_err "$(nvm_wrap_with_color_code r "${error_text}")
|
||||
nvm_err "$(nvm_wrap_with_color_code 'r' "${error_text}")
|
||||
|
||||
$(nvm_wrap_with_color_code y "${warn_text}")"
|
||||
$(nvm_wrap_with_color_code 'y' "${warn_text}")"
|
||||
}
|
||||
|
||||
nvm_process_nvmrc() {
|
||||
@ -3063,16 +3080,16 @@ nvm() {
|
||||
nvm_echo ' nvm cache clear Empty cache directory for nvm'
|
||||
nvm_echo ' nvm set-colors [<color codes>] Set five text colors using format "yMeBg". Available when supported.'
|
||||
nvm_echo ' Initial colors are:'
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code b b)$(nvm_wrap_with_color_code y y)$(nvm_wrap_with_color_code g g)$(nvm_wrap_with_color_code r r)$(nvm_wrap_with_color_code e e)"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')$(nvm_wrap_with_color_code 'y' 'y')$(nvm_wrap_with_color_code 'g' 'g')$(nvm_wrap_with_color_code 'r' 'r')$(nvm_wrap_with_color_code 'e' 'e')"
|
||||
nvm_echo ' Color codes:'
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code r r)/$(nvm_wrap_with_color_code R R) = $(nvm_wrap_with_color_code r red) / $(nvm_wrap_with_color_code R 'bold red')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code g g)/$(nvm_wrap_with_color_code G G) = $(nvm_wrap_with_color_code g green) / $(nvm_wrap_with_color_code G 'bold green')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code b b)/$(nvm_wrap_with_color_code B B) = $(nvm_wrap_with_color_code b blue) / $(nvm_wrap_with_color_code B 'bold blue')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code c c)/$(nvm_wrap_with_color_code C C) = $(nvm_wrap_with_color_code c cyan) / $(nvm_wrap_with_color_code C 'bold cyan')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code m m)/$(nvm_wrap_with_color_code M M) = $(nvm_wrap_with_color_code m magenta) / $(nvm_wrap_with_color_code M 'bold magenta')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code y y)/$(nvm_wrap_with_color_code Y Y) = $(nvm_wrap_with_color_code y yellow) / $(nvm_wrap_with_color_code Y 'bold yellow')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code k k)/$(nvm_wrap_with_color_code K K) = $(nvm_wrap_with_color_code k black) / $(nvm_wrap_with_color_code K 'bold black')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code e e)/$(nvm_wrap_with_color_code W W) = $(nvm_wrap_with_color_code e 'light grey') / $(nvm_wrap_with_color_code W white)"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'r' 'r')/$(nvm_wrap_with_color_code 'R' 'R') = $(nvm_wrap_with_color_code 'r' 'red') / $(nvm_wrap_with_color_code 'R' 'bold red')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'g' 'g')/$(nvm_wrap_with_color_code 'G' 'G') = $(nvm_wrap_with_color_code 'g' 'green') / $(nvm_wrap_with_color_code 'G' 'bold green')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')/$(nvm_wrap_with_color_code 'B' 'B') = $(nvm_wrap_with_color_code 'b' 'blue') / $(nvm_wrap_with_color_code 'B' 'bold blue')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'c' 'c')/$(nvm_wrap_with_color_code 'C' 'C') = $(nvm_wrap_with_color_code 'c' 'cyan') / $(nvm_wrap_with_color_code 'C' 'bold cyan')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'm' 'm')/$(nvm_wrap_with_color_code 'M' 'M') = $(nvm_wrap_with_color_code 'm' 'magenta') / $(nvm_wrap_with_color_code 'M' 'bold magenta')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'y' 'y')/$(nvm_wrap_with_color_code 'Y' 'Y') = $(nvm_wrap_with_color_code 'y' 'yellow') / $(nvm_wrap_with_color_code 'Y' 'bold yellow')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'k' 'k')/$(nvm_wrap_with_color_code 'K' 'K') = $(nvm_wrap_with_color_code 'k' 'black') / $(nvm_wrap_with_color_code 'K' 'bold black')"
|
||||
nvm_echo_with_colors " $(nvm_wrap_with_color_code 'e' 'e')/$(nvm_wrap_with_color_code 'W' 'W') = $(nvm_wrap_with_color_code 'e' 'light grey') / $(nvm_wrap_with_color_code 'W' 'white')"
|
||||
nvm_echo 'Example:'
|
||||
nvm_echo ' nvm install 8.0.0 Install a specific version number'
|
||||
nvm_echo ' nvm use 8.0 Use the latest available 8.0.x release'
|
||||
@ -4388,7 +4405,7 @@ nvm() {
|
||||
nvm_sanitize_path nvm_has_colors nvm_process_parameters \
|
||||
nvm_node_version_has_solaris_binary nvm_iojs_version_has_solaris_binary \
|
||||
nvm_curl_libz_support nvm_command_info nvm_is_zsh nvm_stdout_is_terminal \
|
||||
nvm_npmrc_bad_news_bears \
|
||||
nvm_npmrc_bad_news_bears nvm_sanitize_auth_header \
|
||||
nvm_get_colors nvm_set_colors nvm_print_color_code nvm_wrap_with_color_code nvm_format_help_message_colors \
|
||||
nvm_echo_with_colors nvm_err_with_colors \
|
||||
nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \
|
||||
|
236
test/common.sh
236
test/common.sh
@ -102,104 +102,146 @@ watch() {
|
||||
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"
|
||||
# JSON parsing from https://gist.github.com/assaf/ee377a186371e2e269a7
|
||||
nvm_json_throw() {
|
||||
nvm_err "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
extract_value() {
|
||||
local key
|
||||
key="$1"
|
||||
local parsed
|
||||
parsed="$2"
|
||||
echo "$parsed" | grep "^$key=" | cut -d'=' -f2 | tr -d '"'
|
||||
nvm_json_awk_egrep() {
|
||||
local pattern_string
|
||||
pattern_string="${1}"
|
||||
|
||||
awk '{
|
||||
while ($0) {
|
||||
start=match($0, pattern);
|
||||
token=substr($0, start, RLENGTH);
|
||||
print token;
|
||||
$0=substr($0, start+RLENGTH);
|
||||
}
|
||||
}' "pattern=${pattern_string}"
|
||||
}
|
||||
|
||||
nvm_json_tokenize() {
|
||||
local GREP
|
||||
GREP='grep -Eao'
|
||||
|
||||
local ESCAPE
|
||||
local CHAR
|
||||
|
||||
# if echo "test string" | grep -Eo "test" > /dev/null 2>&1; then
|
||||
# ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
|
||||
# CHAR='[^[:cntrl:]"\\]'
|
||||
# else
|
||||
GREP=nvm_json_awk_egrep
|
||||
ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
|
||||
CHAR='[^[:cntrl:]"\\\\]'
|
||||
# fi
|
||||
|
||||
local STRING
|
||||
STRING="\"${CHAR}*(${ESCAPE}${CHAR}*)*\""
|
||||
local NUMBER
|
||||
NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
|
||||
local KEYWORD
|
||||
KEYWORD='null|false|true'
|
||||
local SPACE
|
||||
SPACE='[[:space:]]+'
|
||||
|
||||
$GREP "${STRING}|${NUMBER}|${KEYWORD}|${SPACE}|." | TERM=dumb grep -Ev "^${SPACE}$"
|
||||
}
|
||||
|
||||
_json_parse_array() {
|
||||
local index=0
|
||||
local ary=''
|
||||
read -r token
|
||||
case "$token" in
|
||||
']') ;;
|
||||
*)
|
||||
while :; do
|
||||
_json_parse_value "${1}" "${index}"
|
||||
index=$((index+1))
|
||||
ary="${ary}${value}"
|
||||
read -r token
|
||||
case "${token}" in
|
||||
']') break ;;
|
||||
',') ary="${ary}," ;;
|
||||
*) nvm_json_throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
|
||||
esac
|
||||
read -r token
|
||||
done
|
||||
;;
|
||||
esac
|
||||
:
|
||||
}
|
||||
|
||||
_json_parse_object() {
|
||||
local key
|
||||
local obj=''
|
||||
read -r token
|
||||
case "$token" in
|
||||
'}') ;;
|
||||
*)
|
||||
while :; do
|
||||
case "${token}" in
|
||||
'"'*'"') key="${token}" ;;
|
||||
*) nvm_json_throw "EXPECTED string GOT ${token:-EOF}" ;;
|
||||
esac
|
||||
read -r token
|
||||
case "${token}" in
|
||||
':') ;;
|
||||
*) nvm_json_throw "EXPECTED : GOT ${token:-EOF}" ;;
|
||||
esac
|
||||
read -r token
|
||||
_json_parse_value "${1}" "${key}"
|
||||
obj="${obj}${key}:${value}"
|
||||
read -r token
|
||||
case "${token}" in
|
||||
'}') break ;;
|
||||
',') obj="${obj}," ;;
|
||||
*) nvm_json_throw "EXPECTED , or } GOT ${token:-EOF}" ;;
|
||||
esac
|
||||
read -r token
|
||||
done
|
||||
;;
|
||||
esac
|
||||
:
|
||||
}
|
||||
|
||||
_json_parse_value() {
|
||||
local jpath="${1:+$1,}$2"
|
||||
local isleaf=0
|
||||
local isempty=0
|
||||
local print=0
|
||||
|
||||
case "$token" in
|
||||
'{') _json_parse_object "${jpath}" ;;
|
||||
'[') _json_parse_array "${jpath}" ;;
|
||||
# At this point, the only valid single-character tokens are digits.
|
||||
''|[!0-9]) nvm_json_throw "EXPECTED value GOT >${token:-EOF}<" ;;
|
||||
*)
|
||||
value=$token
|
||||
isleaf=1
|
||||
[ "${value}" = '""' ] && isempty=1
|
||||
;;
|
||||
esac
|
||||
|
||||
[ "${value}" = '' ] && return
|
||||
[ "${isleaf}" -eq 1 ] && [ $isempty -eq 0 ] && print=1
|
||||
[ "${print}" -eq 1 ] && printf "[%s]\t%s\n" "${jpath}" "${value}"
|
||||
:
|
||||
}
|
||||
|
||||
_json_parse() {
|
||||
read -r token
|
||||
_json_parse_value
|
||||
read -r token
|
||||
case "${token}" in
|
||||
'') ;;
|
||||
*) nvm_json_throw "EXPECTED EOF GOT >${token}<" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
nvm_json_extract() {
|
||||
nvm_json_tokenize | _json_parse | grep -e "${1}" | awk '{print $2 $3}'
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ cleanup () { rm -f "${BEFORE}" "${AFTER}"; }
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
typeset -f | awk '/ \(\) $/ && !/^main / {print $1}' > "${BEFORE}"
|
||||
env | grep -v PATH= | grep -v IFS= | grep -v NVM_ | sort >> "${BEFORE}"
|
||||
env | grep -v PATH= | grep -v IFS= | grep -v NVM_ | grep -v TRAVIS_ | sort >> "${BEFORE}"
|
||||
|
||||
set +e # TODO: fix
|
||||
\. ../../nvm.sh
|
||||
@ -20,11 +20,11 @@ type nvm > /dev/null 2>&1 || die "nvm not loaded"
|
||||
nvm unload
|
||||
|
||||
typeset -f | awk '/ \(\) $/ && !/^main / {print $1}' > "${AFTER}"
|
||||
env | grep -v PATH= | grep -v IFS= | sort >> "${AFTER}"
|
||||
env | grep -v PATH= | grep -v IFS= | grep -v TRAVIS_ | sort >> "${AFTER}"
|
||||
|
||||
! type nvm > /dev/null 2>&1 || die "nvm not unloaded"
|
||||
|
||||
DIFF="$(diff "${BEFORE}" "${AFTER}" ||:)"
|
||||
[ -z "${DIFF}" ] || die "function pollution found: ${DIFF}"
|
||||
[ -z "${DIFF}" ] || die "function pollution found: >${DIFF}<"
|
||||
|
||||
cleanup
|
||||
|
@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
cleanup () {
|
||||
unset -f die cleanup
|
||||
unset -f die cleanup NVM_AUTH_HEADER
|
||||
docker stop httpbin && docker rm httpbin
|
||||
}
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
@ -15,4 +16,13 @@ nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh" >/de
|
||||
# nvm_download should fail to download wrong_install.sh
|
||||
! nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/wrong_install.sh" >/dev/null || die "nvm_download should fail to download no existing file"
|
||||
|
||||
# nvm_download should pass when calling with auth header
|
||||
docker pull kennethreitz/httpbin && docker run --shell=bash -d --name httpbin -p 80:80 kennethreitz/httpbin
|
||||
sleep 1 # wait for httpbin to start
|
||||
NVM_AUTH_HEADER="Bearer test-token" nvm_download "http://127.0.0.1/bearer" > /dev/null || die 'nvm_download with auth header should send correctly'
|
||||
|
||||
# nvm_download should fail when calling without auth header
|
||||
nvm_download "http://127.0.0.1/bearer" > /dev/null && die 'nvm_download with no auth header should not send the header and should fail'
|
||||
docker stop httpbin && docker rm httpbin
|
||||
|
||||
cleanup
|
||||
|
@ -14,7 +14,7 @@ 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")")")"
|
||||
EXPECTED="$(nvm_json_extract node < "${f}/expected.json" | tr -d '"')"
|
||||
|
||||
[ "${EXIT_CODE}" = "0" ] || die "$(basename "${f}"): expected exit code of 0 but got ${EXIT_CODE}"
|
||||
|
||||
@ -26,7 +26,7 @@ for f in ../../../test/fixtures/nvmrc/test/fixtures/invalid/*; do
|
||||
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/"$//')"
|
||||
EXPECTED="$(nvm_json_extract < "${f}/expected.json" | tr -d '"')"
|
||||
|
||||
[ "${EXIT_CODE}" != "0" ] || die "$(basename "${f}"): expected exit code of 'not 0' but got ${EXIT_CODE}"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user