Compare commits

...

16 Commits

Author SHA1 Message Date
Jordan Harband
663c9968cb wip 2024-07-08 09:14:44 -07:00
Jordan Harband
1fd0c8ca90 [New] allow an empty $NVM_IOJS_ORG_MIRROR to quietly skip io.js lookup
Fixes #1080. Fixes #3386.
2024-07-07 22:30:51 -07:00
Jordan Harband
762f9ef9d1 [Tests] only install python 2.7 if not already installed
See ee6f7667 / #3067
2024-07-06 10:29:55 -05:00
Jordan Harband
e597bb208e [Tests] use a better JSON parsing implementation 2024-06-10 11:33:12 -07:00
Jordan Harband
aa427ad396 [Tests] ensure travis can access public repo submodules 2024-06-10 09:15:16 -07:00
Jordan Harband
c20db2ab86 [actions] improve default action permissions 2024-06-10 08:59:48 -07:00
Jordan Harband
29dce5edfd [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>
2024-06-07 10:13:00 -07:00
Jordan Harband
95081f0bc2 [readme] update CII badge URLs 2024-06-06 14:19:11 -07:00
Jordan Harband
1750b8d327 [actions] update vampire/setup-wsl action 2024-05-30 12:37:36 -07:00
Jordan Harband
97093dc1b3 [Dev Deps] update markdown-link-check, semver 2024-05-30 12:36:26 -07:00
Jordan Harband
811c039e2b [actions] finisher tweaks 2024-03-08 22:28:53 -08:00
Huy Z
294ff9e3aa [readme] Fix uninstall instructions
`nvm unload` will unset NVM_DIR. So gotta save NVM_DIR first.
2024-02-13 03:39:07 -08:00
Raphael Boidol
c24c3134a7 [actions] update action versions to use node 20 2024-02-18 21:56:53 +01:00
Jordi Paris Ferrer
c82e7a6f62 Fix typo in WSL section of README
`u` -> `you`
2024-02-17 16:39:36 -08:00
jbidad
4e2a71ba9b [Docs] add nvm unload to uninstall nvm instructions 2024-01-18 12:07:01 +03:30
Jordan Harband
6c9cd2f2d1 [security] fix typo in threat model 2023-12-15 09:46:35 -08:00
21 changed files with 441 additions and 85 deletions

View File

@@ -26,3 +26,10 @@ insert_final_newline = off
[Makefile]
indent_style = tab
[test/fixtures/nvmrc/**]
indent_style = off
insert_final_newline = off
[test/fixtures/actual/alias/empty]
insert_final_newline = off

View File

@@ -11,7 +11,7 @@ The aim of this section is to facilitate the identification of potential securit
The following assets are considered important for the `nvm` project:
- `nvm` source code and project documentation
- Underlying `nvm`` dependencies
- Underlying `nvm` dependencies
- `nvm` development infrastructure
- `nvm` installed devices including servers

View File

@@ -2,6 +2,9 @@ name: 'Tests: `nvm install-latest-npm`'
on: [pull_request, push]
permissions:
contents: read
jobs:
matrix:
runs-on: ubuntu-latest
@@ -9,11 +12,12 @@ jobs:
latest: ${{ steps.set-matrix.outputs.requireds }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
iojs.org:443
nodejs.org:443
raw.githubusercontent.com:443
- uses: ljharb/actions/node/matrix@main
id: set-matrix
with:
@@ -46,7 +50,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
@@ -54,7 +58,7 @@ jobs:
iojs.org:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ljharb/actions/node/install@main
name: 'install node'
with:
@@ -74,8 +78,4 @@ jobs:
needs: [nodes]
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
with:
egress-policy: block
- run: 'echo tests completed'
- run: true

View File

@@ -2,20 +2,21 @@ 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@v1
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
raw.githubusercontent.com:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
with:
@@ -23,11 +24,9 @@ jobs:
- run: npm run eclint
dockerfile_lint:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@v1
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
ghcr.io:443
@@ -36,7 +35,7 @@ jobs:
pkg-containers.githubusercontent.com:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
with:
@@ -44,18 +43,16 @@ jobs:
- run: npm run dockerfile_lint
doctoc:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@v1
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
raw.githubusercontent.com:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
with:
@@ -63,15 +60,13 @@ jobs:
- run: npm run doctoc:check
test_naming:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@v1
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
raw.githubusercontent.com:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: check tests filenames
run: ./rename_test.sh --check

View File

@@ -2,6 +2,9 @@ name: Automatic Rebase
on: [pull_request_target]
permissions:
contents: read
jobs:
_:
permissions:
@@ -12,12 +15,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
api.github.com:443
github.com:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -2,20 +2,24 @@ name: 'Tests: release process'
on: [pull_request, push]
permissions:
contents: read
jobs:
release:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
api.github.com:443
objects.githubusercontent.com:443
raw.githubusercontent.com:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "14"
- run: npm install

View File

@@ -2,6 +2,9 @@ name: Require “Allow Edits”
on: [pull_request_target]
permissions:
contents: read
jobs:
_:
permissions:
@@ -12,7 +15,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
api.github.com:443

View File

@@ -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
@@ -27,13 +28,14 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
ghcr.io:443
github.com:443
pkg-containers.githubusercontent.com:443
- uses: actions/checkout@v3
formulae.brew.sh:443
- uses: actions/checkout@v4
- name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Install latest shellcheck
@@ -51,8 +53,4 @@ jobs:
needs: [shellcheck_matrix]
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
with:
egress-policy: block
- run: 'echo tests completed'
- run: true

View File

@@ -2,6 +2,9 @@ name: urchin tests
on: [push]
permissions:
contents: read
jobs:
tests:
permissions:
@@ -26,7 +29,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
@@ -34,7 +37,7 @@ jobs:
raw.githubusercontent.com:443
nodejs.org:443
iojs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: sudo ${{ matrix.shell }} --version 2> /dev/null || dpkg -s ${{ matrix.shell }} 2> /dev/null || which ${{ matrix.shell }}
- run: curl --version
- run: wget --version
@@ -49,8 +52,10 @@ 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
steps:
- run: 'echo tests completed'
- run: true

View File

@@ -2,6 +2,9 @@ name: update readme TOC
on: [push]
permissions:
contents: read
jobs:
_:
permissions:
@@ -12,12 +15,12 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@v1
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
registry.npmjs.org:443
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
# https://github.com/actions/checkout/issues/217#issue-599945005
# pulls all commits (needed for lerna / semantic release to correctly version)
@@ -25,7 +28,7 @@ jobs:
# pulls all tags (needed for lerna / semantic release to correctly version)
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: '16'
- run: npm install

View File

@@ -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 }}
@@ -123,7 +126,7 @@ jobs:
- ''
- 'script'
steps:
- uses: Vampire/setup-wsl@v2
- uses: Vampire/setup-wsl@v3
with:
distribution: ${{ matrix.wsl-distrib }}
additional-packages: bash git curl ca-certificates wget
@@ -166,7 +169,7 @@ jobs:
- ''
- 'script'
steps:
- uses: Vampire/setup-wsl@v2
- uses: Vampire/setup-wsl@v3
with:
distribution: ${{ matrix.wsl-distrib }}
additional-packages: bash git curl ca-certificates wget
@@ -187,4 +190,4 @@ jobs:
needs: [wsl_matrix, wsl_matrix_unofficial, cygwin_matrix, msys_matrix, msys_fail_install]
runs-on: ubuntu-latest
steps:
- run: 'echo tests completed'
- run: true

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "test/fixtures/nvmrc"]
path = test/fixtures/nvmrc
url = git@github.com:nvm-sh/nvmrc.git

View File

@@ -8,6 +8,12 @@ addons:
# - gcc-4.8
# - g++-4.8
# https://gist.github.com/iedemam/9830045
git:
submodules: false
group: previous
cache:
ccache: true
directories:
@@ -16,6 +22,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 +34,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:

View File

@@ -6,7 +6,7 @@
</a>
# Node Version Manager [![Build Status](https://app.travis-ci.com/nvm-sh/nvm.svg?branch=master)][3] [![nvm version](https://img.shields.io/badge/version-v0.39.7-yellow.svg)][4] [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/684/badge)](https://bestpractices.coreinfrastructure.org/projects/684)
# Node Version Manager [![Build Status](https://app.travis-ci.com/nvm-sh/nvm.svg?branch=master)][3] [![nvm version](https://img.shields.io/badge/version-v0.39.7-yellow.svg)][4] [![CII Best Practices](https://bestpractices.dev/projects/684/badge)](https://bestpractices.dev/projects/684)
<!-- To update this table of contents, ensure you have run `npm install` then `npm run doctoc` -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
@@ -298,6 +298,13 @@ To install a specific version of node:
nvm install 14.7.0 # or 16.3.0, 12.22.1, etc
```
To set an alias:
```sh
nvm alias my_alias v14.4.0
```
Make sure that your alias does not contain any spaces or slashes.
The first version installed becomes the default. New shells will start with the default version of node (e.g., `nvm alias default`).
You can list available versions using `ls-remote`:
@@ -563,7 +570,11 @@ Now using node v5.9.1 (npm v3.7.3)
`nvm use` et. al. will traverse directory structure upwards from the current directory looking for the `.nvmrc` file. In other words, running `nvm use` et. al. in any subdirectory of a directory with an `.nvmrc` will result in that `.nvmrc` being utilized.
The contents of a `.nvmrc` file **must** be the `<version>` (as described by `nvm --help`) followed by a newline. No trailing spaces are allowed, and the trailing newline is required.
The contents of a `.nvmrc` file **must** contain precisely one `<version>` (as described by `nvm --help`) followed by a newline. `.nvmrc` files may also have comments. The comment delimiter is `#`, and it and any text after it, as well as blank lines, and leading and trailing white space, will be ignored when parsing.
Key/value pairs using `=` are also allowed and ignored, but are reserved for future use, and may cause validation errors in the future.
Run [`npx nvmrc`](https://npmjs.com/nvmrc) to validate an `.nvmrc` file. If that tools results do not agree with nvm, one or the other has a bug - please file an issue.
### Deeper Shell Integration
@@ -844,8 +855,12 @@ As a potential alternative, @mhart (a Node contributor) has some [Docker images
To remove `nvm` manually, execute the following:
First, use `nvm unload` to remove the nvm command from your terminal session and delete the installation directory:
```sh
$ rm -rf "$NVM_DIR"
$ nvm_dir="${NVM_DIR:-~/.nvm}"
$ nvm unload
$ rm -rf "$nvm_dir"
```
Edit `~/.bashrc` (or other shell resource config) and remove the lines below:
@@ -1035,7 +1050,7 @@ This could simply be solved by running this in your root directory:
sudo chattr +i /etc/resolv.conf
```
This deletes your `resolv.conf` file that is automatically generated when u run WSL, creates a new file and puts `nameserver 8.8.8.8`, then creates a `wsl.conf` file and adds `[network]` and `generateResolveConf = false` to prevent auto-generation of that file.
This deletes your `resolv.conf` file that is automatically generated when you run WSL, creates a new file and puts `nameserver 8.8.8.8`, then creates a `wsl.conf` file and adds `[network]` and `generateResolveConf = false` to prevent auto-generation of that file.
You can check the contents of the file by running:

100
nvm.sh
View File

@@ -467,7 +467,89 @@ nvm_find_nvmrc() {
fi
}
# Obtain nvm version from rc file
nvm_nvmrc_invalid_msg() {
local error_text
error_text="invalid .nvmrc!
all non-commented content (anything after # is a comment) must be either:
- a single bare nvm-recognized version-ish
- or, multiple distinct key-value pairs, each key/value separated by a single equals sign (=)
additionally, a single bare nvm-recognized version-ish must be present (after stripping comments)."
local warn_text
warn_text="non-commented content parsed:
${1}"
nvm_err "$(nvm_wrap_with_color_code r "${error_text}")
$(nvm_wrap_with_color_code y "${warn_text}")"
}
nvm_process_nvmrc() {
local NVMRC_PATH="$1"
local lines
local unpaired_line
lines=$(command sed 's/#.*//' "$NVMRC_PATH" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | nvm_grep -v '^$')
if [ -z "$lines" ]; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
# Initialize key-value storage
local keys=''
local values=''
while IFS= read -r line; do
if [ -z "${line}" ]; then
continue
elif [ -z "${line%%=*}" ]; then
if [ -n "${unpaired_line}" ]; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
unpaired_line="${line}"
elif case "$line" in *'='*) true;; *) false;; esac; then
key="${line%%=*}"
value="${line#*=}"
# Trim whitespace around key and value
key=$(nvm_echo "${key}" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
value=$(nvm_echo "${value}" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# Check for invalid key "node"
if [ "${key}" = 'node' ]; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
# Check for duplicate keys
if nvm_echo "${keys}" | nvm_grep -q -E "(^| )${key}( |$)"; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
keys="${keys} ${key}"
values="${values} ${value}"
else
if [ -n "${unpaired_line}" ]; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
unpaired_line="${line}"
fi
done <<EOF
$lines
EOF
if [ -z "${unpaired_line}" ]; then
nvm_nvmrc_invalid_msg "${lines}"
return 1
fi
nvm_echo "${unpaired_line}"
}
nvm_rc_version() {
export NVM_RC_VERSION=''
local NVMRC_PATH
@@ -478,7 +560,12 @@ nvm_rc_version() {
fi
return 1
fi
NVM_RC_VERSION="$(command head -n 1 "${NVMRC_PATH}" | command tr -d '\r')" || command printf ''
if ! NVM_RC_VERSION="$(nvm_process_nvmrc "${NVMRC_PATH}")"; then
return 1
fi
if [ -z "${NVM_RC_VERSION}" ]; then
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
nvm_err "Warning: empty .nvmrc file found at \"${NVMRC_PATH}\""
@@ -678,6 +765,11 @@ nvm_remote_versions() {
NVM_FLAVOR="${NVM_NODE_PREFIX}"
unset PATTERN
;;
*)
if [ "${NVM_IOJS_ORG_MIRROR-x}" = '' ]; then
NVM_FLAVOR="${NVM_NODE_PREFIX}"
fi
;;
esac
if nvm_validate_implicit_alias "${PATTERN-}" 2>/dev/null; then
@@ -4058,6 +4150,9 @@ nvm() {
# so, unalias it.
nvm unalias "${ALIAS}"
return $?
elif echo "${ALIAS}" | grep -q "#"; then
nvm_err 'Aliases with a comment delimiter (#) are not supported.'
return 1
elif [ "${TARGET}" != '--' ]; then
# a target was passed: create an alias
if [ "${ALIAS#*\/}" != "${ALIAS}" ]; then
@@ -4271,6 +4366,7 @@ nvm() {
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 \
nvm_process_nvmrc nvm_nvmrc_invalid_msg \
>/dev/null 2>&1
unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS \

View File

@@ -43,9 +43,9 @@
"dockerfile_lint": "^0.3.4",
"doctoc": "^2.2.1",
"eclint": "^2.8.1",
"markdown-link-check": "^3.11.2",
"markdown-link-check": "^3.12.2",
"replace": "^1.2.2",
"semver": "^7.5.4",
"semver": "^7.6.2",
"urchin": "^0.0.5"
}
}

View File

@@ -101,3 +101,147 @@ watch() {
kill %2;
return $EXIT_CODE
}
# JSON parsing from https://gist.github.com/assaf/ee377a186371e2e269a7
nvm_json_throw() {
nvm_err "$*"
exit 1
}
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}'
}

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="$(nvm_json_extract node < "${f}/expected.json" | tr -d '"')"
[ "${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="$(nvm_json_extract < "${f}/expected.json" | tr -d '"')"
[ "${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

View File

@@ -3,7 +3,7 @@
die () { echo "$@" ; cleanup ; exit 1; }
cleanup() {
unset -f nvm_ls_remote nvm_ls_remote_iojs
unset -f nvm_ls_remote nvm_ls_remote_iojs nvm_ls_remote_node NVM_IOJS_ORG_MIRROR
}
\. ../../../nvm.sh
@@ -11,67 +11,72 @@ cleanup() {
OUTPUT="$(nvm_remote_versions stable 2>&1)"
EXPECTED_OUTPUT="Implicit aliases are not supported in nvm_remote_versions."
EXIT_CODE="$(nvm_remote_versions stable >/dev/null 2>&1; echo $?)"
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "implicit alias 'stable' did not error out with correct message, got $OUTPUT"
[ "_$EXIT_CODE" = "_1" ] || die "implicit alias 'stable' did not exit with code 1, got $EXIT_CODE"
[ "_${OUTPUT}" = "_${EXPECTED_OUTPUT}" ] || die "implicit alias 'stable' did not error out with correct message, got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_1' ] || die "implicit alias 'stable' did not exit with code 1, got ${EXIT_CODE}"
OUTPUT="$(nvm_remote_versions unstable 2>&1)"
EXPECTED_OUTPUT="Implicit aliases are not supported in nvm_remote_versions."
EXIT_CODE="$(nvm_remote_versions unstable >/dev/null 2>&1; echo $?)"
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "implicit alias 'unstable' did not error out with correct message, got $OUTPUT"
[ "_$EXIT_CODE" = "_1" ] || die "implicit alias 'unstable' did not exit with code 1, got $EXIT_CODE"
[ "_${OUTPUT}" = "_${EXPECTED_OUTPUT}" ] || die "implicit alias 'unstable' did not error out with correct message, got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_1' ] || die "implicit alias 'unstable' did not exit with code 1, got ${EXIT_CODE}"
nvm_ls_remote() {
echo "N/A"
}
OUTPUT="$(nvm_remote_versions foo)"
EXIT_CODE="$(nvm_remote_versions foo >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_N/A" ] || die "nonexistent version did not report N/A"
[ "_$EXIT_CODE" = "_3" ] || die "nonexistent version did not exit with code 3, got $EXIT_CODE"
[ "_${OUTPUT}" = "_N/A" ] || die "nonexistent version did not report N/A"
[ "_${EXIT_CODE}" = '_3' ] || die "nonexistent version did not exit with code 3, got ${EXIT_CODE}"
nvm_ls_remote_iojs() {
echo "N/A"
}
OUTPUT="$(nvm_remote_versions iojs-foo)"
EXIT_CODE="$(nvm_remote_versions iojs-foo >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_N/A" ] || die "nonexistent version did not report N/A"
[ "_$EXIT_CODE" = "_3" ] || die "nonexistent version did not exit with code 3, got $EXIT_CODE"
[ "_${OUTPUT}" = "_N/A" ] || die "nonexistent version did not report N/A"
[ "_${EXIT_CODE}" = '_3' ] || die "nonexistent version did not exit with code 3, got ${EXIT_CODE}"
nvm_ls_remote() {
nvm_ls_remote_node() {
echo "test output"
echo "more test output"
echo "pattern received: _$1_"
echo "pattern received: _${1}_"
}
nvm_ls_remote_iojs() {
echo "test iojs output"
echo "more iojs test output"
echo "iojs pattern received: _$1_"
echo "iojs pattern received: _${1}_"
}
OUTPUT="$(nvm_remote_versions foo)"
EXIT_CODE="$(nvm_remote_versions foo >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_$(nvm_ls_remote foo)
[ "_${OUTPUT}" = "_$(nvm_ls_remote foo)
$(nvm_ls_remote_iojs foo)" ] \
|| die "nvm_remote_versions foo did not return contents of nvm_ls_remote foo combined with nvm_ls_remote_iojs foo; got $OUTPUT"
[ "_$EXIT_CODE" = "_0" ] || die "nvm_remote_versions foo did not exit with 0, got $EXIT_CODE"
|| die "nvm_remote_versions foo did not return contents of nvm_ls_remote foo combined with nvm_ls_remote_iojs foo; got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_0' ] || die "nvm_remote_versions foo did not exit with 0, got ${EXIT_CODE}"
OUTPUT="$(nvm_remote_versions node)"
EXIT_CODE="$(nvm_remote_versions node >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_$(nvm_ls_remote)" ] \
|| die "nvm_remote_versions node did not return contents of nvm_ls_remote; got $OUTPUT"
[ "_$EXIT_CODE" = "_0" ] || die "nvm_remote_versions node did not exit with 0, got $EXIT_CODE"
[ "_${OUTPUT}" = "_$(nvm_ls_remote)" ] \
|| die "nvm_remote_versions node did not return contents of nvm_ls_remote; got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_0' ] || die "nvm_remote_versions node did not exit with 0, got ${EXIT_CODE}"
OUTPUT="$(nvm_remote_versions iojs-foo)"
EXIT_CODE="$(nvm_remote_versions iojs-foo >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_$(nvm_ls_remote iojs-foo)
[ "_${OUTPUT}" = "_$(nvm_ls_remote iojs-foo)
$(nvm_ls_remote_iojs iojs-foo)" ] \
|| die "nvm_remote_versions iojs-foo did not return contents of nvm_ls_remote iojs-foo combined with nvm_ls_remote_iojs iojs-foo; got $OUTPUT"
[ "_$EXIT_CODE" = "_0" ] || die "nvm_remote_versions iojs-foo did not exit with 0, got $EXIT_CODE"
|| die "nvm_remote_versions iojs-foo did not return contents of nvm_ls_remote iojs-foo combined with nvm_ls_remote_iojs iojs-foo; got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_0' ] || die "nvm_remote_versions iojs-foo did not exit with 0, got ${EXIT_CODE}"
OUTPUT="$(nvm_remote_versions iojs)"
EXIT_CODE="$(nvm_remote_versions iojs >/dev/null 2>&1 ; echo $?)"
[ "_$OUTPUT" = "_$(nvm_ls_remote_iojs)" ] \
|| die "nvm_remote_versions iojs did not return contents of nvm_ls_remote_iojs; got $OUTPUT"
[ "_$EXIT_CODE" = "_0" ] || die "nvm_remote_versions iojs did not exit with 0, got $EXIT_CODE"
[ "_${OUTPUT}" = "_$(nvm_ls_remote_iojs)" ] \
|| die "nvm_remote_versions iojs did not return contents of nvm_ls_remote_iojs; got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_0' ] || die "nvm_remote_versions iojs did not exit with 0, got ${EXIT_CODE}"
OUTPUT="$(NVM_IOJS_ORG_MIRROR= nvm_remote_versions)"
EXIT_CODE="$(nvm_remote_versions iojs >/dev/null 2>&1 ; echo $?)"
[ "_${OUTPUT}" = "_$(nvm_ls_remote_node)" ] \
|| die "NVM_IOJS_ORG_MIRROR= nvm_remote_versions did not return contents of nvm_ls_remote_node; got ${OUTPUT}"
[ "_${EXIT_CODE}" = '_0' ] || die "nvm_ls_remote_node= nvm_remote_versions did not exit with 0, got ${EXIT_CODE}"
cleanup

1
test/fixtures/nvmrc vendored Submodule

Submodule test/fixtures/nvmrc added at 0d325aa903