mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-09-27 00:00:07 +08:00
Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a8b51c46c | ||
|
|
ebada63259 | ||
|
|
0a9dead76d | ||
|
|
304a22ad59 | ||
|
|
d22bf7f538 | ||
|
|
dd61ae4bc8 | ||
|
|
59cf9a4ef6 | ||
|
|
21d33ef04a | ||
|
|
82315e2b18 | ||
|
|
ab77712867 | ||
|
|
0c1243a7ea | ||
|
|
9142a92cdc | ||
|
|
04fef13bdc | ||
|
|
cb0e0ba8ed | ||
|
|
b16fb6ece9 | ||
|
|
190cb9458b | ||
|
|
e2e612e722 | ||
|
|
041a57747a | ||
|
|
419ff4efec | ||
|
|
7a7908ffa1 | ||
|
|
ce15734300 | ||
|
|
ee4fa818d2 | ||
|
|
a6ec739430 | ||
|
|
718e880890 | ||
|
|
ed4dbdfdd5 | ||
|
|
a9933f77a6 | ||
|
|
7079a5d61c | ||
|
|
306f04a90a | ||
|
|
77fca77ddd |
@@ -7,7 +7,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
version:
|
version:
|
||||||
description: 'nvm version tag (e.g., v0.40.4). Defaults to latest release.'
|
description: 'nvm version tag (e.g., v0.40.4). Defaults to the latest version tag.'
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ''
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
update-nodejs-org:
|
update-nodejs-org:
|
||||||
if: github.repository == 'nvm-sh/nvm' && github.actor == 'ljharb'
|
if: github.repository == 'nvm-sh/nvm' && github.actor == 'ljharb'
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: read # for the "Extract and validate version" step's `gh api .../tags` call via the default github.token
|
||||||
name: 'Create PR to nodejs/nodejs.org'
|
name: 'Create PR to nodejs/nodejs.org'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -41,7 +41,8 @@ jobs:
|
|||||||
elif [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
elif [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
||||||
TAG="${GITHUB_REF#refs/tags/}"
|
TAG="${GITHUB_REF#refs/tags/}"
|
||||||
else
|
else
|
||||||
TAG="$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" --jq '.tag_name')"
|
TAG="$(gh api --paginate "repos/${GITHUB_REPOSITORY}/tags" --jq '.[].name' \
|
||||||
|
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! printf '%s\n' "${TAG}" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
if ! printf '%s\n' "${TAG}" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||||
@@ -65,16 +66,19 @@ jobs:
|
|||||||
FORK_OWNER="$(gh api user --jq '.login')"
|
FORK_OWNER="$(gh api user --jq '.login')"
|
||||||
|
|
||||||
DEFAULT_BRANCH="$(gh api repos/nodejs/nodejs.org --jq '.default_branch')"
|
DEFAULT_BRANCH="$(gh api repos/nodejs/nodejs.org --jq '.default_branch')"
|
||||||
|
|
||||||
|
gh repo sync "${FORK_OWNER}/nodejs.org" --branch "${DEFAULT_BRANCH}" || true
|
||||||
|
|
||||||
UPSTREAM_SHA="$(gh api "repos/nodejs/nodejs.org/git/ref/heads/${DEFAULT_BRANCH}" --jq '.object.sha')"
|
UPSTREAM_SHA="$(gh api "repos/nodejs/nodejs.org/git/ref/heads/${DEFAULT_BRANCH}" --jq '.object.sha')"
|
||||||
|
|
||||||
# Create or reset branch on fork to upstream HEAD
|
# Create or reset branch on fork to upstream HEAD
|
||||||
if ! gh api "repos/${FORK_OWNER}/nodejs.org/git/refs" \
|
if ! gh api "repos/${FORK_OWNER}/nodejs.org/git/refs" \
|
||||||
-f "ref=refs/heads/${BRANCH}" \
|
-f "ref=refs/heads/${BRANCH}" \
|
||||||
-f "sha=${UPSTREAM_SHA}" > /dev/null 2>&1; then
|
-f "sha=${UPSTREAM_SHA}" > /dev/null; then
|
||||||
gh api "repos/${FORK_OWNER}/nodejs.org/git/refs/heads/${BRANCH}" \
|
gh api "repos/${FORK_OWNER}/nodejs.org/git/refs/heads/${BRANCH}" \
|
||||||
-X PATCH \
|
-X PATCH \
|
||||||
-f "sha=${UPSTREAM_SHA}" \
|
-f "sha=${UPSTREAM_SHA}" \
|
||||||
-f "force=true" > /dev/null
|
-F "force=true" > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf 'fork_owner=%s\n' "${FORK_OWNER}" >> "${GITHUB_OUTPUT}"
|
printf 'fork_owner=%s\n' "${FORK_OWNER}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
needs: [matrix]
|
needs: [matrix]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
continue-on-error: ${{ matrix.ref == 'v0.40.0' }} # https://github.com/nvm-sh/nvm/issues/3405
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -81,12 +80,19 @@ jobs:
|
|||||||
set -e
|
set -e
|
||||||
export NVM_INSTALL_VERSION="${ref}"
|
export NVM_INSTALL_VERSION="${ref}"
|
||||||
curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/${ref}/install.sh" | bash
|
curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/${ref}/install.sh" | bash
|
||||||
|
# v0.40.0 with an .nvmrc present is expected to fail (https://github.com/nvm-sh/nvm/issues/3405):
|
||||||
|
# the steps below tolerate failure for that combination, and the final step
|
||||||
|
# turns the job red only if the expected failure did NOT happen.
|
||||||
- name: nvm --version
|
- name: nvm --version
|
||||||
|
id: nvm-version
|
||||||
|
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||||
run: |
|
run: |
|
||||||
set +e
|
set +e
|
||||||
. $NVM_DIR/nvm.sh && nvm --version
|
. $NVM_DIR/nvm.sh && nvm --version
|
||||||
- name: nvm install in 1 shell level, ${{ matrix.has-nvmrc }}
|
- name: nvm install in 1 shell level, ${{ matrix.has-nvmrc }}
|
||||||
|
id: install-1
|
||||||
if: ${{ matrix.shell-level == '1 shlvl' }}
|
if: ${{ matrix.shell-level == '1 shlvl' }}
|
||||||
|
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||||
run: |
|
run: |
|
||||||
set -ex
|
set -ex
|
||||||
. $NVM_DIR/nvm.sh
|
. $NVM_DIR/nvm.sh
|
||||||
@@ -96,13 +102,29 @@ jobs:
|
|||||||
nvm install
|
nvm install
|
||||||
fi
|
fi
|
||||||
- name: nvm install in 2 shell levels, ${{ matrix.has-nvmrc }}
|
- name: nvm install in 2 shell levels, ${{ matrix.has-nvmrc }}
|
||||||
|
id: install-2
|
||||||
if: ${{ matrix.shell-level == '2 shlvls' }}
|
if: ${{ matrix.shell-level == '2 shlvls' }}
|
||||||
|
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||||
run: |
|
run: |
|
||||||
if [ '${{ matrix.has-nvmrc }}' == 'nvmrc' ]; then
|
if [ '${{ matrix.has-nvmrc }}' == 'nvmrc' ]; then
|
||||||
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version && nvm install"
|
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version && nvm install"
|
||||||
else
|
else
|
||||||
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version"
|
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version"
|
||||||
fi
|
fi
|
||||||
|
- name: 'confirm the expected failure happened (v0.40.0 + nvmrc)'
|
||||||
|
if: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||||
|
env:
|
||||||
|
SOURCE_OUTCOME: ${{ steps.nvm-version.outcome }}
|
||||||
|
INSTALL_1_OUTCOME: ${{ steps.install-1.outcome }}
|
||||||
|
INSTALL_2_OUTCOME: ${{ steps.install-2.outcome }}
|
||||||
|
run: |
|
||||||
|
echo "nvm --version: ${SOURCE_OUTCOME}; install (1 shlvl): ${INSTALL_1_OUTCOME}; install (2 shlvls): ${INSTALL_2_OUTCOME}"
|
||||||
|
if [ "${SOURCE_OUTCOME}" = 'failure' ] || [ "${INSTALL_1_OUTCOME}" = 'failure' ] || [ "${INSTALL_2_OUTCOME}" = 'failure' ]; then
|
||||||
|
echo 'v0.40.0 failed as expected: https://github.com/nvm-sh/nvm/issues/3405'
|
||||||
|
else
|
||||||
|
echo '::error::v0.40.0 with an .nvmrc was expected to fail (https://github.com/nvm-sh/nvm/issues/3405), but every step succeeded. If v0.40.0 somehow works now, remove the expected-failure handling from this workflow.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
finisher:
|
finisher:
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
@@ -2,16 +2,12 @@ name: Automatic Rebase
|
|||||||
|
|
||||||
on: [pull_request_target]
|
on: [pull_request_target]
|
||||||
|
|
||||||
permissions: read-all
|
permissions:
|
||||||
|
contents: write # for ljharb/rebase to push code to rebase
|
||||||
|
pull-requests: read # for ljharb/rebase to get info about PR
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
_:
|
_:
|
||||||
name: "Automatic Rebase"
|
uses: ljharb/actions/.github/workflows/rebase.yml@main
|
||||||
|
secrets:
|
||||||
runs-on: ubuntu-latest
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
- uses: ljharb/rebase@master
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ name: Require “Allow Edits”
|
|||||||
|
|
||||||
on: [pull_request_target]
|
on: [pull_request_target]
|
||||||
|
|
||||||
permissions: read-all
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
_:
|
_:
|
||||||
|
permissions:
|
||||||
|
pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR
|
||||||
|
|
||||||
name: "Require “Allow Edits”"
|
name: "Require “Allow Edits”"
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -47,8 +47,17 @@ jobs:
|
|||||||
production.cloudflare.docker.com:443
|
production.cloudflare.docker.com:443
|
||||||
production.cloudfront.docker.com:443
|
production.cloudfront.docker.com:443
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
id: checkout
|
||||||
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: 'nvmrc submodule fallback (forks without their own nvmrc)'
|
||||||
|
if: steps.checkout.outcome == 'failure'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git submodule set-url test/fixtures/nvmrc https://github.com/nvm-sh/nvmrc.git
|
||||||
|
git submodule sync --recursive
|
||||||
|
git submodule update --init --recursive
|
||||||
- name: Install zsh, additional shells, and awk variant
|
- name: Install zsh, additional shells, and awk variant
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
|
|||||||
@@ -39,8 +39,17 @@ jobs:
|
|||||||
azure.archive.ubuntu.com:80
|
azure.archive.ubuntu.com:80
|
||||||
packages.microsoft.com:443
|
packages.microsoft.com:443
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
id: checkout
|
||||||
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: 'nvmrc submodule fallback (forks without their own nvmrc)'
|
||||||
|
if: steps.checkout.outcome == 'failure'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git submodule set-url test/fixtures/nvmrc https://github.com/nvm-sh/nvmrc.git
|
||||||
|
git submodule sync --recursive
|
||||||
|
git submodule update --init --recursive
|
||||||
- name: Install zsh and additional shells
|
- name: Install zsh and additional shells
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
|
|||||||
@@ -45,8 +45,17 @@ jobs:
|
|||||||
registry-1.docker.io:443
|
registry-1.docker.io:443
|
||||||
auth.docker.io:443
|
auth.docker.io:443
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
id: checkout
|
||||||
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: 'nvmrc submodule fallback (forks without their own nvmrc)'
|
||||||
|
if: steps.checkout.outcome == 'failure'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git submodule set-url test/fixtures/nvmrc https://github.com/nvm-sh/nvmrc.git
|
||||||
|
git submodule sync --recursive
|
||||||
|
git submodule update --init --recursive
|
||||||
- uses: ljharb/actions/node/install@main
|
- uses: ljharb/actions/node/install@main
|
||||||
name: 'npm install && version checks'
|
name: 'npm install && version checks'
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -42,8 +42,17 @@ jobs:
|
|||||||
registry-1.docker.io:443
|
registry-1.docker.io:443
|
||||||
auth.docker.io:443
|
auth.docker.io:443
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
id: checkout
|
||||||
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: 'nvmrc submodule fallback (forks without their own nvmrc)'
|
||||||
|
if: steps.checkout.outcome == 'failure'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git submodule set-url test/fixtures/nvmrc https://github.com/nvm-sh/nvmrc.git
|
||||||
|
git submodule sync --recursive
|
||||||
|
git submodule update --init --recursive
|
||||||
- uses: ljharb/actions/node/install@main
|
- uses: ljharb/actions/node/install@main
|
||||||
name: 'npm install && version checks'
|
name: 'npm install && version checks'
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: read # for actions/checkout@v6
|
||||||
|
|
||||||
name: "tests"
|
name: "tests"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ jobs:
|
|||||||
bash.exe "%USERPROFILE%\setup.sh"
|
bash.exe "%USERPROFILE%\setup.sh"
|
||||||
|
|
||||||
wsl_matrix:
|
wsl_matrix:
|
||||||
|
permissions:
|
||||||
|
contents: none
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
name: 'WSL nvm install'
|
name: 'WSL nvm install'
|
||||||
defaults:
|
defaults:
|
||||||
@@ -187,6 +189,8 @@ jobs:
|
|||||||
node -v
|
node -v
|
||||||
|
|
||||||
wsl_matrix_unofficial:
|
wsl_matrix_unofficial:
|
||||||
|
permissions:
|
||||||
|
contents: none
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
name: 'WSL nvm install'
|
name: 'WSL nvm install'
|
||||||
defaults:
|
defaults:
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
- [Usage](#usage)
|
- [Usage](#usage)
|
||||||
- [Long-term Support](#long-term-support)
|
- [Long-term Support](#long-term-support)
|
||||||
- [Migrating Global Packages While Installing](#migrating-global-packages-while-installing)
|
- [Migrating Global Packages While Installing](#migrating-global-packages-while-installing)
|
||||||
|
- [Migrating Global Packages Between Installed Versions](#migrating-global-packages-between-installed-versions)
|
||||||
- [Offline Install](#offline-install)
|
- [Offline Install](#offline-install)
|
||||||
- [Default Global Packages From File While Installing](#default-global-packages-from-file-while-installing)
|
- [Default Global Packages From File While Installing](#default-global-packages-from-file-while-installing)
|
||||||
- [io.js](#iojs)
|
- [io.js](#iojs)
|
||||||
@@ -429,6 +430,7 @@ In place of a version pointer like "14.7" or "16.3" or "12.22.1", you can use th
|
|||||||
- `iojs`: this installs the latest version of [`io.js`](https://iojs.org/en/)
|
- `iojs`: this installs the latest version of [`io.js`](https://iojs.org/en/)
|
||||||
- `stable`: this alias is deprecated, and only truly applies to `node` `v0.12` and earlier. Currently, this is an alias for `node`.
|
- `stable`: this alias is deprecated, and only truly applies to `node` `v0.12` and earlier. Currently, this is an alias for `node`.
|
||||||
- `unstable`: this alias points to `node` `v0.11` - the last "unstable" node release, since post-1.0, all node versions are stable. (in SemVer, versions communicate breakage, not stability).
|
- `unstable`: this alias points to `node` `v0.11` - the last "unstable" node release, since post-1.0, all node versions are stable. (in SemVer, versions communicate breakage, not stability).
|
||||||
|
- `current`: the version currently active in this shell (i.e. what `node` resolves to via `$PATH`). It is **not** affected by `.nvmrc`. Useful when you want to refer to the active version explicitly — e.g. `nvm which current` always prints the path to the active `node`, regardless of whether an `.nvmrc` file is present.
|
||||||
|
|
||||||
### Long-term Support
|
### Long-term Support
|
||||||
|
|
||||||
@@ -482,6 +484,17 @@ nvm install-latest-npm
|
|||||||
|
|
||||||
If you've already gotten an error to the effect of "npm does not support Node.js", you'll need to (1) revert to a previous node version (`nvm ls` & `nvm use <your latest _working_ version from the ls>`), (2) delete the newly created node version (`nvm uninstall <your _broken_ version of node from the ls>`), then (3) rerun your `nvm install` with the `--latest-npm` flag.
|
If you've already gotten an error to the effect of "npm does not support Node.js", you'll need to (1) revert to a previous node version (`nvm ls` & `nvm use <your latest _working_ version from the ls>`), (2) delete the newly created node version (`nvm uninstall <your _broken_ version of node from the ls>`), then (3) rerun your `nvm install` with the `--latest-npm` flag.
|
||||||
|
|
||||||
|
### Migrating Global Packages Between Installed Versions
|
||||||
|
|
||||||
|
`--reinstall-packages-from` is tied to `nvm install`. To migrate global npm packages between versions you _already_ have installed, without (re)installing anything, `nvm use` the destination and run `nvm reinstall-packages` as a standalone command, pointing at the version you want to copy _from_:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nvm use 22.22.2
|
||||||
|
nvm reinstall-packages 22.20.0
|
||||||
|
```
|
||||||
|
|
||||||
|
This reinstalls all global packages from `22.20.0` into the currently-active version (`22.22.2`). As with `--reinstall-packages-from`, the npm version itself is not changed.
|
||||||
|
|
||||||
|
|
||||||
### Offline Install
|
### Offline Install
|
||||||
|
|
||||||
@@ -645,7 +658,7 @@ NVM_AUTH_HEADER="Bearer secret-token" nvm install node
|
|||||||
### .nvmrc
|
### .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).
|
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).
|
||||||
Afterwards, `nvm use`, `nvm install`, `nvm exec`, `nvm run`, and `nvm which` will use the version specified in the `.nvmrc` file if no version is supplied on the command line.
|
Afterwards, `nvm use`, `nvm install`, and `nvm which` will use the version specified in the `.nvmrc` file if no version is supplied on the command line; if no `.nvmrc` is found either, they exit with status `127`. (`nvm exec` and `nvm run` follow the same `.nvmrc` lookup, but currently fall back to the active node if neither resolves — treat that fallback as undefined behavior; pass an explicit version if you need predictable scripting.) If you want the currently active version, pass `current` explicitly (e.g. `nvm which current`) — `current` is not affected by `.nvmrc`.
|
||||||
|
|
||||||
For example, to make nvm default to the latest 5.9 release, the latest LTS version, or the latest node version for the current directory:
|
For example, to make nvm default to the latest 5.9 release, the latest LTS version, or the latest node version for the current directory:
|
||||||
|
|
||||||
@@ -985,13 +998,13 @@ export NVM_DIR="$HOME/.nvm"
|
|||||||
|
|
||||||
## Docker For Development Environment
|
## Docker For Development Environment
|
||||||
|
|
||||||
To make the development and testing work easier, we have a Dockerfile for development usage, which is based on Ubuntu 18.04 base image, prepared with essential and useful tools for `nvm` development, to build the docker image of the environment, run the docker command at the root of `nvm` repository:
|
To make development and testing work easier we supply a Dockerfile for development usage. It's based on an Ubuntu base image prepared with essential and useful tools for `nvm` development. To build the docker image of the environment, do a Docker build at the root of `nvm` repository:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ docker build -t nvm-dev .
|
$ docker build -t nvm-dev .
|
||||||
```
|
```
|
||||||
|
|
||||||
This will package your current nvm repository with our pre-defined development environment into a docker image named `nvm-dev`, once it's built with success, validate your image via `docker images`:
|
This will package your current nvm working copy with our pre-defined development environment into a Docker image named `nvm-dev`. After the build you should see it appear in the list of images:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ docker images
|
$ docker images
|
||||||
@@ -1000,7 +1013,7 @@ REPOSITORY TAG IMAGE ID CREATED S
|
|||||||
nvm-dev latest 9ca4c57a97d8 7 days ago 650 MB
|
nvm-dev latest 9ca4c57a97d8 7 days ago 650 MB
|
||||||
```
|
```
|
||||||
|
|
||||||
If you got no error message, now you can easily involve in:
|
To start and enter a container based on this image:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ docker run -h nvm-dev -it nvm-dev
|
$ docker run -h nvm-dev -it nvm-dev
|
||||||
@@ -1008,12 +1021,9 @@ $ docker run -h nvm-dev -it nvm-dev
|
|||||||
nvm@nvm-dev:~/.nvm$
|
nvm@nvm-dev:~/.nvm$
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note that it'll take about 8 minutes to build the image and the image size would be about 650MB, so it's not suitable for production usage.
|
It takes several minutes to build the image and the image size is about 650MB, so it's not suitable for production usage.
|
||||||
|
|
||||||
For more information and documentation about docker, please refer to its official website:
|
For more information and documentation about Docker, please refer to its [official website][docker-www] and [documentation][docker-docs]:
|
||||||
|
|
||||||
- https://www.docker.com/
|
|
||||||
- https://docs.docker.com/
|
|
||||||
|
|
||||||
## Problems
|
## Problems
|
||||||
|
|
||||||
@@ -1192,3 +1202,7 @@ See [LICENSE.md](./LICENSE.md).
|
|||||||
|
|
||||||
Copyright [OpenJS Foundation](https://openjsf.org) and `nvm` contributors. All rights reserved. The [OpenJS Foundation](https://openjsf.org) has registered trademarks and uses trademarks. For a list of trademarks of the [OpenJS Foundation](https://openjsf.org), please see our [Trademark Policy](https://trademark-policy.openjsf.org/) and [Trademark List](https://trademark-list.openjsf.org/). Trademarks and logos not indicated on the [list of OpenJS Foundation trademarks](https://trademark-list.openjsf.org) are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
|
Copyright [OpenJS Foundation](https://openjsf.org) and `nvm` contributors. All rights reserved. The [OpenJS Foundation](https://openjsf.org) has registered trademarks and uses trademarks. For a list of trademarks of the [OpenJS Foundation](https://openjsf.org), please see our [Trademark Policy](https://trademark-policy.openjsf.org/) and [Trademark List](https://trademark-list.openjsf.org/). Trademarks and logos not indicated on the [list of OpenJS Foundation trademarks](https://trademark-list.openjsf.org) are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
|
||||||
[The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [Bylaws](https://bylaws.openjsf.org/) | [Code of Conduct](https://code-of-conduct.openjsf.org) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)
|
[The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [Bylaws](https://bylaws.openjsf.org/) | [Code of Conduct](https://code-of-conduct.openjsf.org) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)
|
||||||
|
|
||||||
|
<!-------------------------------------------------------------------->
|
||||||
|
[docker-docs]: https://docs.docker.com/
|
||||||
|
[docker-www]: https://www.docker.com/
|
||||||
|
|||||||
+19
-7
@@ -6,6 +6,18 @@ nvm_has() {
|
|||||||
type "$1" > /dev/null 2>&1
|
type "$1" > /dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# resolves like `command "${1}"` does: only executables on the PATH,
|
||||||
|
# ignoring shell functions and aliases
|
||||||
|
nvm_has_executable() {
|
||||||
|
(
|
||||||
|
# `|| true` so that shells with errexit-style options (eg, zsh's ERR_RETURN)
|
||||||
|
# do not abort the subshell when the name is not an alias or a function
|
||||||
|
unalias "${1-}" 2>/dev/null || true
|
||||||
|
unset -f "${1-}" 2>/dev/null || true
|
||||||
|
command -v "${1-}" > /dev/null 2>&1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
nvm_echo() {
|
nvm_echo() {
|
||||||
command printf %s\\n "$*" 2>/dev/null
|
command printf %s\\n "$*" 2>/dev/null
|
||||||
}
|
}
|
||||||
@@ -105,9 +117,9 @@ nvm_node_version() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nvm_download() {
|
nvm_download() {
|
||||||
if nvm_has "curl"; then
|
if nvm_has_executable "curl"; then
|
||||||
curl --fail --compressed -q "$@"
|
command curl --fail --compressed -q "$@"
|
||||||
elif nvm_has "wget"; then
|
elif nvm_has_executable "wget"; then
|
||||||
# Emulate curl with wget
|
# Emulate curl with wget
|
||||||
ARGS=$(nvm_echo "$@" | command sed -e 's/--progress-bar /--progress=bar /' \
|
ARGS=$(nvm_echo "$@" | command sed -e 's/--progress-bar /--progress=bar /' \
|
||||||
-e 's/--compressed //' \
|
-e 's/--compressed //' \
|
||||||
@@ -119,7 +131,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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +413,7 @@ nvm_do_install() {
|
|||||||
# Autodetect install method
|
# Autodetect install method
|
||||||
if nvm_has git; then
|
if nvm_has git; then
|
||||||
install_nvm_from_git
|
install_nvm_from_git
|
||||||
elif nvm_has curl || nvm_has wget; then
|
elif nvm_has_executable curl || nvm_has_executable wget; then
|
||||||
install_nvm_as_script
|
install_nvm_as_script
|
||||||
else
|
else
|
||||||
nvm_echo >&2 'You need git, curl, or wget to install nvm'
|
nvm_echo >&2 'You need git, curl, or wget to install nvm'
|
||||||
@@ -414,7 +426,7 @@ nvm_do_install() {
|
|||||||
fi
|
fi
|
||||||
install_nvm_from_git
|
install_nvm_from_git
|
||||||
elif [ "${METHOD}" = 'script' ]; then
|
elif [ "${METHOD}" = 'script' ]; then
|
||||||
if ! nvm_has curl && ! nvm_has wget; then
|
if ! nvm_has_executable curl && ! nvm_has_executable wget; then
|
||||||
nvm_echo >&2 "You need curl or wget to install nvm"
|
nvm_echo >&2 "You need curl or wget to install nvm"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -496,7 +508,7 @@ nvm_do_install() {
|
|||||||
# during the execution of the install script
|
# during the execution of the install script
|
||||||
#
|
#
|
||||||
nvm_reset() {
|
nvm_reset() {
|
||||||
unset -f nvm_has nvm_install_dir nvm_latest_version nvm_profile_is_bash_or_zsh \
|
unset -f nvm_has nvm_has_executable nvm_install_dir nvm_latest_version nvm_profile_is_bash_or_zsh \
|
||||||
nvm_source nvm_node_version nvm_download install_nvm_from_git nvm_install_node \
|
nvm_source nvm_node_version nvm_download install_nvm_from_git nvm_install_node \
|
||||||
install_nvm_as_script nvm_try_profile nvm_detect_profile nvm_check_global_modules \
|
install_nvm_as_script nvm_try_profile nvm_detect_profile nvm_check_global_modules \
|
||||||
nvm_do_install nvm_reset nvm_default_install_dir nvm_grep
|
nvm_do_install nvm_reset nvm_default_install_dir nvm_grep
|
||||||
|
|||||||
@@ -49,6 +49,18 @@ nvm_has() {
|
|||||||
type "${1-}" >/dev/null 2>&1
|
type "${1-}" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# resolves like `command "${1}"` does: only executables on the PATH,
|
||||||
|
# ignoring shell functions and aliases
|
||||||
|
nvm_has_executable() {
|
||||||
|
(
|
||||||
|
# `|| true` so that shells with errexit-style options (eg, zsh's ERR_RETURN)
|
||||||
|
# do not abort the subshell when the name is not an alias or a function
|
||||||
|
unalias "${1-}" 2>/dev/null || true
|
||||||
|
unset -f "${1-}" 2>/dev/null || true
|
||||||
|
command -v "${1-}" >/dev/null 2>&1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
nvm_has_non_aliased() {
|
nvm_has_non_aliased() {
|
||||||
nvm_has "${1-}" && ! nvm_is_alias "${1-}"
|
nvm_has "${1-}" && ! nvm_is_alias "${1-}"
|
||||||
}
|
}
|
||||||
@@ -87,7 +99,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() {
|
||||||
@@ -97,13 +109,13 @@ nvm_curl_use_compression() {
|
|||||||
nvm_get_latest() {
|
nvm_get_latest() {
|
||||||
local NVM_LATEST_URL
|
local NVM_LATEST_URL
|
||||||
local CURL_COMPRESSED_FLAG
|
local CURL_COMPRESSED_FLAG
|
||||||
if nvm_has "curl"; then
|
if nvm_has_executable "curl"; then
|
||||||
if nvm_curl_use_compression; then
|
if nvm_curl_use_compression; then
|
||||||
CURL_COMPRESSED_FLAG="--compressed"
|
CURL_COMPRESSED_FLAG="--compressed"
|
||||||
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="$(command 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_executable "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
|
||||||
@@ -127,13 +139,13 @@ nvm_download() {
|
|||||||
|
|
||||||
local NVM_DOWNLOADER
|
local NVM_DOWNLOADER
|
||||||
NVM_DOWNLOADER=''
|
NVM_DOWNLOADER=''
|
||||||
if nvm_has "curl"; then
|
if nvm_has_executable "curl"; then
|
||||||
NVM_DOWNLOADER='curl'
|
NVM_DOWNLOADER='curl'
|
||||||
set -- -q --fail "$@"
|
set -- -q --fail "$@"
|
||||||
if nvm_curl_use_compression; then
|
if nvm_curl_use_compression; then
|
||||||
set -- --compressed "$@"
|
set -- --compressed "$@"
|
||||||
fi
|
fi
|
||||||
elif nvm_has "wget"; then
|
elif nvm_has_executable "wget"; then
|
||||||
NVM_DOWNLOADER='wget'
|
NVM_DOWNLOADER='wget'
|
||||||
# Emulate curl with wget
|
# Emulate curl with wget
|
||||||
local NVM_DOWNLOAD_WGET_COUNT
|
local NVM_DOWNLOAD_WGET_COUNT
|
||||||
@@ -170,12 +182,17 @@ 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() {
|
||||||
# Remove potentially dangerous characters
|
# Remove potentially dangerous characters; allow the full base64 (A-Za-z0-9+/=)
|
||||||
nvm_echo "$1" | command sed 's/[^a-zA-Z0-9:;_. -]//g'
|
# and base64url (A-Za-z0-9-_=) charsets, plus the space, colon, dot, and
|
||||||
|
# underscore the previous allowlist already permitted, so that values like
|
||||||
|
# `Basic <base64>` and `Bearer <token>` survive intact.
|
||||||
|
# token68's '~' is still stripped.
|
||||||
|
# Note: '-' must be at the end of the bracket expression to be treated as a literal.
|
||||||
|
nvm_echo "$1" | command sed 's/[^a-zA-Z0-9 :_.+/=-]//g'
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_has_system_node() {
|
nvm_has_system_node() {
|
||||||
@@ -548,12 +565,12 @@ ${1}"
|
|||||||
$(nvm_wrap_with_color_code 'y' "${warn_text}")"
|
$(nvm_wrap_with_color_code 'y' "${warn_text}")"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_process_nvmrc() {
|
nvm_process_nvmrc_content() {
|
||||||
local NVMRC_PATH
|
local NVMRC_CONTENT
|
||||||
NVMRC_PATH="$1"
|
NVMRC_CONTENT="${1-}"
|
||||||
local lines
|
local lines
|
||||||
|
|
||||||
lines=$(command sed 's/#.*//' "$NVMRC_PATH" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | nvm_grep -v '^$')
|
lines=$(nvm_echo "${NVMRC_CONTENT}" | command sed 's/#.*//' | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | nvm_grep -v '^$')
|
||||||
|
|
||||||
if [ -z "$lines" ]; then
|
if [ -z "$lines" ]; then
|
||||||
nvm_nvmrc_invalid_msg "${lines}"
|
nvm_nvmrc_invalid_msg "${lines}"
|
||||||
@@ -617,12 +634,19 @@ EOF
|
|||||||
nvm_echo "${unpaired_line}"
|
nvm_echo "${unpaired_line}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvm_process_nvmrc() {
|
||||||
|
local NVMRC_PATH
|
||||||
|
NVMRC_PATH="$1"
|
||||||
|
|
||||||
|
nvm_process_nvmrc_content "$(command cat "${NVMRC_PATH}")"
|
||||||
|
}
|
||||||
|
|
||||||
nvm_rc_version() {
|
nvm_rc_version() {
|
||||||
local NVMRC_PATH
|
local NVMRC_PATH
|
||||||
NVMRC_PATH="$(nvm_find_nvmrc)"
|
NVMRC_PATH="$(nvm_find_nvmrc)"
|
||||||
if [ ! -e "${NVMRC_PATH}" ]; then
|
if [ ! -e "${NVMRC_PATH}" ]; then
|
||||||
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
|
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
|
||||||
nvm_err "No .nvmrc file found"
|
nvm_err "No version provided and no .nvmrc file found"
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -649,7 +673,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() {
|
||||||
@@ -1343,7 +1367,24 @@ nvm_alias() {
|
|||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
command sed 's/#.*//; s/[[:space:]]*$//' "${NVM_ALIAS_PATH}" | command awk 'NF'
|
if [ ! -r "${NVM_ALIAS_PATH}" ]; then
|
||||||
|
# an existing-but-unreadable alias file yields empty output with a success
|
||||||
|
# status - a nonzero status here would make `nvm_ensure_default_set`
|
||||||
|
# overwrite an existing default alias it merely could not read
|
||||||
|
nvm_err "Alias file is not readable: ${NVM_ALIAS_PATH}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local NVM_ALIAS_LINE
|
||||||
|
while IFS= read -r NVM_ALIAS_LINE || [ -n "${NVM_ALIAS_LINE}" ]; do
|
||||||
|
NVM_ALIAS_LINE="${NVM_ALIAS_LINE%%#*}"
|
||||||
|
case "${NVM_ALIAS_LINE}" in
|
||||||
|
*[![:space:]]*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
NVM_ALIAS_LINE="${NVM_ALIAS_LINE%"${NVM_ALIAS_LINE##*[![:space:]]}"}"
|
||||||
|
nvm_echo "${NVM_ALIAS_LINE}"
|
||||||
|
done < "${NVM_ALIAS_PATH}"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_ls_current() {
|
nvm_ls_current() {
|
||||||
@@ -1376,24 +1417,32 @@ nvm_resolve_alias() {
|
|||||||
local ALIAS
|
local ALIAS
|
||||||
ALIAS="${PATTERN}"
|
ALIAS="${PATTERN}"
|
||||||
local ALIAS_TEMP
|
local ALIAS_TEMP
|
||||||
|
local ALIAS_OUTPUT
|
||||||
|
|
||||||
local SEEN_ALIASES
|
local SEEN_ALIASES
|
||||||
SEEN_ALIASES="${ALIAS}"
|
SEEN_ALIASES="
|
||||||
local NVM_ALIAS_INDEX
|
${ALIAS}
|
||||||
NVM_ALIAS_INDEX=1
|
"
|
||||||
while true; do
|
while true; do
|
||||||
ALIAS_TEMP="$( (nvm_alias "${ALIAS}" 2>/dev/null | command head -n "${NVM_ALIAS_INDEX}" | command tail -n 1) || nvm_echo)"
|
ALIAS_OUTPUT="$(nvm_alias "${ALIAS}" 2>/dev/null)" || ALIAS_OUTPUT=''
|
||||||
|
ALIAS_TEMP="${ALIAS_OUTPUT%%
|
||||||
|
*}"
|
||||||
|
|
||||||
if [ -z "${ALIAS_TEMP}" ]; then
|
if [ -z "${ALIAS_TEMP}" ]; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if command printf '%b' "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then
|
case "${SEEN_ALIASES}" in
|
||||||
ALIAS="∞"
|
*"
|
||||||
break
|
${ALIAS_TEMP}
|
||||||
fi
|
"*)
|
||||||
|
ALIAS="∞"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
SEEN_ALIASES="${SEEN_ALIASES}\\n${ALIAS_TEMP}"
|
SEEN_ALIASES="${SEEN_ALIASES}${ALIAS_TEMP}
|
||||||
|
"
|
||||||
ALIAS="${ALIAS_TEMP}"
|
ALIAS="${ALIAS_TEMP}"
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -1474,6 +1523,17 @@ nvm_strip_iojs_prefix() {
|
|||||||
nvm_ls() {
|
nvm_ls() {
|
||||||
local PATTERN
|
local PATTERN
|
||||||
PATTERN="${1-}"
|
PATTERN="${1-}"
|
||||||
|
case "${PATTERN}" in
|
||||||
|
*'#'* | *'
|
||||||
|
'*)
|
||||||
|
local NVMRC_PATTERN
|
||||||
|
if ! NVMRC_PATTERN="$(nvm_process_nvmrc_content "${PATTERN}" 2>/dev/null)"; then
|
||||||
|
nvm_echo 'N/A'
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
PATTERN="${NVMRC_PATTERN}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
local VERSIONS
|
local VERSIONS
|
||||||
VERSIONS=''
|
VERSIONS=''
|
||||||
if [ "${PATTERN}" = 'current' ]; then
|
if [ "${PATTERN}" = 'current' ]; then
|
||||||
@@ -2171,6 +2231,7 @@ nvm_get_arch() {
|
|||||||
x86_64 | amd64) NVM_ARCH="x64" ;;
|
x86_64 | amd64) NVM_ARCH="x64" ;;
|
||||||
i*86) NVM_ARCH="x86" ;;
|
i*86) NVM_ARCH="x86" ;;
|
||||||
aarch64 | armv8l) NVM_ARCH="arm64" ;;
|
aarch64 | armv8l) NVM_ARCH="arm64" ;;
|
||||||
|
loongarch64) NVM_ARCH="loong64" ;;
|
||||||
*) NVM_ARCH="${HOST_ARCH}" ;;
|
*) NVM_ARCH="${HOST_ARCH}" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -2438,15 +2499,10 @@ nvm_get_download_slug() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If running MAC M1 :: Node v14.17.0 was the first version to offer official experimental support:
|
# If running MAC M1 :: ARM64 binaries are not available for Node < 16.0.0
|
||||||
# https://github.com/nodejs/node/issues/40126 (although binary distributions aren't available until v16)
|
# https://github.com/nodejs/node/issues/40126 (binary distributions aren't available until v16)
|
||||||
if \
|
if nvm_version_greater '16.0.0' "${VERSION}" && [ "_${NVM_OS}" = '_darwin' ] && [ "${NVM_ARCH}" = 'arm64' ]; then
|
||||||
nvm_version_greater '14.17.0' "${VERSION}" \
|
NVM_ARCH=x64
|
||||||
|| (nvm_version_greater_than_or_equal_to "${VERSION}" '15.0.0' && nvm_version_greater '16.0.0' "${VERSION}") \
|
|
||||||
; then
|
|
||||||
if [ "_${NVM_OS}" = '_darwin' ] && [ "${NVM_ARCH}" = 'arm64' ]; then
|
|
||||||
NVM_ARCH=x64
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${KIND}" = 'binary' ]; then
|
if [ "${KIND}" = 'binary' ]; then
|
||||||
@@ -3222,7 +3278,7 @@ nvm() {
|
|||||||
nvm_echo ' nvm --help Show this message'
|
nvm_echo ' nvm --help Show this message'
|
||||||
nvm_echo ' --no-colors Suppress colored output'
|
nvm_echo ' --no-colors Suppress colored output'
|
||||||
nvm_echo ' nvm --version Print out the installed version of nvm'
|
nvm_echo ' nvm --version Print out the installed version of nvm'
|
||||||
nvm_echo ' nvm install [<version>] Download and install a <version>. Uses .nvmrc if available and version is omitted.'
|
nvm_echo ' nvm install [<version>] Download and install a <version>. Uses .nvmrc if version is omitted; otherwise errors.'
|
||||||
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm install`:'
|
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm install`:'
|
||||||
nvm_echo ' -s Skip binary download, install from source only.'
|
nvm_echo ' -s Skip binary download, install from source only.'
|
||||||
nvm_echo ' -b Skip source download, install from binary only.'
|
nvm_echo ' -b Skip source download, install from binary only.'
|
||||||
@@ -3239,23 +3295,23 @@ nvm() {
|
|||||||
nvm_echo ' nvm uninstall <version> Uninstall a version'
|
nvm_echo ' nvm uninstall <version> Uninstall a version'
|
||||||
nvm_echo ' nvm uninstall --lts Uninstall using automatic LTS (long-term support) alias `lts/*`, if available.'
|
nvm_echo ' nvm uninstall --lts Uninstall using automatic LTS (long-term support) alias `lts/*`, if available.'
|
||||||
nvm_echo ' nvm uninstall --lts=<LTS name> Uninstall using automatic alias for provided LTS line, if available.'
|
nvm_echo ' nvm uninstall --lts=<LTS name> Uninstall using automatic alias for provided LTS line, if available.'
|
||||||
nvm_echo ' nvm use [<version>] Modify PATH to use <version>. Uses .nvmrc if available and version is omitted.'
|
nvm_echo ' nvm use [current | <version>] Modify PATH to use <version>. Uses .nvmrc if version is omitted; otherwise errors.'
|
||||||
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm use`:'
|
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm use`:'
|
||||||
nvm_echo ' --silent Silences stdout/stderr output'
|
nvm_echo ' --silent Silences stdout/stderr output'
|
||||||
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
||||||
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
||||||
nvm_echo ' --save Writes the specified version to .nvmrc.'
|
nvm_echo ' --save Writes the specified version to .nvmrc.'
|
||||||
nvm_echo ' nvm exec [<version>] [<command>] Run <command> on <version>. Uses .nvmrc if available and version is omitted.'
|
nvm_echo ' nvm exec [current | <version>] [<command>] Run <command> on <version>. Uses .nvmrc if version is omitted; otherwise errors.'
|
||||||
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm exec`:'
|
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm exec`:'
|
||||||
nvm_echo ' --silent Silences stdout/stderr output'
|
nvm_echo ' --silent Silences stdout/stderr output'
|
||||||
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
||||||
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
||||||
nvm_echo ' nvm run [<version>] [<args>] Run `node` on <version> with <args> as arguments. Uses .nvmrc if available and version is omitted.'
|
nvm_echo ' nvm run [current | <version>] [<args>] Run `node` on <version> with <args> as arguments. Uses .nvmrc if version is omitted; otherwise errors.'
|
||||||
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm run`:'
|
nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm run`:'
|
||||||
nvm_echo ' --silent Silences stdout/stderr output'
|
nvm_echo ' --silent Silences stdout/stderr output'
|
||||||
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'
|
||||||
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
nvm_echo ' --lts=<LTS name> Uses automatic alias for provided LTS line, if available.'
|
||||||
nvm_echo ' nvm current Display currently activated version of Node'
|
nvm_echo ' nvm current Display the active node version (resolved via $PATH; not affected by .nvmrc).'
|
||||||
nvm_echo ' nvm ls [<version>] List installed versions, matching a given <version> if provided'
|
nvm_echo ' nvm ls [<version>] List installed versions, matching a given <version> if provided'
|
||||||
nvm_echo ' --no-colors Suppress colored output'
|
nvm_echo ' --no-colors Suppress colored output'
|
||||||
nvm_echo ' --no-alias Suppress `nvm alias` output'
|
nvm_echo ' --no-alias Suppress `nvm alias` output'
|
||||||
@@ -3276,7 +3332,7 @@ nvm() {
|
|||||||
nvm_echo ' nvm install-latest-npm Attempt to upgrade to the latest working `npm` on the current node version'
|
nvm_echo ' nvm install-latest-npm Attempt to upgrade to the latest working `npm` on the current node version'
|
||||||
nvm_echo ' nvm reinstall-packages <version> Reinstall global `npm` packages contained in <version> to current version'
|
nvm_echo ' nvm reinstall-packages <version> Reinstall global `npm` packages contained in <version> to current version'
|
||||||
nvm_echo ' nvm unload Unload `nvm` from shell'
|
nvm_echo ' nvm unload Unload `nvm` from shell'
|
||||||
nvm_echo ' nvm which [current | <version>] Display path to installed node version. Uses .nvmrc if available and version is omitted.'
|
nvm_echo ' nvm which [current | <version>] Display path to installed node version. Uses .nvmrc if version is omitted; otherwise errors.'
|
||||||
nvm_echo ' --silent Silences stdout/stderr output when a version is omitted'
|
nvm_echo ' --silent Silences stdout/stderr output when a version is omitted'
|
||||||
nvm_echo ' nvm cache dir Display path to the cache directory for nvm'
|
nvm_echo ' nvm cache dir Display path to the cache directory for nvm'
|
||||||
nvm_echo ' nvm cache clear Empty cache directory for nvm'
|
nvm_echo ' nvm cache clear Empty cache directory for nvm'
|
||||||
@@ -3338,7 +3394,9 @@ nvm() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm cache dir'
|
||||||
|
nvm_err ' nvm cache clear'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -3572,7 +3630,7 @@ nvm() {
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${NVM_OFFLINE}" != 1 ] && ! nvm_has "curl" && ! nvm_has "wget"; then
|
if [ "${NVM_OFFLINE}" != 1 ] && ! nvm_has_executable "curl" && ! nvm_has_executable "wget"; then
|
||||||
nvm_err 'nvm needs curl or wget to proceed.'
|
nvm_err 'nvm needs curl or wget to proceed.'
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -3594,7 +3652,9 @@ nvm() {
|
|||||||
else
|
else
|
||||||
{ provided_version="$(nvm_rc_version 3>&1 1>&4)"; } 4>&1
|
{ provided_version="$(nvm_rc_version 3>&1 1>&4)"; } 4>&1
|
||||||
if [ $version_not_provided -eq 1 ] && [ -z "${provided_version}" ]; then
|
if [ $version_not_provided -eq 1 ] && [ -z "${provided_version}" ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm install [<version>]'
|
||||||
|
nvm_err ' Provide a <version>, or run from a directory containing an .nvmrc file.'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -3732,10 +3792,10 @@ nvm() {
|
|||||||
nvm install-latest-npm
|
nvm install-latest-npm
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
fi
|
fi
|
||||||
if [ $EXIT_CODE -ne 0 ] && [ -z "${SKIP_DEFAULT_PACKAGES-}" ]; then
|
if [ $EXIT_CODE -eq 0 ] && [ -z "${SKIP_DEFAULT_PACKAGES-}" ]; then
|
||||||
nvm_install_default_packages
|
nvm_install_default_packages
|
||||||
fi
|
fi
|
||||||
if [ $EXIT_CODE -ne 0 ] && [ -n "${REINSTALL_PACKAGES_FROM-}" ] && [ "_${REINSTALL_PACKAGES_FROM}" != "_N/A" ]; then
|
if [ $EXIT_CODE -eq 0 ] && [ -n "${REINSTALL_PACKAGES_FROM-}" ] && [ "_${REINSTALL_PACKAGES_FROM}" != "_N/A" ]; then
|
||||||
nvm reinstall-packages "${REINSTALL_PACKAGES_FROM}"
|
nvm reinstall-packages "${REINSTALL_PACKAGES_FROM}"
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
fi
|
fi
|
||||||
@@ -3753,7 +3813,7 @@ nvm() {
|
|||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $EXIT_CODE -ne 0 ] && [ -n "${ALIAS-}" ]; then
|
if [ $EXIT_CODE -eq 0 ] && [ -n "${ALIAS-}" ]; then
|
||||||
nvm alias "${ALIAS}" "${provided_version}"
|
nvm alias "${ALIAS}" "${provided_version}"
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
fi
|
fi
|
||||||
@@ -3852,7 +3912,10 @@ nvm() {
|
|||||||
;;
|
;;
|
||||||
"uninstall")
|
"uninstall")
|
||||||
if [ $# -ne 1 ]; then
|
if [ $# -ne 1 ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm uninstall <version>'
|
||||||
|
nvm_err ' nvm uninstall --lts'
|
||||||
|
nvm_err ' nvm uninstall --lts=<LTS name>'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4041,7 +4104,9 @@ nvm() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${VERSION}" ]; then
|
if [ -z "${VERSION}" ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm use [<version>]'
|
||||||
|
nvm_err ' Provide a <version>, or run from a directory containing an .nvmrc file.'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4165,7 +4230,9 @@ nvm() {
|
|||||||
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
|
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
|
||||||
fi
|
fi
|
||||||
if [ "${VERSION:-N/A}" = 'N/A' ]; then
|
if [ "${VERSION:-N/A}" = 'N/A' ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm run [<version>] [<args>]'
|
||||||
|
nvm_err ' Provide a <version>, or run from a directory containing an .nvmrc file.'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -4179,6 +4246,14 @@ nvm() {
|
|||||||
if [ $has_checked_nvmrc -ne 1 ]; then
|
if [ $has_checked_nvmrc -ne 1 ]; then
|
||||||
{ NVM_RC_VERSION="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
|
{ NVM_RC_VERSION="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
|
||||||
fi
|
fi
|
||||||
|
if [ -z "${NVM_RC_VERSION-}" ]; then
|
||||||
|
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
|
||||||
|
nvm_err 'WARNING: `nvm run` was invoked without a version argument and without an .nvmrc file.'
|
||||||
|
nvm_err ' Falling back to the active node version; this will become an error in a future release.'
|
||||||
|
nvm_err ' Pass `current` explicitly (e.g. `nvm run current ...`) to silence this warning.'
|
||||||
|
fi
|
||||||
|
NVM_RC_VERSION="$(nvm_version current)" ||:
|
||||||
|
fi
|
||||||
provided_version="${NVM_RC_VERSION}"
|
provided_version="${NVM_RC_VERSION}"
|
||||||
IS_VERSION_FROM_NVMRC=1
|
IS_VERSION_FROM_NVMRC=1
|
||||||
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
|
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
|
||||||
@@ -4236,19 +4311,36 @@ nvm() {
|
|||||||
|
|
||||||
local provided_version
|
local provided_version
|
||||||
provided_version="$1"
|
provided_version="$1"
|
||||||
|
local VERSION_SOURCE
|
||||||
|
VERSION_SOURCE=''
|
||||||
if [ "${NVM_LTS-}" != '' ]; then
|
if [ "${NVM_LTS-}" != '' ]; then
|
||||||
provided_version="lts/${NVM_LTS:-*}"
|
provided_version="lts/${NVM_LTS:-*}"
|
||||||
VERSION="${provided_version}"
|
VERSION="${provided_version}"
|
||||||
|
VERSION_SOURCE='lts'
|
||||||
elif [ -n "${provided_version}" ]; then
|
elif [ -n "${provided_version}" ]; then
|
||||||
VERSION="$(nvm_version "${provided_version}")" ||:
|
VERSION="$(nvm_version "${provided_version}")" ||:
|
||||||
if [ "_${VERSION}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then
|
if [ "_${VERSION}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then
|
||||||
{ provided_version="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
|
{ provided_version="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
|
||||||
VERSION="$(nvm_version "${provided_version}")" ||:
|
VERSION="$(nvm_version "${provided_version}")" ||:
|
||||||
|
if [ -n "${provided_version}" ]; then
|
||||||
|
VERSION_SOURCE='nvmrc'
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
|
VERSION_SOURCE='arg'
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VERSION_SOURCE}" ]; then
|
||||||
|
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
|
||||||
|
nvm_err 'WARNING: `nvm exec` was invoked without a version argument and without an .nvmrc file.'
|
||||||
|
nvm_err ' Falling back to the active node version; this will become an error in a future release.'
|
||||||
|
nvm_err ' Pass `current` explicitly (e.g. `nvm exec current ...`) to silence this warning.'
|
||||||
|
fi
|
||||||
|
provided_version='current'
|
||||||
|
VERSION="$(nvm_version current)" ||:
|
||||||
|
fi
|
||||||
|
|
||||||
nvm_ensure_version_installed "${provided_version}"
|
nvm_ensure_version_installed "${provided_version}"
|
||||||
EXIT_CODE=$?
|
EXIT_CODE=$?
|
||||||
if [ "${EXIT_CODE}" != "0" ]; then
|
if [ "${EXIT_CODE}" != "0" ]; then
|
||||||
@@ -4383,7 +4475,9 @@ nvm() {
|
|||||||
VERSION="${provided_version-}"
|
VERSION="${provided_version-}"
|
||||||
fi
|
fi
|
||||||
if [ -z "${VERSION}" ]; then
|
if [ -z "${VERSION}" ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm which [current | <version>]'
|
||||||
|
nvm_err ' Provide a <version>, or run from a directory containing an .nvmrc file.'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4480,7 +4574,8 @@ nvm() {
|
|||||||
NVM_ALIAS_DIR="$(nvm_alias_path)"
|
NVM_ALIAS_DIR="$(nvm_alias_path)"
|
||||||
command mkdir -p "${NVM_ALIAS_DIR}"
|
command mkdir -p "${NVM_ALIAS_DIR}"
|
||||||
if [ $# -ne 1 ]; then
|
if [ $# -ne 1 ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm unalias <name>'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
if [ "${1#*\/}" != "${1-}" ]; then
|
if [ "${1#*\/}" != "${1-}" ]; then
|
||||||
@@ -4517,7 +4612,8 @@ nvm() {
|
|||||||
;;
|
;;
|
||||||
"install-latest-npm")
|
"install-latest-npm")
|
||||||
if [ $# -ne 0 ]; then
|
if [ $# -ne 0 ]; then
|
||||||
>&2 nvm --help
|
nvm_err 'Usage: nvm install-latest-npm'
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4525,7 +4621,8 @@ nvm() {
|
|||||||
;;
|
;;
|
||||||
"reinstall-packages" | "copy-packages")
|
"reinstall-packages" | "copy-packages")
|
||||||
if [ $# -ne 1 ]; then
|
if [ $# -ne 1 ]; then
|
||||||
>&2 nvm --help
|
nvm_err "Usage: nvm ${COMMAND} <version>"
|
||||||
|
nvm_err ' Run `nvm --help` for full help.'
|
||||||
return 127
|
return 127
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4652,7 +4749,7 @@ nvm() {
|
|||||||
nvm_version_greater nvm_version_greater_than_or_equal_to \
|
nvm_version_greater nvm_version_greater_than_or_equal_to \
|
||||||
nvm_print_npm_version nvm_install_latest_npm nvm_npm_global_modules \
|
nvm_print_npm_version nvm_install_latest_npm nvm_npm_global_modules \
|
||||||
nvm_has_system_node nvm_has_system_iojs \
|
nvm_has_system_node nvm_has_system_iojs \
|
||||||
nvm_download nvm_get_latest nvm_has nvm_install_default_packages nvm_get_default_packages \
|
nvm_download nvm_get_latest nvm_has nvm_has_executable nvm_install_default_packages nvm_get_default_packages \
|
||||||
nvm_curl_use_compression nvm_curl_version \
|
nvm_curl_use_compression nvm_curl_version \
|
||||||
nvm_auto nvm_supports_xz \
|
nvm_auto nvm_supports_xz \
|
||||||
nvm_echo nvm_err nvm_grep nvm_cd \
|
nvm_echo nvm_err nvm_grep nvm_cd \
|
||||||
@@ -4668,7 +4765,7 @@ nvm() {
|
|||||||
nvm_get_colors nvm_set_colors nvm_print_color_code nvm_wrap_with_color_code nvm_format_help_message_colors \
|
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_echo_with_colors nvm_err_with_colors \
|
||||||
nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \
|
nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball \
|
||||||
nvm_process_nvmrc nvm_nvmrc_invalid_msg \
|
nvm_process_nvmrc nvm_process_nvmrc_content nvm_nvmrc_invalid_msg \
|
||||||
nvm_write_nvmrc \
|
nvm_write_nvmrc \
|
||||||
>/dev/null 2>&1
|
>/dev/null 2>&1
|
||||||
unset NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
|
unset NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
|
||||||
|
|||||||
+2
-2
@@ -43,11 +43,11 @@
|
|||||||
"homepage": "https://github.com/nvm-sh/nvm",
|
"homepage": "https://github.com/nvm-sh/nvm",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dockerfile_lint": "^0.3.4",
|
"dockerfile_lint": "^0.3.4",
|
||||||
"doctoc": "^2.2.1",
|
"doctoc": "^2.5.0",
|
||||||
"eclint": "^2.8.1",
|
"eclint": "^2.8.1",
|
||||||
"markdown-link-check": "^3.14.2",
|
"markdown-link-check": "^3.14.2",
|
||||||
"replace": "^1.2.2",
|
"replace": "^1.2.2",
|
||||||
"semver": "^7.7.3",
|
"semver": "^7.8.5",
|
||||||
"urchin": "^0.0.5"
|
"urchin": "^0.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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-}"
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file whose name contains spaces
|
||||||
|
mkdir -p ../../../alias
|
||||||
|
printf 'v22.1.0\n' > "../../../alias/test edge spaces"
|
||||||
|
ACTUAL="$(nvm_alias "test edge spaces")"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f "../../../alias/test edge spaces"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file where the first line has a valid version
|
||||||
|
# followed by a second line of binary-like data
|
||||||
|
printf 'v22.1.0\n' > ../../../alias/test-edge-binary
|
||||||
|
printf '\001\002\003\377\n' >> ../../../alias/test-edge-binary
|
||||||
|
ACTUAL="$(nvm_alias test-edge-binary)"
|
||||||
|
# nvm_alias emits every non-blank, non-comment line — first line should be the version
|
||||||
|
FIRST_LINE="$(nvm_echo "${ACTUAL}" | command head -n 1)"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${FIRST_LINE}" = "${EXPECTED}" ] || die "expected first line >${EXPECTED}<, got >${FIRST_LINE}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-binary
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with Windows-style line endings (CRLF)
|
||||||
|
printf 'v22.1.0\r\n' > ../../../alias/test-edge-cr
|
||||||
|
ACTUAL="$(nvm_alias test-edge-cr)"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
# Create an alias file with bare carriage return (no newline)
|
||||||
|
printf 'v22.2.0\r' > ../../../alias/test-edge-cr-bare
|
||||||
|
ACTUAL="$(nvm_alias test-edge-cr-bare)"
|
||||||
|
EXPECTED='v22.2.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for bare CR, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-cr ../../../alias/test-edge-cr-bare
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file containing only comments
|
||||||
|
printf '# this is a comment\n# another comment\n' > ../../../alias/test-edge-comments
|
||||||
|
ACTUAL="$(nvm_alias test-edge-comments 2>/dev/null)"
|
||||||
|
EXIT_CODE="$(nvm_alias test-edge-comments 2>/dev/null; echo $?)"
|
||||||
|
[ -z "${ACTUAL}" ] || die "expected empty output for comment-only alias file, got >${ACTUAL}<"
|
||||||
|
[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0, got ${EXIT_CODE}"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-comments
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with an embedded NUL byte after the version.
|
||||||
|
# NUL handling varies by shell: some stop at NUL, others read through it.
|
||||||
|
# The function must not crash, and must emit output starting with the version.
|
||||||
|
printf 'v22.1.0\000garbage\n' > ../../../alias/test-edge-nul
|
||||||
|
ACTUAL="$(nvm_alias test-edge-nul)"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0, got ${EXIT_CODE}"
|
||||||
|
case "${ACTUAL}" in
|
||||||
|
v22.1.0*) ;; # OK — starts with the version regardless of NUL handling
|
||||||
|
*) die "expected output starting with >v22.1.0<, got >${ACTUAL}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-nul
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an empty alias file
|
||||||
|
printf '' > ../../../alias/test-edge-empty
|
||||||
|
ACTUAL="$(nvm_alias test-edge-empty 2>/dev/null)"
|
||||||
|
EXIT_CODE="$(nvm_alias test-edge-empty 2>/dev/null; echo $?)"
|
||||||
|
[ -z "${ACTUAL}" ] || die "expected empty output for empty alias file, got >${ACTUAL}<"
|
||||||
|
[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0, got ${EXIT_CODE}"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-empty
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with trailing form feed
|
||||||
|
printf 'v22.1.0\f\n' > ../../../alias/test-edge-ff
|
||||||
|
ACTUAL="$(nvm_alias test-edge-ff)"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for form feed, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
# Create an alias file with trailing vertical tab
|
||||||
|
printf 'v22.2.0\v\n' > ../../../alias/test-edge-vt
|
||||||
|
ACTUAL="$(nvm_alias test-edge-vt)"
|
||||||
|
EXPECTED='v22.2.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for vertical tab, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-ff ../../../alias/test-edge-vt
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with no trailing newline
|
||||||
|
printf 'v22.1.0' > ../../../alias/test-edge-no-newline
|
||||||
|
ACTUAL="$(nvm_alias test-edge-no-newline)"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-no-newline
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
chmod 644 ../../../alias/test-edge-unreadable 2>/dev/null
|
||||||
|
rm -f ../../../alias/test-edge-unreadable
|
||||||
|
}
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file that exists but can not be read
|
||||||
|
echo 'v0.0.1' > ../../../alias/test-edge-unreadable
|
||||||
|
chmod 000 ../../../alias/test-edge-unreadable
|
||||||
|
|
||||||
|
# root (and some containers) can read mode-000 files; nothing to assert there
|
||||||
|
if [ -r ../../../alias/test-edge-unreadable ]; then
|
||||||
|
cleanup
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# like the sed/awk pipeline this replaced: empty output, success status, so
|
||||||
|
# that `nvm_ensure_default_set` does not overwrite an unreadable default alias
|
||||||
|
OUTPUT="$(nvm_alias test-edge-unreadable 2>/dev/null)"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0 for unreadable alias file, got ${EXIT_CODE}"
|
||||||
|
[ -z "${OUTPUT}" ] || die "expected empty output for unreadable alias file, got >${OUTPUT}<"
|
||||||
|
|
||||||
|
STDERR="$(nvm_alias test-edge-unreadable 2>&1 >/dev/null)"
|
||||||
|
case "${STDERR}" in
|
||||||
|
*'not readable'*) ;;
|
||||||
|
*) die "expected a not-readable warning on stderr, got >${STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cleanup
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with a very long line (version followed by a long comment)
|
||||||
|
LONG_COMMENT="$(printf '%0*d' 10000 0 | command tr '0' 'x')"
|
||||||
|
printf 'v22.1.0 #%s\n' "${LONG_COMMENT}" > ../../../alias/test-edge-long
|
||||||
|
ACTUAL="$(nvm_alias test-edge-long)"
|
||||||
|
EXPECTED='v22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-long
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias file with trailing spaces and tabs
|
||||||
|
printf '22.1.0 \t \n' > ../../../alias/test-edge-trailing-ws
|
||||||
|
ACTUAL="$(nvm_alias test-edge-trailing-ws)"
|
||||||
|
EXPECTED='22.1.0'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-trailing-ws
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# 1-hop self-reference: alias points to itself
|
||||||
|
echo 'self' > '../../../alias/self'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias self)"
|
||||||
|
EXPECTED='∞'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for self-reference, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f '../../../alias/self'
|
||||||
|
|
||||||
|
# Multi-hop loop: link1 -> link2 -> link3 -> link1
|
||||||
|
echo 'link2' > '../../../alias/link1'
|
||||||
|
echo 'link3' > '../../../alias/link2'
|
||||||
|
echo 'link1' > '../../../alias/link3'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias link1)"
|
||||||
|
EXPECTED='∞'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for 3-hop cycle, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f '../../../alias/link1' '../../../alias/link2' '../../../alias/link3'
|
||||||
|
|
||||||
|
# Cycle through an alias name containing a space
|
||||||
|
echo 'midway' > '../../../alias/foo bar'
|
||||||
|
echo 'foo bar' > '../../../alias/midway'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias 'foo bar')"
|
||||||
|
EXPECTED='∞'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for space-name cycle, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f '../../../alias/foo bar' '../../../alias/midway'
|
||||||
|
|
||||||
|
# Non-cycle through an alias name containing a space.
|
||||||
|
# Guards the newline-delimited SEEN_ALIASES storage: with space- or
|
||||||
|
# token-delimited storage, seen name 'foo bar' would falsely match 'bar'.
|
||||||
|
# Resolves: 'foo bar' -> 'midway' -> 'bar' -> 0.0.99
|
||||||
|
echo 'midway' > '../../../alias/foo bar'
|
||||||
|
echo 'bar' > '../../../alias/midway'
|
||||||
|
echo '0.0.99' > '../../../alias/bar'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias 'foo bar')"
|
||||||
|
EXPECTED='v0.0.99'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for space-name chain, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f '../../../alias/foo bar' '../../../alias/midway' '../../../alias/bar'
|
||||||
|
|
||||||
|
# Non-cycle through an alias name containing a regex metacharacter.
|
||||||
|
# Guards the literal `case` matching: the previous grep-based detection
|
||||||
|
# interpolated the resolved name into an anchored regex, so resolving 'axb'
|
||||||
|
# matched the seen name 'axb' against the pattern 'a.b' and falsely
|
||||||
|
# reported a cycle.
|
||||||
|
# Resolves: 'axb' -> 'a.b' -> 0.0.99
|
||||||
|
echo 'a.b' > '../../../alias/axb'
|
||||||
|
echo '0.0.99' > '../../../alias/a.b'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias axb)"
|
||||||
|
EXPECTED='v0.0.99'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for metachar-name chain, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
# ... while a genuine cycle through a metachar name is still detected
|
||||||
|
echo 'axb' > '../../../alias/a.b'
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias axb)"
|
||||||
|
EXPECTED='∞'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for metachar-name cycle, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f '../../../alias/axb' '../../../alias/a.b'
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create a 4-deep alias chain: hop1 -> hop2 -> hop3 -> hop4 -> 0.0.99
|
||||||
|
echo 'hop2' > ../../../alias/hop1
|
||||||
|
echo 'hop3' > ../../../alias/hop2
|
||||||
|
echo 'hop4' > ../../../alias/hop3
|
||||||
|
echo '0.0.99' > ../../../alias/hop4
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias hop1)"
|
||||||
|
EXPECTED='v0.0.99'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}< for 4-deep chain, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
rm -f ../../../alias/hop1 ../../../alias/hop2 ../../../alias/hop3 ../../../alias/hop4
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. "${NVM_DIR}/nvm.sh"
|
||||||
|
|
||||||
|
# Create an alias pointing to a version that does not exist as an alias
|
||||||
|
echo '99.99.99' > ../../../alias/test-edge-noexist
|
||||||
|
|
||||||
|
ACTUAL="$(nvm_resolve_alias test-edge-noexist)"
|
||||||
|
EXPECTED='v99.99.99'
|
||||||
|
EXIT_CODE="$(nvm_resolve_alias test-edge-noexist >/dev/null 2>&1; echo $?)"
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
[ "${EXIT_CODE}" = '0' ] || die "expected exit code 0, got ${EXIT_CODE}"
|
||||||
|
|
||||||
|
rm -f ../../../alias/test-edge-noexist
|
||||||
@@ -17,3 +17,8 @@ rm -f "../../../alias/iojs"
|
|||||||
rm -f "../../../alias/default"
|
rm -f "../../../alias/default"
|
||||||
rm -f "../../../alias/test-blank-lines"
|
rm -f "../../../alias/test-blank-lines"
|
||||||
rm -f "../../../alias/test-multi-lines"
|
rm -f "../../../alias/test-multi-lines"
|
||||||
|
rm -f "../../../alias/test-edge-"* "../../../alias/test edge spaces"
|
||||||
|
rm -f "../../../alias/self" "../../../alias/link1" "../../../alias/link2" "../../../alias/link3"
|
||||||
|
rm -f "../../../alias/foo bar" "../../../alias/midway" "../../../alias/bar"
|
||||||
|
rm -f "../../../alias/hop1" "../../../alias/hop2" "../../../alias/hop3" "../../../alias/hop4"
|
||||||
|
rm -f "../../../alias/axb" "../../../alias/a.b"
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. ../../nvm.sh
|
||||||
|
|
||||||
|
\. ../common.sh
|
||||||
|
|
||||||
|
HELP="$(nvm --help 2>&1)"
|
||||||
|
|
||||||
|
# Signatures for use/exec/run advertise `current` (mirroring `nvm which`).
|
||||||
|
for EXPECTED in \
|
||||||
|
'nvm use [current | <version>]' \
|
||||||
|
'nvm exec [current | <version>] [<command>]' \
|
||||||
|
'nvm run [current | <version>] [<args>]' \
|
||||||
|
'nvm which [current | <version>]' \
|
||||||
|
; do
|
||||||
|
case "${HELP}" in
|
||||||
|
*"${EXPECTED}"*) ;;
|
||||||
|
*) die "nvm --help did not contain signature >${EXPECTED}<" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# The .nvmrc fallback is documented as conditional, not free.
|
||||||
|
case "${HELP}" in
|
||||||
|
*'Uses .nvmrc if version is omitted; otherwise errors.'*) ;;
|
||||||
|
*) die "nvm --help did not document the .nvmrc fallback caveat" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# The stale, looser phrasing must be gone.
|
||||||
|
case "${HELP}" in
|
||||||
|
*'if available and version is omitted'*) die "nvm --help still contains the old .nvmrc phrasing" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# `nvm current` is documented as resolving via \$PATH, not .nvmrc.
|
||||||
|
case "${HELP}" in
|
||||||
|
*'Display the active node version (resolved via $PATH; not affected by .nvmrc).'*) ;;
|
||||||
|
*) die "nvm --help did not document that 'nvm current' resolves via \$PATH" ;;
|
||||||
|
esac
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
cd "${ORIG_PWD}" 2>/dev/null || true
|
||||||
|
[ -n "${TMP_DIR-}" ] && rm -rf "${TMP_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. ../../nvm.sh
|
||||||
|
|
||||||
|
\. ../common.sh
|
||||||
|
|
||||||
|
ORIG_PWD="$(pwd)"
|
||||||
|
|
||||||
|
# Run from a fresh, empty directory so no ambient .nvmrc above the test dir
|
||||||
|
# can satisfy the lookup and mask the warning.
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
cd "${TMP_DIR}" || die "could not cd to temp dir"
|
||||||
|
|
||||||
|
EXEC_WARNING='WARNING: `nvm exec` was invoked without a version argument and without an .nvmrc file.'
|
||||||
|
RUN_WARNING='WARNING: `nvm run` was invoked without a version argument and without an .nvmrc file.'
|
||||||
|
|
||||||
|
# `nvm exec` with no version and no .nvmrc should warn on stderr (and fall back).
|
||||||
|
set +ex # needed for stderr
|
||||||
|
EXEC_STDERR="$(nvm exec </dev/null 2>&1 1>/dev/null)"
|
||||||
|
set -ex
|
||||||
|
case "${EXEC_STDERR}" in
|
||||||
|
*"${EXEC_WARNING}"*) ;;
|
||||||
|
*) die "'nvm exec' with no version did not warn; got >${EXEC_STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# `--silent` should suppress the warning.
|
||||||
|
set +ex # needed for stderr
|
||||||
|
EXEC_SILENT_STDERR="$(nvm exec --silent </dev/null 2>&1 1>/dev/null)"
|
||||||
|
set -ex
|
||||||
|
case "${EXEC_SILENT_STDERR}" in
|
||||||
|
*WARNING*) die "'nvm exec --silent' should not warn; got >${EXEC_SILENT_STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# `nvm run` with an unresolvable version and no .nvmrc should warn (and fall back).
|
||||||
|
set +ex # needed for stderr
|
||||||
|
RUN_STDERR="$(nvm run bogusversion </dev/null 2>&1 1>/dev/null)"
|
||||||
|
set -ex
|
||||||
|
case "${RUN_STDERR}" in
|
||||||
|
*"${RUN_WARNING}"*) ;;
|
||||||
|
*) die "'nvm run' with no resolvable version did not warn; got >${RUN_STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# `--silent` should suppress the warning.
|
||||||
|
set +ex # needed for stderr
|
||||||
|
RUN_SILENT_STDERR="$(nvm run --silent bogusversion </dev/null 2>&1 1>/dev/null)"
|
||||||
|
set -ex
|
||||||
|
case "${RUN_SILENT_STDERR}" in
|
||||||
|
*WARNING*) die "'nvm run --silent' should not warn; got >${RUN_SILENT_STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cleanup
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
cd "${ORIG_PWD}" 2>/dev/null || true
|
||||||
|
[ -n "${TMP_DIR-}" ] && rm -rf "${TMP_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
export NVM_DIR="$(cd ../.. && pwd)"
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. ../../nvm.sh
|
||||||
|
|
||||||
|
\. ../common.sh
|
||||||
|
|
||||||
|
ORIG_PWD="$(pwd)"
|
||||||
|
|
||||||
|
# Run from a fresh, empty directory so the "no version + no .nvmrc" cases
|
||||||
|
# (install/run/which) are not masked by an ambient .nvmrc above the test dir.
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
cd "${TMP_DIR}" || die "could not cd to temp dir"
|
||||||
|
|
||||||
|
# Asserts a subcommand emits the given focused usage line (not the full help
|
||||||
|
# dump) on stderr, and exits 127.
|
||||||
|
assert_usage() {
|
||||||
|
local EXPECTED_LINE
|
||||||
|
EXPECTED_LINE="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
try_err "$@"
|
||||||
|
|
||||||
|
case "${CAPTURED_STDERR}" in
|
||||||
|
*"${EXPECTED_LINE}"*) ;;
|
||||||
|
*) die "\`$*\` did not show focused usage >${EXPECTED_LINE}<; got >${CAPTURED_STDERR}<" ;;
|
||||||
|
esac
|
||||||
|
# the focused usage should NOT be the full help dump
|
||||||
|
case "${CAPTURED_STDERR}" in
|
||||||
|
*'Show this message'*) die "\`$*\` dumped full help instead of a focused usage" ;;
|
||||||
|
esac
|
||||||
|
[ "_${CAPTURED_EXIT_CODE}" = "_127" ] \
|
||||||
|
|| die "\`$*\` expected exit code 127; got ${CAPTURED_EXIT_CODE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_usage 'Usage: nvm cache dir' nvm cache bogus
|
||||||
|
assert_usage 'Usage: nvm install [<version>]' nvm install
|
||||||
|
assert_usage 'Usage: nvm run [<version>] [<args>]' nvm run
|
||||||
|
assert_usage 'Usage: nvm which [current | <version>]' nvm which
|
||||||
|
assert_usage 'Usage: nvm uninstall <version>' nvm uninstall
|
||||||
|
assert_usage 'Usage: nvm uninstall <version>' nvm uninstall a b
|
||||||
|
assert_usage 'Usage: nvm unalias <name>' nvm unalias
|
||||||
|
assert_usage 'Usage: nvm unalias <name>' nvm unalias a b
|
||||||
|
assert_usage 'Usage: nvm install-latest-npm' nvm install-latest-npm extra
|
||||||
|
assert_usage 'Usage: nvm reinstall-packages <version>' nvm reinstall-packages
|
||||||
|
assert_usage 'Usage: nvm copy-packages <version>' nvm copy-packages a b
|
||||||
|
|
||||||
|
# `nvm use` reaches its focused-usage guard only when version resolution returns
|
||||||
|
# an empty string. From the CLI that cannot happen: an omitted version is caught
|
||||||
|
# earlier (the `Please see ... nvmrc` branch), and an unresolvable non-empty
|
||||||
|
# version yields the "N/A" sentinel, never "". The branch is a defensive guard,
|
||||||
|
# so drive it directly by stubbing the resolver to return empty. Keep this last:
|
||||||
|
# the stub stays in effect for the rest of the shell.
|
||||||
|
nvm_match_version() { nvm_echo ''; }
|
||||||
|
assert_usage 'Usage: nvm use [<version>]' nvm use foo
|
||||||
|
|
||||||
|
cleanup
|
||||||
@@ -30,9 +30,10 @@ nvm_echo "$CAPTURED_STDERR" | nvm_grep -q "${EXPECTED_ERR}" \
|
|||||||
|
|
||||||
# --offline should not require curl or wget
|
# --offline should not require curl or wget
|
||||||
nvm_has() { return 1; }
|
nvm_has() { return 1; }
|
||||||
|
nvm_has_executable() { return 1; }
|
||||||
try_err nvm install --offline 999.999.999
|
try_err nvm install --offline 999.999.999
|
||||||
# Should fail with "not found" not "nvm needs curl or wget"
|
# Should fail with "not found" not "nvm needs curl or wget"
|
||||||
nvm_echo "$CAPTURED_STDERR" | nvm_grep -q "curl or wget" \
|
nvm_echo "$CAPTURED_STDERR" | nvm_grep -q "curl or wget" \
|
||||||
&& die "nvm install --offline should not require curl or wget"
|
&& die "nvm install --offline should not require curl or wget"
|
||||||
alias nvm_has='\nvm_has'
|
alias nvm_has='\nvm_has'
|
||||||
unset -f nvm_has
|
unset -f nvm_has nvm_has_executable
|
||||||
|
|||||||
@@ -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,66 @@
|
|||||||
|
#!/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")"
|
||||||
|
|
||||||
|
# when no curl executable exists, a shadowing curl shell function must not fool
|
||||||
|
# downloader selection: nvm_download must fall back to the wget executable
|
||||||
|
WGET_ONLY_BIN="$WORK/wget-only-bin"
|
||||||
|
mkdir -p "$WGET_ONLY_BIN"
|
||||||
|
{
|
||||||
|
echo '#!/bin/sh'
|
||||||
|
echo ': > "$ARGV_LOG"'
|
||||||
|
echo 'for a in "$@"; do printf "%s\n" "$a" >> "$ARGV_LOG"; done'
|
||||||
|
} > "$WGET_ONLY_BIN/wget"
|
||||||
|
chmod +x "$WGET_ONLY_BIN/wget"
|
||||||
|
|
||||||
|
(
|
||||||
|
PATH="$WGET_ONLY_BIN"
|
||||||
|
export PATH
|
||||||
|
nvm_download -s 'http://wget-fallback.example.com/' -o /dev/null
|
||||||
|
) || die 'nvm_download did not fall back to wget when curl is only a shell function'
|
||||||
|
grep -Fxq 'http://wget-fallback.example.com/' "$ARGV_LOG" || die "nvm_download did not invoke the wget executable; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
cleanup
|
||||||
@@ -6,7 +6,7 @@ TEST_BIN="$WORK/bin"
|
|||||||
ARGV_LOG="$WORK/argv.log"
|
ARGV_LOG="$WORK/argv.log"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
unset -f die cleanup nvm_has
|
unset -f die cleanup nvm_has_executable
|
||||||
rm -rf "$WORK"
|
rm -rf "$WORK"
|
||||||
export PATH="$OLDPATH"
|
export PATH="$OLDPATH"
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ chmod +x "$TEST_BIN/wget"
|
|||||||
export ARGV_LOG
|
export ARGV_LOG
|
||||||
export PATH="$TEST_BIN:$OLDPATH"
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
# force the wget path while keeping system tools (sed) available for sanitization
|
# force the wget path while keeping system tools (sed) available for sanitization
|
||||||
nvm_has() { [ "$1" != curl ] && command -v "$1" >/dev/null 2>&1; }
|
nvm_has_executable() { [ "$1" != curl ] && command -v "$1" >/dev/null 2>&1; }
|
||||||
|
|
||||||
# given an Authorization credential in NVM_AUTH_HEADER
|
# given an Authorization credential in NVM_AUTH_HEADER
|
||||||
# when nvm_download uses the wget path
|
# when nvm_download uses the wget path
|
||||||
|
|||||||
@@ -93,4 +93,6 @@ run_test amd64 osx x64
|
|||||||
run_test arm64 smartos x64
|
run_test arm64 smartos x64
|
||||||
run_test armv8l smartos x64
|
run_test armv8l smartos x64
|
||||||
|
|
||||||
|
run_test loongarch64 linux loong64
|
||||||
|
|
||||||
cleanup
|
cleanup
|
||||||
|
|||||||
@@ -110,3 +110,26 @@ ACTUAL="$(nvm_get_download_slug iojs source 15.99.99)"
|
|||||||
EXPECTED="iojs-15.99.99"
|
EXPECTED="iojs-15.99.99"
|
||||||
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
|
||||||
|
REAL_OS="$(command uname -s 2>/dev/null || echo '')"
|
||||||
|
REAL_ARCH="$(command uname -m 2>/dev/null || echo '')"
|
||||||
|
if [ "${REAL_OS}" = "Darwin" ] && [ "${REAL_ARCH}" = "arm64" ]; then
|
||||||
|
# Node < 16 uses x64 on darwin-arm64
|
||||||
|
ACTUAL="$(nvm_get_download_slug node binary 14.21.3)"
|
||||||
|
EXPECTED='node-14.21.3-darwin-x64'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
ACTUAL="$(nvm_get_download_slug node binary 15.99.99)"
|
||||||
|
EXPECTED='node-15.99.99-darwin-x64'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
ACTUAL="$(nvm_get_download_slug iojs binary 15.99.99)"
|
||||||
|
EXPECTED='iojs-15.99.99-darwin-x64'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
|
||||||
|
# Test Node >= 16 uses arm64 on darwin-arm64
|
||||||
|
ACTUAL="$(nvm_get_download_slug node binary 16.0.0)"
|
||||||
|
EXPECTED='node-16.0.0-darwin-arm64'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
ACTUAL="$(nvm_get_download_slug node binary 18.0.0)"
|
||||||
|
EXPECTED='node-18.0.0-darwin-arm64'
|
||||||
|
[ "${ACTUAL}" = "${EXPECTED}" ] || die "expected >${EXPECTED}<, got >${ACTUAL}<"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
die () { echo "$@" ; cleanup ; exit 1; }
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
unset -f nvm_has
|
unset -f nvm_has nvm_has_executable
|
||||||
}
|
}
|
||||||
|
|
||||||
: nvm.sh
|
: nvm.sh
|
||||||
@@ -12,6 +12,7 @@ cleanup() {
|
|||||||
\. ../../common.sh
|
\. ../../common.sh
|
||||||
|
|
||||||
nvm_has() { return 1 ; }
|
nvm_has() { return 1 ; }
|
||||||
|
nvm_has_executable() { return 1 ; }
|
||||||
|
|
||||||
try_err nvm_get_latest
|
try_err nvm_get_latest
|
||||||
[ "_$CAPTURED_STDERR" = "_nvm needs curl or wget to proceed." ] \
|
[ "_$CAPTURED_STDERR" = "_nvm needs curl or wget to proceed." ] \
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
die () { echo "$@" ; exit 1; }
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "${TEST_DIR-}"
|
||||||
|
unset NVMRC_CONTENT OUTPUT EXIT_CODE TEST_DIR NVM_DIR
|
||||||
|
}
|
||||||
|
|
||||||
: nvm.sh
|
: nvm.sh
|
||||||
\. ../../../nvm.sh
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
\. ../../common.sh
|
||||||
|
|
||||||
|
# an isolated NVM_DIR with a single known version, so that ambient versions
|
||||||
|
# and aliases can not affect any assertions
|
||||||
|
TEST_DIR="${PWD}/nvm_ls_hash_pattern_tmp"
|
||||||
|
mkdir -p "${TEST_DIR}/versions/node/v24.13.0/bin" || die 'failed to create test version dir'
|
||||||
|
make_echo "${TEST_DIR}/versions/node/v24.13.0/bin/node" 'v24.13.0' || die 'failed to create test node binary'
|
||||||
|
NVM_DIR="${TEST_DIR}"
|
||||||
|
|
||||||
# Test: nvm_ls with pattern containing # should not cause sed error
|
# Test: nvm_ls with pattern containing # should not cause sed error
|
||||||
# This is a regression test for https://github.com/nvm-sh/nvm/issues/3761
|
# This is a regression test for https://github.com/nvm-sh/nvm/issues/3761
|
||||||
|
|
||||||
@@ -22,3 +36,33 @@ echo "$OUTPUT" | grep -q "invalid command code" && \
|
|||||||
# Should return N/A with exit code 3 (not found)
|
# Should return N/A with exit code 3 (not found)
|
||||||
[ "$EXIT_CODE" = "3" ] || die "nvm_ls 'foo#bar' should exit with code 3, got $EXIT_CODE"
|
[ "$EXIT_CODE" = "3" ] || die "nvm_ls 'foo#bar' should exit with code 3, got $EXIT_CODE"
|
||||||
echo "$OUTPUT" | grep -q "N/A" || die "nvm_ls 'foo#bar' should output N/A, got: $OUTPUT"
|
echo "$OUTPUT" | grep -q "N/A" || die "nvm_ls 'foo#bar' should output N/A, got: $OUTPUT"
|
||||||
|
|
||||||
|
NVMRC_CONTENT='v24.13.0
|
||||||
|
# krypton is the codename for Node.js v24.x'
|
||||||
|
|
||||||
|
OUTPUT="$(nvm_ls "${NVMRC_CONTENT}" 2>&1)"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
|
[ "$EXIT_CODE" = "0" ] || die "nvm_ls with .nvmrc comments should exit with code 0, got $EXIT_CODE"
|
||||||
|
[ "$OUTPUT" = "v24.13.0" ] || die "nvm_ls with .nvmrc comments should output v24.13.0, got: $OUTPUT"
|
||||||
|
|
||||||
|
OUTPUT="$(nvm_version "${NVMRC_CONTENT}" 2>&1)"
|
||||||
|
[ "$OUTPUT" = "v24.13.0" ] || die "nvm_version with .nvmrc comments should output v24.13.0, got: $OUTPUT"
|
||||||
|
|
||||||
|
# a partial version reaches nvm_ls's find/sed pipeline, which is where multiline
|
||||||
|
# patterns used to break sed ("unterminated regular expression" on BSD sed,
|
||||||
|
# "unterminated address regex" on GNU sed); a full x.y.z version takes the
|
||||||
|
# explicit-version fast path and never reaches it
|
||||||
|
NVMRC_CONTENT='24
|
||||||
|
# krypton is the codename for Node.js v24.x'
|
||||||
|
|
||||||
|
OUTPUT="$(nvm_ls "${NVMRC_CONTENT}" 2>&1)"
|
||||||
|
EXIT_CODE=$?
|
||||||
|
|
||||||
|
echo "$OUTPUT" | grep -q "unterminated" && \
|
||||||
|
die "nvm_ls with partial version + comments caused a sed error: $OUTPUT"
|
||||||
|
|
||||||
|
[ "$EXIT_CODE" = "0" ] || die "nvm_ls with partial version + comments should exit with code 0, got $EXIT_CODE"
|
||||||
|
[ "$OUTPUT" = "v24.13.0" ] || die "nvm_ls with partial version + comments should output v24.13.0, got: $OUTPUT"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
cd "${ORIG_PWD}" 2>/dev/null || true
|
||||||
|
[ -n "${TMP_DIR-}" ] && rm -rf "${TMP_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
: nvm.sh
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
\. ../../common.sh
|
||||||
|
|
||||||
|
ORIG_PWD="$(pwd)"
|
||||||
|
|
||||||
|
# Run from a fresh, empty directory so no ambient .nvmrc above the test dir
|
||||||
|
# is found by the upward lookup.
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
cd "${TMP_DIR}" || die "could not cd to temp dir"
|
||||||
|
|
||||||
|
# The message must name both halves of the problem: no argument AND no .nvmrc.
|
||||||
|
try_err nvm_rc_version
|
||||||
|
EXPECTED='No version provided and no .nvmrc file found'
|
||||||
|
[ "_${CAPTURED_STDERR}" = "_${EXPECTED}" ] \
|
||||||
|
|| die "nvm_rc_version did not print >${EXPECTED}<; got >${CAPTURED_STDERR}<"
|
||||||
|
[ "_${CAPTURED_EXIT_CODE}" = "_1" ] \
|
||||||
|
|| die "nvm_rc_version expected exit code 1; got ${CAPTURED_EXIT_CODE}"
|
||||||
|
|
||||||
|
# NVM_SILENT suppresses the message but the call still fails.
|
||||||
|
export NVM_SILENT=1
|
||||||
|
try_err nvm_rc_version
|
||||||
|
unset NVM_SILENT
|
||||||
|
[ -z "${CAPTURED_STDERR}" ] \
|
||||||
|
|| die "NVM_SILENT nvm_rc_version should be silent; got >${CAPTURED_STDERR}<"
|
||||||
|
[ "_${CAPTURED_EXIT_CODE}" = "_1" ] \
|
||||||
|
|| die "NVM_SILENT nvm_rc_version expected exit code 1; got ${CAPTURED_EXIT_CODE}"
|
||||||
|
|
||||||
|
cleanup
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
die () { echo "$@" ; exit 1; }
|
||||||
|
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# Test 1: all standard base64 characters (RFC 4648) are preserved
|
||||||
|
STANDARD_B64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||||
|
RESULT=$(nvm_sanitize_auth_header "${STANDARD_B64}")
|
||||||
|
[ "${RESULT}" = "${STANDARD_B64}" ] || die "FAIL: standard base64 chars were stripped. Got: '${RESULT}'"
|
||||||
|
|
||||||
|
# Test 2: all base64url characters (RFC 4648 §5) are preserved
|
||||||
|
B64URL="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="
|
||||||
|
RESULT=$(nvm_sanitize_auth_header "${B64URL}")
|
||||||
|
[ "${RESULT}" = "${B64URL}" ] || die "FAIL: base64url chars were stripped. Got: '${RESULT}'"
|
||||||
|
|
||||||
|
# Test 3: a real JWT Bearer token (base64url-encoded header.payload.signature) is preserved
|
||||||
|
JWT_TOKEN="Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
|
||||||
|
RESULT=$(nvm_sanitize_auth_header "${JWT_TOKEN}")
|
||||||
|
[ "${RESULT}" = "${JWT_TOKEN}" ] || die "FAIL: JWT Bearer token chars were stripped. Got: '${RESULT}'"
|
||||||
|
|
||||||
|
# Test 4: Basic auth (base64-encoded user:pass) is preserved
|
||||||
|
BASIC_TOKEN="Basic dXNlcm5hbWU6cGFzc3dvcmQ="
|
||||||
|
RESULT=$(nvm_sanitize_auth_header "${BASIC_TOKEN}")
|
||||||
|
[ "${RESULT}" = "${BASIC_TOKEN}" ] || die "FAIL: Basic auth base64 token chars were stripped. Got: '${RESULT}'"
|
||||||
|
|
||||||
|
# Test 5: dangerous shell metacharacters are removed
|
||||||
|
DANGEROUS="Bearer token;\`evil\`-cmd \$(inject)"
|
||||||
|
RESULT=$(nvm_sanitize_auth_header "${DANGEROUS}")
|
||||||
|
case "${RESULT}" in
|
||||||
|
*";"*|*"\`"*|*'$'*|*"("*|*")"*)
|
||||||
|
die "FAIL: dangerous shell metacharacters survived sanitization. Got: '${RESULT}'"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "All nvm_sanitize_auth_header tests passed"
|
||||||
Regular → Executable
+2
-2
@@ -32,9 +32,9 @@ fi
|
|||||||
# Test 2: Verify that sanitized header still works for legitimate requests
|
# Test 2: Verify that sanitized header still works for legitimate requests
|
||||||
# The sanitized header should only contain safe characters
|
# The sanitized header should only contain safe characters
|
||||||
SANITIZED=$(nvm_sanitize_auth_header "${MALICIOUS_HEADER}")
|
SANITIZED=$(nvm_sanitize_auth_header "${MALICIOUS_HEADER}")
|
||||||
# Verify that dangerous characters were removed
|
# Verify that dangerous shell metacharacters were removed
|
||||||
case "${SANITIZED}" in
|
case "${SANITIZED}" in
|
||||||
*";"*|*"touch"*|*"/tmp"*)
|
*";"*|*'$'*|*"\`"*)
|
||||||
die "SECURITY FAILURE: Sanitization did not remove dangerous characters properly"
|
die "SECURITY FAILURE: Sanitization did not remove dangerous characters properly"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
die () { echo "$@" ; exit 1; }
|
# State touched by the regression section below; cleanup restores it even on failure.
|
||||||
|
DEFAULT_PACKAGES_FILE="${NVM_DIR}/default-packages"
|
||||||
|
DEFAULT_PACKAGES_BACKUP=""
|
||||||
|
DEFAULT_PACKAGES_WROTE=""
|
||||||
|
TEST_ALIAS=""
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
if [ -n "${DEFAULT_PACKAGES_WROTE}" ]; then
|
||||||
|
rm -f "${DEFAULT_PACKAGES_FILE}"
|
||||||
|
DEFAULT_PACKAGES_WROTE=""
|
||||||
|
fi
|
||||||
|
if [ -n "${DEFAULT_PACKAGES_BACKUP}" ] && [ -f "${DEFAULT_PACKAGES_BACKUP}" ]; then
|
||||||
|
mv "${DEFAULT_PACKAGES_BACKUP}" "${DEFAULT_PACKAGES_FILE}"
|
||||||
|
DEFAULT_PACKAGES_BACKUP=""
|
||||||
|
fi
|
||||||
|
if [ -n "${TEST_ALIAS}" ]; then
|
||||||
|
nvm unalias "${TEST_ALIAS}" > /dev/null 2>&1 || true
|
||||||
|
TEST_ALIAS=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
\. ../../nvm.sh
|
\. ../../nvm.sh
|
||||||
|
|
||||||
@@ -44,3 +65,54 @@ nvm use --lts=argon
|
|||||||
node --version | grep v4.9.1 > /dev/null || die "nvm ls --lts=argon didn't use v4.9.1"
|
node --version | grep v4.9.1 > /dev/null || die "nvm ls --lts=argon didn't use v4.9.1"
|
||||||
|
|
||||||
npm list --global | grep object-is > /dev/null || die "object-is isn't installed"
|
npm list --global | grep object-is > /dev/null || die "object-is isn't installed"
|
||||||
|
|
||||||
|
|
||||||
|
# Regression: `--reinstall-packages-from` must still migrate packages when the
|
||||||
|
# target version is *already installed*. See https://github.com/nvm-sh/nvm/issues/3858
|
||||||
|
|
||||||
|
# install a fresh global package on the source (v9.7.0) only
|
||||||
|
nvm use 9.7.0
|
||||||
|
npm install -g is-nan@1.0.1 || die "npm install -g is-nan failed"
|
||||||
|
npm list --global --depth=0 | grep is-nan > /dev/null || die "is-nan isn't installed on v9.7.0"
|
||||||
|
|
||||||
|
# precondition: the already-installed target (v9.10.0) must not have it yet
|
||||||
|
nvm use 9.10.0
|
||||||
|
npm list --global --depth=0 | grep is-nan > /dev/null && die "is-nan should not be installed on v9.10.0 before reinstall"
|
||||||
|
|
||||||
|
# target is already installed, so this should report so AND still migrate packages
|
||||||
|
OUTPUT="$(nvm install --reinstall-packages-from=9.7.0 9.10.0 2>&1)" || die "nvm install --reinstall-packages-from=9.7.0 9.10.0 failed: ${OUTPUT}"
|
||||||
|
nvm_echo "${OUTPUT}" | grep "is already installed" > /dev/null || die "expected 'already installed' message, got: ${OUTPUT}"
|
||||||
|
|
||||||
|
nvm use 9.10.0
|
||||||
|
npm list --global --depth=0 | grep is-nan > /dev/null || die "is-nan was not migrated to already-installed v9.10.0"
|
||||||
|
|
||||||
|
|
||||||
|
# ...the same is true for default packages: they must install on the already-installed path too.
|
||||||
|
|
||||||
|
# back up any real default-packages file, then point it at a package the target lacks
|
||||||
|
if [ -f "${DEFAULT_PACKAGES_FILE}" ]; then
|
||||||
|
DEFAULT_PACKAGES_BACKUP="${DEFAULT_PACKAGES_FILE}.3858.bak"
|
||||||
|
mv "${DEFAULT_PACKAGES_FILE}" "${DEFAULT_PACKAGES_BACKUP}" || die "could not back up ${DEFAULT_PACKAGES_FILE}"
|
||||||
|
fi
|
||||||
|
DEFAULT_PACKAGES_WROTE=1
|
||||||
|
nvm_echo 'object-inspect@1.0.2' > "${DEFAULT_PACKAGES_FILE}"
|
||||||
|
|
||||||
|
# precondition: the already-installed target must not have the default package yet
|
||||||
|
nvm use 9.10.0
|
||||||
|
npm list --global --depth=0 | grep object-inspect > /dev/null && die "object-inspect should not be installed on v9.10.0 before default-packages test"
|
||||||
|
|
||||||
|
nvm install 9.10.0 > /dev/null 2>&1 || die "nvm install 9.10.0 (already installed, default-packages) failed"
|
||||||
|
nvm use 9.10.0
|
||||||
|
npm list --global --depth=0 | grep object-inspect > /dev/null || die "default packages were not installed on already-installed v9.10.0"
|
||||||
|
|
||||||
|
# restore the default-packages file before the next assertion
|
||||||
|
cleanup
|
||||||
|
|
||||||
|
|
||||||
|
# ...and `--alias` must be set on the already-installed path too.
|
||||||
|
TEST_ALIAS='nvm-3858-already-installed'
|
||||||
|
nvm unalias "${TEST_ALIAS}" > /dev/null 2>&1 || true # ensure a clean precondition
|
||||||
|
nvm install --alias="${TEST_ALIAS}" 9.10.0 > /dev/null 2>&1 || die "nvm install --alias=${TEST_ALIAS} 9.10.0 (already installed) failed"
|
||||||
|
TERM=dumb nvm alias "${TEST_ALIAS}" | grep 'v9.10.0' > /dev/null || die "--alias was not set on already-installed v9.10.0"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
|||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
if [ "_$1" = "_-m" ]; then
|
||||||
|
echo "loongarch64"
|
||||||
|
else
|
||||||
|
echo "Linux foo 6.12.54-16k #0 SMP PREEMPT_DYNAMIC Fri Dec 5 12:35:43 UTC loongarch64 GNU/Linux"
|
||||||
|
fi
|
||||||
@@ -2,37 +2,46 @@
|
|||||||
|
|
||||||
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
|
unset -f curl wget
|
||||||
|
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 +91,22 @@ 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"
|
||||||
|
|
||||||
|
# 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 >&2 'the shadowing curl function was called'
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
wget() {
|
||||||
|
echo >&2 'the shadowing wget function was called'
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
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