mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-09-25 00:00:15 +08:00
Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42bb45f289 | ||
|
|
419ff4efec | ||
|
|
7a7908ffa1 | ||
|
|
ce15734300 | ||
|
|
ee4fa818d2 | ||
|
|
a6ec739430 | ||
|
|
718e880890 | ||
|
|
ed4dbdfdd5 | ||
|
|
a9933f77a6 | ||
|
|
7079a5d61c | ||
|
|
306f04a90a | ||
|
|
77fca77ddd | ||
|
|
1889911f08 | ||
|
|
70fb4ede6b | ||
|
|
90bb88748b | ||
|
|
6d870d182c | ||
|
|
d264b796a3 | ||
|
|
84079dbff3 | ||
|
|
61c9ff7371 | ||
|
|
16f6ddc3d5 | ||
|
|
c4d9239cbb | ||
|
|
dd13968c1e |
@@ -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}"
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
matrix:
|
matrix:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
matrix: ${{ steps.matrix.outputs.matrix }}
|
matrix: ${{ steps.matrix.outputs.matrix }}
|
||||||
@@ -43,6 +45,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
permissions:
|
||||||
|
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
|
continue-on-error: ${{ matrix.ref == 'v0.40.0' }} # https://github.com/nvm-sh/nvm/issues/3405
|
||||||
@@ -101,6 +105,8 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
finisher:
|
finisher:
|
||||||
|
permissions:
|
||||||
|
contents: none
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [test]
|
needs: [test]
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -45,9 +45,19 @@ jobs:
|
|||||||
registry-1.docker.io:443
|
registry-1.docker.io:443
|
||||||
auth.docker.io:443
|
auth.docker.io:443
|
||||||
production.cloudflare.docker.com:443
|
production.cloudflare.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
|
||||||
|
|||||||
@@ -41,11 +41,21 @@ jobs:
|
|||||||
archive.ubuntu.com:80
|
archive.ubuntu.com:80
|
||||||
security.ubuntu.com:80
|
security.ubuntu.com:80
|
||||||
production.cloudflare.docker.com:443
|
production.cloudflare.docker.com:443
|
||||||
|
production.cloudfront.docker.com:443
|
||||||
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:
|
||||||
@@ -55,6 +65,12 @@ jobs:
|
|||||||
- run: npx which urchin
|
- run: npx which urchin
|
||||||
- name: Run installation_node tests in container
|
- name: Run installation_node tests in container
|
||||||
run: |
|
run: |
|
||||||
|
# Retry the image pull to tolerate transient Docker registry failures
|
||||||
|
for i in 1 2 3 4 5; do
|
||||||
|
docker pull ubuntu:16.04 && break
|
||||||
|
echo "docker pull failed, attempt $i/5"
|
||||||
|
sleep $((i * 5))
|
||||||
|
done
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${{ github.workspace }}:/workspace" \
|
-v "${{ github.workspace }}:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
|
|||||||
@@ -38,11 +38,21 @@ jobs:
|
|||||||
archive.ubuntu.com:80
|
archive.ubuntu.com:80
|
||||||
security.ubuntu.com:80
|
security.ubuntu.com:80
|
||||||
production.cloudflare.docker.com:443
|
production.cloudflare.docker.com:443
|
||||||
|
production.cloudfront.docker.com:443
|
||||||
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:
|
||||||
@@ -52,6 +62,12 @@ jobs:
|
|||||||
- run: npx which urchin
|
- run: npx which urchin
|
||||||
- name: Run xenial tests in container
|
- name: Run xenial tests in container
|
||||||
run: |
|
run: |
|
||||||
|
# Retry the image pull to tolerate transient Docker registry failures
|
||||||
|
for i in 1 2 3 4 5; do
|
||||||
|
docker pull ubuntu:16.04 && break
|
||||||
|
echo "docker pull failed, attempt $i/5"
|
||||||
|
sleep $((i * 5))
|
||||||
|
done
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-v "${{ github.workspace }}:/workspace" \
|
-v "${{ github.workspace }}:/workspace" \
|
||||||
-w /workspace \
|
-w /workspace \
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
# Node Version Manager [][3] [][4] [](https://bestpractices.dev/projects/684)
|
# Node Version Manager [][3] [][4] [](https://bestpractices.dev/projects/684)
|
||||||
|
|
||||||
<!-- To update this table of contents, ensure you have run `npm install` then `npm run doctoc` -->
|
<!-- To update this table of contents, ensure you have run `npm install` then `npm run doctoc` -->
|
||||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
@@ -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)
|
||||||
@@ -105,10 +106,10 @@ nvm is a version manager for [node.js](https://nodejs.org/en/), designed to be i
|
|||||||
|
|
||||||
To **install** or **update** nvm, you should run the [install script][2]. To do that, you may either download and run the script manually, or use the following cURL or Wget command:
|
To **install** or **update** nvm, you should run the [install script][2]. To do that, you may either download and run the script manually, or use the following cURL or Wget command:
|
||||||
```sh
|
```sh
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
```
|
```
|
||||||
```sh
|
```sh
|
||||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
Running either of the above commands downloads a script and runs it. The script clones the nvm repository to `~/.nvm`, and attempts to add the source lines from the snippet below to the correct profile file (`~/.bashrc`, `~/.bash_profile`, `~/.zshrc`, or `~/.profile`). If you find the install script is updating the wrong profile file, set the `$PROFILE` env var to the profile file’s path, and then rerun the installation script.
|
Running either of the above commands downloads a script and runs it. The script clones the nvm repository to `~/.nvm`, and attempts to add the source lines from the snippet below to the correct profile file (`~/.bashrc`, `~/.bash_profile`, `~/.zshrc`, or `~/.profile`). If you find the install script is updating the wrong profile file, set the `$PROFILE` env var to the profile file’s path, and then rerun the installation script.
|
||||||
@@ -135,7 +136,7 @@ Eg: `curl ... | NVM_DIR="path/to/nvm"`. Ensure that the `NVM_DIR` does not conta
|
|||||||
|
|
||||||
- The installer can use `git`, `curl`, or `wget` to download `nvm`, whichever is available.
|
- The installer can use `git`, `curl`, or `wget` to download `nvm`, whichever is available.
|
||||||
|
|
||||||
- You can instruct the installer to not edit your shell config (for example if you already get completions via a [zsh nvm plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/nvm)) by setting `PROFILE=/dev/null` before running the `install.sh` script. Here's an example one-line command to do that: `PROFILE=/dev/null bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash'`
|
- You can instruct the installer to not edit your shell config (for example if you already get completions via a [zsh nvm plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/nvm)) by setting `PROFILE=/dev/null` before running the `install.sh` script. Here's an example one-line command to do that: `PROFILE=/dev/null bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash'`
|
||||||
|
|
||||||
#### Installing in Docker
|
#### Installing in Docker
|
||||||
|
|
||||||
@@ -151,7 +152,7 @@ RUN touch "${BASH_ENV}"
|
|||||||
RUN echo '. "${BASH_ENV}"' >> ~/.bashrc
|
RUN echo '. "${BASH_ENV}"' >> ~/.bashrc
|
||||||
|
|
||||||
# Download and install nvm
|
# Download and install nvm
|
||||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | PROFILE="${BASH_ENV}" bash
|
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | PROFILE="${BASH_ENV}" bash
|
||||||
RUN echo node > .nvmrc
|
RUN echo node > .nvmrc
|
||||||
RUN nvm install
|
RUN nvm install
|
||||||
```
|
```
|
||||||
@@ -169,7 +170,7 @@ ARG NODE_VERSION=20
|
|||||||
RUN apt update && apt install curl -y
|
RUN apt update && apt install curl -y
|
||||||
|
|
||||||
# install nvm
|
# install nvm
|
||||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
|
|
||||||
# set env
|
# set env
|
||||||
ENV NVM_DIR=/root/.nvm
|
ENV NVM_DIR=/root/.nvm
|
||||||
@@ -195,7 +196,7 @@ After creation of the image you can start container interactively and run comman
|
|||||||
docker run --rm -it nvmimage
|
docker run --rm -it nvmimage
|
||||||
|
|
||||||
root@0a6b5a237c14:/# nvm -v
|
root@0a6b5a237c14:/# nvm -v
|
||||||
0.40.4
|
0.40.5
|
||||||
|
|
||||||
root@0a6b5a237c14:/# node -v
|
root@0a6b5a237c14:/# node -v
|
||||||
v19.9.0
|
v19.9.0
|
||||||
@@ -258,7 +259,7 @@ You can use a task:
|
|||||||
```yaml
|
```yaml
|
||||||
- name: Install nvm
|
- name: Install nvm
|
||||||
ansible.builtin.shell: >
|
ansible.builtin.shell: >
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
args:
|
args:
|
||||||
creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"
|
creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"
|
||||||
```
|
```
|
||||||
@@ -320,7 +321,7 @@ If you have `git` installed (requires git v1.7.10+):
|
|||||||
|
|
||||||
1. clone this repo in the root of your user profile
|
1. clone this repo in the root of your user profile
|
||||||
- `cd ~/` from anywhere then `git clone https://github.com/nvm-sh/nvm.git .nvm`
|
- `cd ~/` from anywhere then `git clone https://github.com/nvm-sh/nvm.git .nvm`
|
||||||
1. `cd ~/.nvm` and check out the latest version with `git checkout v0.40.4`
|
1. `cd ~/.nvm` and check out the latest version with `git checkout v0.40.5`
|
||||||
1. activate `nvm` by sourcing it from your shell: `. ./nvm.sh`
|
1. activate `nvm` by sourcing it from your shell: `. ./nvm.sh`
|
||||||
|
|
||||||
Now add these lines to your `~/.bashrc`, `~/.profile`, or `~/.zshrc` file to have it automatically sourced upon login:
|
Now add these lines to your `~/.bashrc`, `~/.profile`, or `~/.zshrc` file to have it automatically sourced upon login:
|
||||||
@@ -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:
|
||||||
|
|
||||||
@@ -945,13 +958,13 @@ If installing nvm on Alpine Linux *is* still what you want or need to do, you sh
|
|||||||
### Alpine Linux 3.13+
|
### Alpine Linux 3.13+
|
||||||
```sh
|
```sh
|
||||||
apk add -U curl bash ca-certificates openssl ncurses coreutils python3 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
|
apk add -U curl bash ca-certificates openssl ncurses coreutils python3 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
### Alpine Linux 3.5 - 3.12
|
### Alpine Linux 3.5 - 3.12
|
||||||
```sh
|
```sh
|
||||||
apk add -U curl bash ca-certificates openssl ncurses coreutils python2 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
|
apk add -U curl bash ca-certificates openssl ncurses coreutils python2 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
_Note: Alpine 3.5 can only install NodeJS versions up to v6.9.5, Alpine 3.6 can only install versions up to v6.10.3, Alpine 3.7 installs versions up to v8.9.3, Alpine 3.8 installs versions up to v8.14.0, Alpine 3.9 installs versions up to v10.19.0, Alpine 3.10 installs versions up to v10.24.1, Alpine 3.11 installs versions up to v12.22.6, Alpine 3.12 installs versions up to v12.22.12, Alpine 3.13 & 3.14 install versions up to v14.20.0, Alpine 3.15 & 3.16 install versions up to v16.16.0 (**These are all versions on the main branch**). Alpine 3.5 - 3.12 required the package `python2` to build NodeJS, as they are older versions to build. Alpine 3.13+ requires `python3` to successfully build newer NodeJS versions, but you can use `python2` with Alpine 3.13+ if you need to build versions of node supported in Alpine 3.5 - 3.15, you just need to specify what version of NodeJS you need to install in the package install script._
|
_Note: Alpine 3.5 can only install NodeJS versions up to v6.9.5, Alpine 3.6 can only install versions up to v6.10.3, Alpine 3.7 installs versions up to v8.9.3, Alpine 3.8 installs versions up to v8.14.0, Alpine 3.9 installs versions up to v10.19.0, Alpine 3.10 installs versions up to v10.24.1, Alpine 3.11 installs versions up to v12.22.6, Alpine 3.12 installs versions up to v12.22.12, Alpine 3.13 & 3.14 install versions up to v14.20.0, Alpine 3.15 & 3.16 install versions up to v16.16.0 (**These are all versions on the main branch**). Alpine 3.5 - 3.12 required the package `python2` to build NodeJS, as they are older versions to build. Alpine 3.13+ requires `python3` to successfully build newer NodeJS versions, but you can use `python2` with Alpine 3.13+ if you need to build versions of node supported in Alpine 3.5 - 3.15, you just need to specify what version of NodeJS you need to install in the package install script._
|
||||||
@@ -1054,9 +1067,9 @@ You have to make sure that the user directory name in `$HOME` and the user direc
|
|||||||
To change the user directory and/or account name follow the instructions [here](https://support.apple.com/en-us/HT201548)
|
To change the user directory and/or account name follow the instructions [here](https://support.apple.com/en-us/HT201548)
|
||||||
|
|
||||||
[1]: https://github.com/nvm-sh/nvm.git
|
[1]: https://github.com/nvm-sh/nvm.git
|
||||||
[2]: https://github.com/nvm-sh/nvm/blob/v0.40.4/install.sh
|
[2]: https://github.com/nvm-sh/nvm/blob/v0.40.5/install.sh
|
||||||
[3]: https://github.com/nvm-sh/nvm/actions/workflows/tests-fast.yml
|
[3]: https://github.com/nvm-sh/nvm/actions/workflows/tests-fast.yml
|
||||||
[4]: https://github.com/nvm-sh/nvm/releases/tag/v0.40.4
|
[4]: https://github.com/nvm-sh/nvm/releases/tag/v0.40.5
|
||||||
[Urchin]: https://git.sdf.org/tlevine/urchin
|
[Urchin]: https://git.sdf.org/tlevine/urchin
|
||||||
[Fish]: https://fishshell.com
|
[Fish]: https://fishshell.com
|
||||||
|
|
||||||
@@ -1114,7 +1127,7 @@ Here's what you will need to do:
|
|||||||
If one of these broken versions is installed on your system, the above step will likely still succeed even if you didn't include the `--shared-zlib` flag.
|
If one of these broken versions is installed on your system, the above step will likely still succeed even if you didn't include the `--shared-zlib` flag.
|
||||||
However, later, when you attempt to `npm install` something using your old version of node.js, you will see `incorrect data check` errors.
|
However, later, when you attempt to `npm install` something using your old version of node.js, you will see `incorrect data check` errors.
|
||||||
If you want to avoid the possible hassle of dealing with this, include that flag.
|
If you want to avoid the possible hassle of dealing with this, include that flag.
|
||||||
For more details, see [this issue](https://github.com/nodejs/node/issues/39313) and [this comment](https://github.com/nodejs/node/issues/39313#issuecomment-90.40.476)
|
For more details, see [this issue](https://github.com/nodejs/node/issues/39313) and [this comment](https://github.com/nodejs/node/issues/39313#issuecomment-90.40.576)
|
||||||
|
|
||||||
- Exit back to your native shell.
|
- Exit back to your native shell.
|
||||||
|
|
||||||
@@ -1141,7 +1154,7 @@ Now you should be able to use node as usual.
|
|||||||
If you've encountered this error on WSL-2:
|
If you've encountered this error on WSL-2:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
|
||||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||||
Dload Upload Total Spent Left Speed
|
Dload Upload Total Spent Left Speed
|
||||||
0 0 0 0 0 0 0 0 --:--:-- 0:00:09 --:--:-- 0curl: (6) Could not resolve host: raw.githubusercontent.com
|
0 0 0 0 0 0 0 0 --:--:-- 0:00:09 --:--:-- 0curl: (6) Could not resolve host: raw.githubusercontent.com
|
||||||
@@ -1176,7 +1189,7 @@ Currently, the sole maintainer is [@ljharb](https://github.com/ljharb) - more ma
|
|||||||
|
|
||||||
## Project Support
|
## Project Support
|
||||||
|
|
||||||
Only the latest version (v0.40.4 at this time) is supported.
|
Only the latest version (v0.40.5 at this time) is supported.
|
||||||
|
|
||||||
## Enterprise Support
|
## Enterprise Support
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ nvm_install_dir() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nvm_latest_version() {
|
nvm_latest_version() {
|
||||||
nvm_echo "v0.40.4"
|
nvm_echo "v0.40.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_profile_is_bash_or_zsh() {
|
nvm_profile_is_bash_or_zsh() {
|
||||||
|
|||||||
@@ -115,47 +115,62 @@ nvm_get_latest() {
|
|||||||
nvm_echo "${NVM_LATEST_URL##*/}"
|
nvm_echo "${NVM_LATEST_URL##*/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Every argument is passed through as a literal argv element so that untrusted,
|
||||||
|
# mirror-supplied version strings in the URLs are never re-parsed by the shell
|
||||||
|
# (which would allow command substitution / OS command injection).
|
||||||
nvm_download() {
|
nvm_download() {
|
||||||
if nvm_has "curl"; then
|
|
||||||
local CURL_COMPRESSED_FLAG=""
|
|
||||||
local CURL_HEADER_FLAG=""
|
|
||||||
local sanitized_header
|
local sanitized_header
|
||||||
|
sanitized_header=''
|
||||||
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
||||||
sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")
|
sanitized_header="$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")"
|
||||||
CURL_HEADER_FLAG="--header \"Authorization: ${sanitized_header}\""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local NVM_DOWNLOADER
|
||||||
|
NVM_DOWNLOADER=''
|
||||||
|
if nvm_has "curl"; then
|
||||||
|
NVM_DOWNLOADER='curl'
|
||||||
|
set -- -q --fail "$@"
|
||||||
if nvm_curl_use_compression; then
|
if nvm_curl_use_compression; then
|
||||||
CURL_COMPRESSED_FLAG="--compressed"
|
set -- --compressed "$@"
|
||||||
fi
|
fi
|
||||||
local NVM_DOWNLOAD_ARGS
|
|
||||||
NVM_DOWNLOAD_ARGS=''
|
|
||||||
for arg in "$@"; do
|
|
||||||
NVM_DOWNLOAD_ARGS="${NVM_DOWNLOAD_ARGS} \"$arg\""
|
|
||||||
done
|
|
||||||
eval "curl -q --fail ${CURL_COMPRESSED_FLAG:-} ${CURL_HEADER_FLAG:-} ${NVM_DOWNLOAD_ARGS}"
|
|
||||||
elif nvm_has "wget"; then
|
elif nvm_has "wget"; then
|
||||||
|
NVM_DOWNLOADER='wget'
|
||||||
# Emulate curl with wget
|
# Emulate curl with wget
|
||||||
ARGS=$(nvm_echo "$@" | command sed "
|
local NVM_DOWNLOAD_WGET_COUNT
|
||||||
s/--progress-bar /--progress=bar /
|
NVM_DOWNLOAD_WGET_COUNT=$#
|
||||||
s/--compressed //
|
local NVM_DOWNLOAD_WGET_SKIP
|
||||||
s/--fail //
|
NVM_DOWNLOAD_WGET_SKIP=0
|
||||||
s/-L //
|
local NVM_DOWNLOAD_WGET_ARG
|
||||||
s/-I /--server-response /
|
for NVM_DOWNLOAD_WGET_ARG in "$@"; do
|
||||||
s/-s /-q /
|
if [ "${NVM_DOWNLOAD_WGET_SKIP}" = '1' ]; then
|
||||||
s/-sS /-nv /
|
NVM_DOWNLOAD_WGET_SKIP=0
|
||||||
s/-o /-O /
|
continue
|
||||||
s/-C - /-c /
|
fi
|
||||||
")
|
case "${NVM_DOWNLOAD_WGET_ARG}" in
|
||||||
|
'--progress-bar') set -- "$@" '--progress=bar' ;;
|
||||||
|
'--compressed') : ;;
|
||||||
|
'--fail') : ;;
|
||||||
|
'-L') : ;;
|
||||||
|
'-I') set -- "$@" '--server-response' ;;
|
||||||
|
'-s') set -- "$@" '-q' ;;
|
||||||
|
'-sS') set -- "$@" '-nv' ;;
|
||||||
|
'-o') set -- "$@" '-O' ;;
|
||||||
|
'-C') NVM_DOWNLOAD_WGET_SKIP=1; set -- "$@" '-c' ;;
|
||||||
|
*) set -- "$@" "${NVM_DOWNLOAD_WGET_ARG}" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift "${NVM_DOWNLOAD_WGET_COUNT}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${NVM_DOWNLOADER}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
|
||||||
sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")
|
set -- "$@" --header "Authorization: ${sanitized_header}"
|
||||||
ARGS="${ARGS} --header \"${sanitized_header}\""
|
|
||||||
fi
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
eval wget $ARGS
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
"${NVM_DOWNLOADER}" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_sanitize_auth_header() {
|
nvm_sanitize_auth_header() {
|
||||||
@@ -607,7 +622,7 @@ nvm_rc_version() {
|
|||||||
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
|
||||||
@@ -1912,7 +1927,7 @@ nvm_get_checksum() {
|
|||||||
SHASUMS_URL="${MIRROR}/${3}/SHASUMS.txt"
|
SHASUMS_URL="${MIRROR}/${3}/SHASUMS.txt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
nvm_download -L -s "${SHASUMS_URL}" -o - | command awk "{ if (\"${4}.${5}\" == \$2) print \$1}"
|
nvm_download -L -s "${SHASUMS_URL}" -o - | command awk -v tarball="${4}.${5}" '{ if (tarball == $2) print $1 }'
|
||||||
}
|
}
|
||||||
|
|
||||||
nvm_print_versions() {
|
nvm_print_versions() {
|
||||||
@@ -2491,10 +2506,16 @@ nvm_download_artifact() {
|
|||||||
local VERSION
|
local VERSION
|
||||||
VERSION="${4}"
|
VERSION="${4}"
|
||||||
|
|
||||||
if [ -z "${VERSION}" ]; then
|
case "${VERSION}" in
|
||||||
|
'')
|
||||||
nvm_err 'A version number is required.'
|
nvm_err 'A version number is required.'
|
||||||
return 3
|
return 3
|
||||||
fi
|
;;
|
||||||
|
*[!0-9A-Za-z._+-]*)
|
||||||
|
nvm_err 'Invalid version: contains disallowed characters'
|
||||||
|
return 3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if [ "${KIND}" = 'binary' ] && ! nvm_binary_available "${VERSION}"; then
|
if [ "${KIND}" = 'binary' ] && ! nvm_binary_available "${VERSION}"; then
|
||||||
nvm_err "No precompiled binary available for ${VERSION}."
|
nvm_err "No precompiled binary available for ${VERSION}."
|
||||||
@@ -3201,7 +3222,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.'
|
||||||
@@ -3218,23 +3239,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'
|
||||||
@@ -3255,7 +3276,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'
|
||||||
@@ -3317,7 +3338,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
|
||||||
@@ -3573,7 +3596,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
|
||||||
@@ -3711,10 +3736,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
|
||||||
@@ -3732,7 +3757,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
|
||||||
@@ -3831,7 +3856,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
|
||||||
|
|
||||||
@@ -4020,7 +4048,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
|
||||||
|
|
||||||
@@ -4144,7 +4174,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
|
||||||
@@ -4158,6 +4190,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}")" ||:
|
||||||
@@ -4215,19 +4255,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
|
||||||
@@ -4362,7 +4419,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
|
||||||
|
|
||||||
@@ -4459,7 +4518,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
|
||||||
@@ -4496,7 +4556,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
|
||||||
|
|
||||||
@@ -4504,7 +4565,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
|
||||||
|
|
||||||
@@ -4602,7 +4664,7 @@ nvm() {
|
|||||||
NVM_VERSION_ONLY=true NVM_LTS="${NVM_LTS-}" nvm_remote_version "${PATTERN:-node}"
|
NVM_VERSION_ONLY=true NVM_LTS="${NVM_LTS-}" nvm_remote_version "${PATTERN:-node}"
|
||||||
;;
|
;;
|
||||||
"--version" | "-v")
|
"--version" | "-v")
|
||||||
nvm_echo '0.40.4'
|
nvm_echo '0.40.5'
|
||||||
;;
|
;;
|
||||||
"unload")
|
"unload")
|
||||||
nvm deactivate >/dev/null 2>&1
|
nvm deactivate >/dev/null 2>&1
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nvm",
|
"name": "nvm",
|
||||||
"version": "0.40.4",
|
"version": "0.40.5",
|
||||||
"description": "Node Version Manager - Simple bash script to manage multiple active node.js versions",
|
"description": "Node Version Manager - Simple bash script to manage multiple active node.js versions",
|
||||||
"directories": {
|
"directories": {
|
||||||
"test": "test"
|
"test": "test"
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
cleanup () {
|
cleanup () {
|
||||||
unset -f die cleanup
|
unset -f die cleanup
|
||||||
docker stop httpbin && docker rm httpbin
|
docker rm -f httpbin >/dev/null 2>&1 || true
|
||||||
}
|
}
|
||||||
die () { echo "$@" ; cleanup ; exit 1; }
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
@@ -17,13 +17,24 @@ nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh" >/de
|
|||||||
# nvm_download should fail to download wrong_install.sh
|
# nvm_download should fail to download wrong_install.sh
|
||||||
! nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/wrong_install.sh" >/dev/null || die "nvm_download should fail to download no existing file"
|
! nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/wrong_install.sh" >/dev/null || die "nvm_download should fail to download no existing file"
|
||||||
|
|
||||||
# nvm_download should pass when calling with auth header
|
# the auth header checks need a local httpbin container; retry the pull, and
|
||||||
docker pull kennethreitz/httpbin && SHELL=bash docker run -d --name httpbin -p 80:80 kennethreitz/httpbin
|
# skip (rather than fail) if the image cannot be pulled or run, so a transient
|
||||||
sleep 1 # wait for httpbin to start
|
# Docker registry outage does not fail the suite
|
||||||
NVM_AUTH_HEADER="Bearer test-token" nvm_download "http://127.0.0.1/bearer" > /dev/null || die 'nvm_download with auth header should send correctly'
|
httpbin_pulled=0
|
||||||
|
for i in 1 2 3 4 5; do
|
||||||
# nvm_download should fail when calling without auth header
|
if docker pull kennethreitz/httpbin; then httpbin_pulled=1; break; fi
|
||||||
nvm_download "http://127.0.0.1/bearer" > /dev/null && die 'nvm_download with no auth header should not send the header and should fail'
|
echo "docker pull httpbin failed, attempt $i/5"
|
||||||
|
sleep $((i * 5))
|
||||||
|
done
|
||||||
|
if [ "${httpbin_pulled}" = 1 ] && SHELL=bash docker run -d --name httpbin -p 80:80 kennethreitz/httpbin; then
|
||||||
|
sleep 1 # wait for httpbin to start
|
||||||
|
# nvm_download should pass when calling with auth header
|
||||||
|
NVM_AUTH_HEADER="Bearer test-token" nvm_download "http://127.0.0.1/bearer" > /dev/null || die 'nvm_download with auth header should send correctly'
|
||||||
|
# nvm_download should fail when calling without auth header
|
||||||
|
nvm_download "http://127.0.0.1/bearer" > /dev/null && die 'nvm_download with no auth header should not send the header and should fail'
|
||||||
|
else
|
||||||
|
echo 'skipping auth header checks: unable to pull or run httpbin'
|
||||||
|
fi
|
||||||
|
|
||||||
# ensure quoted extra args remain quoted
|
# ensure quoted extra args remain quoted
|
||||||
nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh" -o "; die quoted-command-not-quoted" || die 'command failed'
|
nvm_download "https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh" -o "; die quoted-command-not-quoted" || die 'command failed'
|
||||||
|
|||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
WORK="$PWD/nvm_download-noeval-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
ARGV_LOG="$WORK/argv.log"
|
||||||
|
PROOF="$WORK/nvm_injection_proof"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
unset -f die cleanup
|
||||||
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
|
}
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
|
||||||
|
mkdir -p "$TEST_BIN"
|
||||||
|
|
||||||
|
# fake curl/wget: record each received argument verbatim, then succeed
|
||||||
|
{
|
||||||
|
echo '#!/bin/sh'
|
||||||
|
echo ': > "$ARGV_LOG"'
|
||||||
|
echo 'for a in "$@"; do printf "%s\n" "$a" >> "$ARGV_LOG"; done'
|
||||||
|
echo 'exit 0'
|
||||||
|
} > "$TEST_BIN/curl"
|
||||||
|
chmod +x "$TEST_BIN/curl"
|
||||||
|
cp "$TEST_BIN/curl" "$TEST_BIN/wget"
|
||||||
|
|
||||||
|
export ARGV_LOG
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
|
||||||
|
# given a url containing command-substitution syntax (mirror-supplied)
|
||||||
|
INJECT_URL="http://example.test/v1\$(touch ${PROOF})/x.tar.gz"
|
||||||
|
|
||||||
|
# when nvm_download is invoked (curl path)
|
||||||
|
rm -f "$PROOF"
|
||||||
|
nvm_download "$INJECT_URL" -o - || die 'nvm_download (curl) returned nonzero on injection url'
|
||||||
|
# then the substitution must not have executed
|
||||||
|
[ ! -e "$PROOF" ] || die "command injection fired via curl path: proof file was created"
|
||||||
|
# and curl must have received the url as one literal argument
|
||||||
|
grep -Fxq "$INJECT_URL" "$ARGV_LOG" || die "curl did not receive the url as a single literal argument; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
# given a normal download (curl path)
|
||||||
|
URL="https://nodejs.org/dist/index.tab"
|
||||||
|
FILE="$WORK/target"
|
||||||
|
# when invoked with -L -s URL -o FILE
|
||||||
|
nvm_download -L -s "$URL" -o "$FILE" || die 'nvm_download (curl) returned nonzero on normal url'
|
||||||
|
# then the url, -o, and output file are passed through verbatim
|
||||||
|
grep -Fxq "$URL" "$ARGV_LOG" || die "curl did not receive the url; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "-o" "$ARGV_LOG" || die "curl did not receive -o; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxq "$FILE" "$ARGV_LOG" || die "curl did not receive the output file; got: $(cat "$ARGV_LOG")"
|
||||||
|
# and curl-style flags are passed through verbatim (curl keeps -s; it is not translated to wget's -q)
|
||||||
|
grep -Fxqe "-s" "$ARGV_LOG" || die "curl did not receive -s verbatim; got: $(cat "$ARGV_LOG")"
|
||||||
|
rm -f "$FILE"
|
||||||
|
|
||||||
|
# given curl is unavailable (the wget-path calls run with PATH limited to our
|
||||||
|
# fake wget, so neither the fake nor the system curl is found)
|
||||||
|
rm -f "$TEST_BIN/curl"
|
||||||
|
|
||||||
|
# when nvm_download is invoked with the injection url (wget path)
|
||||||
|
rm -f "$PROOF"
|
||||||
|
( PATH="$TEST_BIN"; export PATH; nvm_download "$INJECT_URL" -o - ) || die 'nvm_download (wget) returned nonzero on injection url'
|
||||||
|
# then the substitution must not have executed
|
||||||
|
[ ! -e "$PROOF" ] || die "command injection fired via wget path: proof file was created"
|
||||||
|
grep -Fxq "$INJECT_URL" "$ARGV_LOG" || die "wget did not receive the url as a single literal argument; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
# when invoked with -L -C - --progress-bar URL -o FILE (wget path)
|
||||||
|
( PATH="$TEST_BIN"; export PATH; nvm_download -L -C - --progress-bar "$URL" -o "$FILE" ) || die 'nvm_download (wget) returned nonzero on normal url'
|
||||||
|
# then flags are translated to wget equivalents
|
||||||
|
grep -Fxqe "-c" "$ARGV_LOG" || die "wget did not translate -C - to -c; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "--progress=bar" "$ARGV_LOG" || die "wget did not translate --progress-bar; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "-O" "$ARGV_LOG" || die "wget did not translate -o to -O; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "-L" "$ARGV_LOG" && die "wget should drop -L; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "-C" "$ARGV_LOG" && die "wget should not pass -C through; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxqe "-" "$ARGV_LOG" && die "wget should drop the lone - after -C; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
# when invoked with -s (wget path)
|
||||||
|
( PATH="$TEST_BIN"; export PATH; nvm_download -L -s "$URL" -o "$FILE" ) || die 'nvm_download (wget) returned nonzero on -s url'
|
||||||
|
# then -s becomes -q
|
||||||
|
grep -Fxqe "-q" "$ARGV_LOG" || die "wget did not translate -s to -q; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
echo "nvm_download no eval injection: passed"
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
WORK="$PWD/nvm_download-wgetauth-work.$$"
|
||||||
|
TEST_BIN="$WORK/bin"
|
||||||
|
ARGV_LOG="$WORK/argv.log"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
unset -f die cleanup nvm_has
|
||||||
|
rm -rf "$WORK"
|
||||||
|
export PATH="$OLDPATH"
|
||||||
|
}
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
OLDPATH="$PATH"
|
||||||
|
|
||||||
|
mkdir -p "$TEST_BIN"
|
||||||
|
|
||||||
|
# fake wget: record each received argument verbatim, then succeed
|
||||||
|
{
|
||||||
|
echo '#!/bin/sh'
|
||||||
|
echo ': > "$ARGV_LOG"'
|
||||||
|
echo 'for a in "$@"; do printf "%s\n" "$a" >> "$ARGV_LOG"; done'
|
||||||
|
echo 'exit 0'
|
||||||
|
} > "$TEST_BIN/wget"
|
||||||
|
chmod +x "$TEST_BIN/wget"
|
||||||
|
|
||||||
|
export ARGV_LOG
|
||||||
|
export PATH="$TEST_BIN:$OLDPATH"
|
||||||
|
# force the wget path while keeping system tools (sed) available for sanitization
|
||||||
|
nvm_has() { [ "$1" != curl ] && command -v "$1" >/dev/null 2>&1; }
|
||||||
|
|
||||||
|
# given an Authorization credential in NVM_AUTH_HEADER
|
||||||
|
# when nvm_download uses the wget path
|
||||||
|
NVM_AUTH_HEADER='Bearer test-token' nvm_download "https://nodejs.org/dist/x" -o - || die 'nvm_download (wget) returned nonzero'
|
||||||
|
# then wget receives a well-formed Authorization header (with the header name, like the curl path)
|
||||||
|
grep -Fxqe '--header' "$ARGV_LOG" || die "wget did not receive --header; got: $(cat "$ARGV_LOG")"
|
||||||
|
grep -Fxq 'Authorization: Bearer test-token' "$ARGV_LOG" || die "wget did not receive a well-formed Authorization header; got: $(cat "$ARGV_LOG")"
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
echo "nvm_download wget Authorization header: passed"
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="${TMPDIR:-/tmp}/nvm_version_injection.$$"
|
||||||
|
PROOF="${WORK}/PWNED"
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
unset -f die cleanup nvm_download
|
||||||
|
rm -rf "${WORK}"
|
||||||
|
}
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
mkdir -p "${WORK}"
|
||||||
|
export NVM_DIR="${WORK}"
|
||||||
|
|
||||||
|
# GHSA-3c52-35h2-gfmm: a mirror-supplied version with shell/awk metacharacters
|
||||||
|
# must be rejected before it is used in URLs, paths, or awk. Neutralize network.
|
||||||
|
nvm_download () { return 0; }
|
||||||
|
|
||||||
|
# given a version containing command-substitution syntax
|
||||||
|
# when nvm_download_artifact is asked to download it
|
||||||
|
# then it is rejected for disallowed characters and nothing is executed
|
||||||
|
rm -f "${PROOF}"
|
||||||
|
out="$(nvm_download_artifact node source std 'v1$(touch '"${PROOF}"')' 2>&1 </dev/null)"
|
||||||
|
case "${out}" in
|
||||||
|
*'disallowed characters'*) : ;;
|
||||||
|
*) die "command-substitution version was not rejected; got: ${out}" ;;
|
||||||
|
esac
|
||||||
|
[ ! -e "${PROOF}" ] || die 'command-substitution payload executed via nvm_download_artifact'
|
||||||
|
|
||||||
|
# and an awk-breakout version is likewise rejected
|
||||||
|
out="$(nvm_download_artifact node source std 'v1"==$2){system("x")}#' 2>&1 </dev/null)"
|
||||||
|
case "${out}" in
|
||||||
|
*'disallowed characters'*) : ;;
|
||||||
|
*) die "awk-style version was not rejected; got: ${out}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# and a legitimate nightly version must NOT be rejected by the character guard
|
||||||
|
out="$(nvm_download_artifact node source std 'v22.0.0-nightly20240101abcdef' 2>&1 </dev/null)"
|
||||||
|
case "${out}" in
|
||||||
|
*'disallowed characters'*) die 'a legitimate nightly version was wrongly rejected by the guard' ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
echo 'nvm_download_artifact version injection: passed'
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
WORK="${TMPDIR:-/tmp}/nvm_get_checksum_awk.$$"
|
||||||
|
PROOF="${WORK}/PWNED"
|
||||||
|
|
||||||
|
cleanup () {
|
||||||
|
unset -f die cleanup nvm_download
|
||||||
|
rm -rf "${WORK}"
|
||||||
|
}
|
||||||
|
die () { echo "$@" ; cleanup ; exit 1; }
|
||||||
|
|
||||||
|
\. ../../../nvm.sh
|
||||||
|
|
||||||
|
mkdir -p "${WORK}"
|
||||||
|
|
||||||
|
# GHSA-3c52-35h2-gfmm: nvm_get_checksum must treat the (untrusted, version-derived)
|
||||||
|
# slug as awk data, never as awk program text.
|
||||||
|
# given a crafted slug carrying an unconditional awk system() action
|
||||||
|
# and a mock that supplies one SHASUMS record (so such an action would fire)
|
||||||
|
nvm_download () { printf 'deadbeef sometarball\n'; }
|
||||||
|
# when nvm_get_checksum runs with that slug as its 4th argument
|
||||||
|
rm -f "${PROOF}"
|
||||||
|
nvm_get_checksum node std v1 'x" == $2) print $1} {system("touch${IFS}'"$PROOF"'")} #' tar.gz >/dev/null 2>&1
|
||||||
|
# then the injected awk code must not execute
|
||||||
|
[ ! -e "${PROOF}" ] || die 'awk injection fires in nvm_get_checksum (slug interpolated into awk program text)'
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
echo 'nvm_get_checksum awk injection: passed'
|
||||||
@@ -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
|
||||||
@@ -17,6 +17,9 @@ NVM_ENV=testing \. ../../install.sh
|
|||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
|
git config --global gc.autoDetach false
|
||||||
|
git config --global maintenance.auto false
|
||||||
|
|
||||||
# nvm_do_install is available
|
# nvm_do_install is available
|
||||||
type install_nvm_from_git > /dev/null 2>&1 || die 'install_nvm_from_git is not available'
|
type install_nvm_from_git > /dev/null 2>&1 || die 'install_nvm_from_git is not available'
|
||||||
|
|
||||||
@@ -61,7 +64,7 @@ test_install_data() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local head_ref="$(git for-each-ref --points-at HEAD --format='%(refname:short)' 'refs/tags/')"
|
local head_ref="$(git for-each-ref --points-at HEAD --format='%(refname:short)' 'refs/tags/')"
|
||||||
if [ -n "${avoid_ref}" ] && [ "${head_ref}" != "${avoid_ref}"]; then
|
if [ -n "${avoid_ref}" ] && [ "${head_ref}" != "${avoid_ref}" ]; then
|
||||||
echo "${current_ref}" | grep -q "$avoid_ref" && die "install_nvm_from_git ${message} did clone with unwanted ref ${avoid_ref}"
|
echo "${current_ref}" | grep -q "$avoid_ref" && die "install_nvm_from_git ${message} did clone with unwanted ref ${avoid_ref}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -94,14 +97,14 @@ test_install() {
|
|||||||
test_step "Clones repo $message"
|
test_step "Clones repo $message"
|
||||||
install_nvm_from_git
|
install_nvm_from_git
|
||||||
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
||||||
rm -rf "$NVM_DIR"
|
rm -rf "$NVM_DIR" || { sleep 1; rm -rf "$NVM_DIR"; }
|
||||||
|
|
||||||
# Ensure it initializes the repository for an empty existing repository
|
# Ensure it initializes the repository for an empty existing repository
|
||||||
mkdir -p "$NVM_DIR" || die 'Unable to create directory'
|
mkdir -p "$NVM_DIR" || die 'Unable to create directory'
|
||||||
test_step "Initialize repo $message"
|
test_step "Initialize repo $message"
|
||||||
install_nvm_from_git
|
install_nvm_from_git
|
||||||
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
||||||
rm -rf "$NVM_DIR"
|
rm -rf "$NVM_DIR" || { sleep 1; rm -rf "$NVM_DIR"; }
|
||||||
|
|
||||||
# Ensure it updates the repository for an existing git repository
|
# Ensure it updates the repository for an existing git repository
|
||||||
git clone "$(nvm_source "git")" -b "v0.36.0" --depth=2 "$NVM_DIR" || die 'Unable to clone repository'
|
git clone "$(nvm_source "git")" -b "v0.36.0" --depth=2 "$NVM_DIR" || die 'Unable to clone repository'
|
||||||
@@ -109,7 +112,7 @@ test_install() {
|
|||||||
test_step "Updates repo $message"
|
test_step "Updates repo $message"
|
||||||
install_nvm_from_git
|
install_nvm_from_git
|
||||||
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
test_install_data "$(get_head_ref)" "$(get_head_changeset)" "$message" "$ref" "$changeset" "$avoid_ref"
|
||||||
rm -rf "$NVM_DIR"
|
rm -rf "$NVM_DIR" || { sleep 1; rm -rf "$NVM_DIR"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Handle latest version
|
# Handle latest version
|
||||||
|
|||||||
@@ -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.0 || die "npm install -g is-nan failed"
|
||||||
|
npm list --global | 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 | 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 | 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 | 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 | 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
|
||||||
|
|||||||
Reference in New Issue
Block a user