mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-07-19 21:38:24 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2f0b5b57c | ||
|
|
207465dd36 | ||
|
|
c30ed0b1d3 | ||
|
|
0e74b147d6 |
@@ -8,7 +8,6 @@ test/bak
|
||||
.urchin.log
|
||||
.urchin_stdout
|
||||
test/**/test_output
|
||||
test/**/.nvmrc
|
||||
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
# Incident Response Process for **nvm**
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We take the security of **nvm** very seriously. If you believe you’ve found a security vulnerability, please inform us responsibly through coordinated disclosure.
|
||||
|
||||
### How to Report
|
||||
|
||||
> **Do not** report security vulnerabilities through public GitHub issues, discussions, or social media.
|
||||
|
||||
Instead, please use one of these secure channels:
|
||||
|
||||
1. **GitHub Security Advisories**
|
||||
Use the **Report a vulnerability** button in the Security tab of the [nvm-sh/nvm repository](https://github.com/nvm-sh/nvm).
|
||||
|
||||
2. **Email**
|
||||
Follow the posted [Security Policy](https://github.com/nvm-sh/nvm/security/policy).
|
||||
|
||||
### What to Include
|
||||
|
||||
**Required Information:**
|
||||
- Brief description of the vulnerability type
|
||||
- Affected version(s) and components
|
||||
- Steps to reproduce the issue
|
||||
- Impact assessment (what an attacker could achieve)
|
||||
|
||||
**Helpful Additional Details:**
|
||||
- Full paths of affected scripts or files
|
||||
- Specific commit or branch where the issue exists
|
||||
- Required configuration to reproduce
|
||||
- Proof-of-concept code (if available)
|
||||
- Suggested mitigation or fix
|
||||
|
||||
## Our Response Process
|
||||
|
||||
**Timeline Commitments:**
|
||||
- **Initial acknowledgment**: Within 24 hours
|
||||
- **Detailed response**: Within 3 business days
|
||||
- **Status updates**: Every 7 days until resolved
|
||||
- **Resolution target**: 90 days for most issues
|
||||
|
||||
**What We’ll Do:**
|
||||
1. Acknowledge your report and assign a tracking ID
|
||||
2. Assess the vulnerability and determine severity
|
||||
3. Develop and test a fix
|
||||
4. Coordinate disclosure timeline with you
|
||||
5. Release a security update and publish an advisory and CVE
|
||||
6. Credit you in our security advisory (if desired)
|
||||
|
||||
## Disclosure Policy
|
||||
|
||||
- **Coordinated disclosure**: We’ll work with you on timing
|
||||
- **Typical timeline**: 90 days from report to public disclosure
|
||||
- **Early disclosure**: If actively exploited
|
||||
- **Delayed disclosure**: For complex issues
|
||||
|
||||
## Scope
|
||||
|
||||
**In Scope:**
|
||||
- **nvm** project (all supported versions)
|
||||
- Installation and update scripts (`install.sh`, `nvm.sh`)
|
||||
- Official documentation and CI/CD integrations
|
||||
- Dependencies with direct security implications
|
||||
|
||||
**Out of Scope:**
|
||||
- Third-party forks or mirrors
|
||||
- Platform-specific installs outside core scripts
|
||||
- Social engineering or physical attacks
|
||||
- Theoretical vulnerabilities without practical exploitation
|
||||
|
||||
## Security Measures
|
||||
|
||||
**Our Commitments:**
|
||||
- Regular vulnerability scanning via GitHub Actions
|
||||
- Automated security checks in CI/CD pipelines
|
||||
- Secure scripting practices and mandatory code review
|
||||
- Prompt patch releases for critical issues
|
||||
|
||||
**User Responsibilities:**
|
||||
- Keep **nvm** updated
|
||||
- Verify script downloads via PGP signatures
|
||||
- Follow secure configuration guidelines for shell environments
|
||||
|
||||
## Legal Safe Harbor
|
||||
|
||||
**We will NOT:**
|
||||
- Initiate legal action
|
||||
- Contact law enforcement
|
||||
- Suspend or terminate your access
|
||||
|
||||
**You must:**
|
||||
- Only test against your own installations
|
||||
- Not access, modify, or delete user data
|
||||
- Not degrade service availability
|
||||
- Not publicly disclose before coordinated disclosure
|
||||
- Act in good faith
|
||||
|
||||
## Recognition
|
||||
|
||||
- **Advisory Credits**: Credit in GitHub Security Advisories (unless anonymous)
|
||||
|
||||
## Security Updates
|
||||
|
||||
**Stay Informed:**
|
||||
- Subscribe to GitHub releases for **nvm**
|
||||
- Enable GitHub Security Advisory notifications
|
||||
|
||||
**Update Process:**
|
||||
- Patch releases (e.g., v0.40.3 → v0.40.4)
|
||||
- Out-of-band releases for critical issues
|
||||
- Advisories via GitHub Security Advisories
|
||||
|
||||
## Contact Information
|
||||
|
||||
- **Security reports**: Security tab of [nvm-sh/nvm](https://github.com/nvm-sh/nvm/security)
|
||||
- **General inquiries**: GitHub Discussions or Issues
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
---
|
||||
name: File an issue…
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Thank you for being interested in nvm! Please help us by filling out the following form if you‘re having trouble. If you have a feature request, or some other question, please feel free to clear out the form. Thanks! -->
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
+8
-16
@@ -1,13 +1,6 @@
|
||||
# Security
|
||||
|
||||
Please file a private vulnerability report via GitHub, email [@ljharb](https://github.com/ljharb), or see https://tidelift.com/security if you have a potential security vulnerability to report.
|
||||
|
||||
## Escalation
|
||||
|
||||
If you do not receive an acknowledgement of your report within 6 business days, or if you cannot find a private security contact for the project, you may escalate to the OpenJS Foundation CNA at `security@lists.openjsf.org`.
|
||||
|
||||
If the project acknowledges your report but does not provide any further response or engagement within 14 days, escalation is also appropriate.
|
||||
|
||||
Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
|
||||
|
||||
## OpenSSF CII Best Practices
|
||||
|
||||
@@ -19,17 +12,16 @@ There are three “tiers”: passing, silver, and gold.
|
||||
We meet 100% of the “passing” criteria.
|
||||
|
||||
### Silver
|
||||
We meet 100% of the “silver” criteria.
|
||||
We meet 95% of the “silver” criteria. The gaps are as follows:
|
||||
- we do not have a DCO or a CLA process for contributions.
|
||||
- because we only have one maintainer, the project has no way to continue if that maintainer stops being active.
|
||||
- we do not currently document “what the user can and cannot expect in terms of security” for our project. This is planned to be completed in 2023.
|
||||
|
||||
### Gold
|
||||
We meet 78% of the “gold” criteria. The gaps are as follows:
|
||||
- because we only have one maintainer, the project has no way to continue if that maintainer stops being active.
|
||||
We meet 65% of the “gold” criteria. The gaps are as follows:
|
||||
- we do not yet have the “silver” badge; see all the gaps above.
|
||||
- We do not include a copyright or license statement in each source file. Efforts are underway to change this archaic practice into a suggestion instead of a hard requirement.
|
||||
|
||||
## Threat Model
|
||||
|
||||
See [THREAT_MODEL.md](.github/THREAT_MODEL.md).
|
||||
|
||||
## Incident Response Plan
|
||||
|
||||
Please see our [Incident Response Plan](.github/INCIDENT_RESPONSE_PLAN.md).
|
||||
See [THREAT_MODEL.md](./THREAT_MODEL.md).
|
||||
|
||||
@@ -107,35 +107,3 @@ Additionally, the maintainer of a third-party dependency might introduce a vulne
|
||||
**Recommendation**: Third-party libraries should be kept up-to-date, applying patches to address publicly known vulnerabilities in a timely fashion.
|
||||
Monitoring and logging capabilities should also be in place to detect and respond to potential attacks.
|
||||
SLSA compliance may also be considered for further supply chain security hardening.
|
||||
|
||||
## Trust boundary: mirror payloads vs. mirror metadata
|
||||
|
||||
`nvm` fetches two very different kinds of data from a Node.js/io.js mirror (`nodejs.org`/`iojs.org` by default, or whatever `$NVM_NODEJS_ORG_MIRROR` and `$NVM_IOJS_ORG_MIRROR` point at), and they sit on opposite sides of a trust boundary:
|
||||
|
||||
- **Payloads** — the Node.js/io.js binaries and source tarballs that `nvm install` downloads, unpacks, compiles (for source installs), and runs.
|
||||
- **Metadata** — everything `nvm` parses *about* those payloads rather than executing: the `index.tab` version list (including each release's LTS codename), and the `SHASUMS`/`SHASUMS256` checksum files.
|
||||
|
||||
Conflating the two leads to mis-scoped reports, so the project draws the line explicitly.
|
||||
|
||||
### Payloads are trusted, by construction
|
||||
|
||||
The entire purpose of `nvm` is to download a mirror's build of Node.js and run it.
|
||||
A mirror that serves a backdoored binary has arbitrary code execution the moment you `nvm install` and invoke `node`, and no validation inside `nvm` can prevent that - you have chosen to execute that code.
|
||||
Installing from source (`nvm install -s`) is if anything more direct: the mirror-supplied source tarball is unpacked and its `configure`/`make` build runs arbitrary code on your machine *at install time*, before `node` is ever invoked.
|
||||
Checksum verification protects **integrity** (a corrupted or truncated download, or a network intermediary that cannot also forge the same-origin `SHASUMS`), not **authenticity** against the mirror itself, since the checksums come from the same origin as the payload.
|
||||
Selecting a mirror is therefore equivalent to selecting whom you trust for arbitrary code execution in your account.
|
||||
A malicious payload from the configured mirror is consequently **out of scope**: no privilege boundary is crossed, so there is no privilege to escalate.
|
||||
|
||||
### Metadata is not trusted
|
||||
|
||||
Parsing a version list is a pure data operation.
|
||||
A user who runs `nvm ls-remote` to browse available versions - and installs nothing - has not opted into running any code from the mirror.
|
||||
Metadata can also be attacker-controlled with no mirror misconfiguration at all, via a compromised mirror/CDN or a man-in-the-middle of the channel (see *Threat ID 3*), so it is treated as hostile input.
|
||||
The invariant `nvm` maintains is:
|
||||
|
||||
> Mirror-supplied metadata must never reach a shell/command evaluator, an `awk`/`sed` program body, or an unvalidated filesystem path (see *Threat ID 2*).
|
||||
|
||||
This is why version strings from `index.tab` are passed to the downloader as literal `argv` elements rather than re-parsed by the shell ([CVE-2026-10796](https://github.com/advisories/GHSA-3c52-35h2-gfmm), [CVE-2026-1665](https://github.com/advisories/GHSA-4fc5-r4vr-8rp7)); why checksum comparisons pass the mirror's values as `awk -v` **data** and never as program text; and why LTS codenames are constrained to safe alias filenames before naming a file under `$NVM_DIR/alias/lts`, so a hostile codename such as `../../../.bashrc` cannot traverse out of the alias directory.
|
||||
|
||||
The point is not that metadata is "more dangerous" than a payload — a trusted payload can obviously do anything.
|
||||
It is that metadata carries **no** implied grant of code execution, so any code-execution or arbitrary-write primitive reachable purely by parsing it is a defect worth removing on its own merits, independent of how much the payload channel is trusted.
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
name: "Code scanning - action"
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 17 * * 4'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
permissions:
|
||||
actions: read # for github/codeql-action/init to get workflow details
|
||||
contents: read # for actions/checkout to fetch code
|
||||
security-events: write # for github/codeql-action/autobuild to send a status report
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v4
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
@@ -37,11 +37,6 @@ jobs:
|
||||
matrix:
|
||||
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
include:
|
||||
- node-version: "21"
|
||||
- node-version: "20.5"
|
||||
- node-version: "20.4"
|
||||
- node-version: "14.17"
|
||||
- node-version: "14.16"
|
||||
- node-version: "9.2"
|
||||
- node-version: "9.1"
|
||||
- node-version: "9.0"
|
||||
@@ -63,7 +58,7 @@ jobs:
|
||||
iojs.org:443
|
||||
nodejs.org:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'install node'
|
||||
with:
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install ${{ matrix.node-version }} && npm install'
|
||||
with:
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
pkg-containers.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install ${{ matrix.node-version }} && npm install'
|
||||
with:
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install ${{ matrix.node-version }} && npm install'
|
||||
with:
|
||||
@@ -67,33 +67,6 @@ jobs:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
raw.githubusercontent.com:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: check tests filenames
|
||||
run: ./rename_test.sh --check
|
||||
|
||||
check_exec:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install lts/* && npm install'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- name: check that test files are executable
|
||||
run: npm run test:check-exec
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all linting'
|
||||
needs: [eclint, dockerfile_lint, doctoc, test_naming, check_exec]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
name: 'Update nodejs.org'
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'nvm version tag (e.g., v0.40.4). Defaults to the latest version tag.'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update-nodejs-org:
|
||||
if: github.repository == 'nvm-sh/nvm' && github.actor == 'ljharb'
|
||||
permissions:
|
||||
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'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
api.github.com:443
|
||||
|
||||
- name: Extract and validate version
|
||||
id: version
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
INPUT_VERSION="${{ inputs.version }}"
|
||||
|
||||
if [ -n "${INPUT_VERSION}" ]; then
|
||||
TAG="${INPUT_VERSION}"
|
||||
elif [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
else
|
||||
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
|
||||
|
||||
if ! printf '%s\n' "${TAG}" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
echo "::notice::Tag '${TAG}' does not match expected format vX.Y.Z, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf 'tag=%s\n' "${TAG}" >> "${GITHUB_OUTPUT}"
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
||||
- name: Set up fork and branch
|
||||
if: steps.version.outputs.tag
|
||||
id: fork
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
BRANCH="nvm-${{ steps.version.outputs.tag }}"
|
||||
|
||||
gh repo fork nodejs/nodejs.org --clone=false 2>&1 || true
|
||||
FORK_OWNER="$(gh api user --jq '.login')"
|
||||
|
||||
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')"
|
||||
|
||||
# Create or reset branch on fork to upstream HEAD
|
||||
if ! gh api "repos/${FORK_OWNER}/nodejs.org/git/refs" \
|
||||
-f "ref=refs/heads/${BRANCH}" \
|
||||
-f "sha=${UPSTREAM_SHA}" > /dev/null; then
|
||||
gh api "repos/${FORK_OWNER}/nodejs.org/git/refs/heads/${BRANCH}" \
|
||||
-X PATCH \
|
||||
-f "sha=${UPSTREAM_SHA}" \
|
||||
-F "force=true" > /dev/null
|
||||
fi
|
||||
|
||||
printf 'fork_owner=%s\n' "${FORK_OWNER}" >> "${GITHUB_OUTPUT}"
|
||||
printf 'branch=%s\n' "${BRANCH}" >> "${GITHUB_OUTPUT}"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NODEJS_ORG_TOKEN }}
|
||||
|
||||
- name: Update nvm version in English snippet
|
||||
if: steps.version.outputs.tag
|
||||
id: update
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
NEW_VERSION="${{ steps.version.outputs.tag }}"
|
||||
FORK_OWNER="${{ steps.fork.outputs.fork_owner }}"
|
||||
BRANCH="${{ steps.fork.outputs.branch }}"
|
||||
FILE_PATH="apps/site/snippets/en/download/nvm.bash"
|
||||
PATTERN='nvm-sh/nvm/v[0-9]+\.[0-9]+\.[0-9]+/install\.sh'
|
||||
REPLACEMENT="nvm-sh/nvm/${NEW_VERSION}/install.sh"
|
||||
|
||||
# Get file content via API
|
||||
FILE_RESPONSE="$(gh api "repos/${FORK_OWNER}/nodejs.org/contents/${FILE_PATH}?ref=${BRANCH}")"
|
||||
FILE_SHA="$(printf '%s' "${FILE_RESPONSE}" | jq -r '.sha')"
|
||||
printf '%s' "${FILE_RESPONSE}" | jq -r '.content' | base64 -d > "${RUNNER_TEMP}/nvm.bash"
|
||||
|
||||
# Validate exactly 1 match
|
||||
MATCH_COUNT="$(grep -cE "${PATTERN}" "${RUNNER_TEMP}/nvm.bash" || true)"
|
||||
|
||||
if [ "${MATCH_COUNT}" -eq 0 ]; then
|
||||
echo "::error::No nvm version pattern found in ${FILE_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${MATCH_COUNT}" -ne 1 ]; then
|
||||
echo "::error::Expected exactly 1 nvm version match in ${FILE_PATH}, found ${MATCH_COUNT}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Replace and check for changes
|
||||
cp "${RUNNER_TEMP}/nvm.bash" "${RUNNER_TEMP}/nvm.bash.orig"
|
||||
sed -i -E "s|${PATTERN}|${REPLACEMENT}|g" "${RUNNER_TEMP}/nvm.bash"
|
||||
|
||||
if cmp -s "${RUNNER_TEMP}/nvm.bash" "${RUNNER_TEMP}/nvm.bash.orig"; then
|
||||
echo "::notice::English snippet already has version ${NEW_VERSION}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! grep -qF "${REPLACEMENT}" "${RUNNER_TEMP}/nvm.bash"; then
|
||||
echo "::error::Replacement verification failed in ${FILE_PATH}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update file via GitHub API (avoids git push workflow scope requirement)
|
||||
NEW_CONTENT_B64="$(base64 -w 0 < "${RUNNER_TEMP}/nvm.bash")"
|
||||
gh api "repos/${FORK_OWNER}/nodejs.org/contents/${FILE_PATH}" \
|
||||
-X PUT \
|
||||
-f "message=meta: bump nvm to ${NEW_VERSION}" \
|
||||
-f "content=${NEW_CONTENT_B64}" \
|
||||
-f "sha=${FILE_SHA}" \
|
||||
-f "branch=${BRANCH}" \
|
||||
-f "committer[name]=github-actions[bot]" \
|
||||
-f "committer[email]=41898282+github-actions[bot]@users.noreply.github.com" > /dev/null
|
||||
|
||||
printf 'updated=true\n' >> "${GITHUB_OUTPUT}"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NODEJS_ORG_TOKEN }}
|
||||
|
||||
- name: Create pull request
|
||||
if: steps.update.outputs.updated
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
NEW_VERSION="${{ steps.version.outputs.tag }}"
|
||||
FORK_OWNER="${{ steps.fork.outputs.fork_owner }}"
|
||||
BRANCH="${{ steps.fork.outputs.branch }}"
|
||||
|
||||
BODY="Updates the English nvm install snippet to [\`${NEW_VERSION}\`](https://github.com/nvm-sh/nvm/releases/tag/${NEW_VERSION}). The translation system handles other locales.
|
||||
|
||||
Ref: https://github.com/nodejs/nodejs.org/issues/8628"
|
||||
|
||||
gh pr create \
|
||||
--repo nodejs/nodejs.org \
|
||||
--head "${FORK_OWNER}:${BRANCH}" \
|
||||
--title "meta: bump nvm to ${NEW_VERSION}" \
|
||||
--body "${BODY}"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.NODEJS_ORG_TOKEN }}
|
||||
@@ -1,135 +0,0 @@
|
||||
name: 'Tests: nvm install with set -e'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref:
|
||||
description: 'git ref to use'
|
||||
required: false
|
||||
default: 'HEAD'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.matrix.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- id: matrix
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "${{ github.event.inputs.ref }}" ]; then
|
||||
echo "matrix=\"[\"${{ github.event.inputs.ref }}\"]\"" >> $GITHUB_OUTPUT
|
||||
else
|
||||
TAGS="$((echo "HEAD" && git tag --sort=-v:refname --merged HEAD --format='%(refname:strip=2) %(creatordate:short)' | grep '^v' | while read tag date; do
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
timestamp=$(date -j -f "%Y-%m-%d" "$date" +%s)
|
||||
threshold=$(date -j -v-4y +%s)
|
||||
else
|
||||
timestamp=$(date -d "$date" +%s)
|
||||
threshold=$(date -d "4 years ago" +%s)
|
||||
fi
|
||||
if [ $timestamp -ge $threshold ]; then echo "$tag"; fi
|
||||
done) | xargs)"
|
||||
echo $TAGS
|
||||
TAGS_JSON=$(printf "%s\n" $TAGS | jq -R . | jq -sc .)
|
||||
echo "matrix=${TAGS_JSON}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
test:
|
||||
permissions:
|
||||
contents: read
|
||||
needs: [matrix]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ref: ${{ fromJson(needs.matrix.outputs.matrix) }}
|
||||
has-nvmrc:
|
||||
- 'no nvmrc'
|
||||
- 'nvmrc'
|
||||
shell-level:
|
||||
- 1 shlvl
|
||||
- 2 shlvls
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: resolve HEAD to sha
|
||||
run: |
|
||||
if [ '${{ matrix.ref }}' = 'HEAD' ]; then
|
||||
REF="$(git rev-parse HEAD)"
|
||||
else
|
||||
REF="${{ matrix.ref }}"
|
||||
fi
|
||||
echo "resolved ref: ${REF}"
|
||||
echo "ref="$REF"" >> $GITHUB_ENV
|
||||
- run: echo $- # which options are set
|
||||
- run: echo node > .nvmrc
|
||||
if: ${{ matrix.has-nvmrc == 'nvmrc' }}
|
||||
- run: curl -I --compressed -v https://nodejs.org/dist/
|
||||
- name: 'install nvm'
|
||||
run: |
|
||||
set -e
|
||||
export NVM_INSTALL_VERSION="${ref}"
|
||||
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
|
||||
id: nvm-version
|
||||
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||
run: |
|
||||
set +e
|
||||
. $NVM_DIR/nvm.sh && nvm --version
|
||||
- name: nvm install in 1 shell level, ${{ matrix.has-nvmrc }}
|
||||
id: install-1
|
||||
if: ${{ matrix.shell-level == '1 shlvl' }}
|
||||
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||
run: |
|
||||
set -ex
|
||||
. $NVM_DIR/nvm.sh
|
||||
echo nvm.sh sourced
|
||||
nvm --version
|
||||
if [ '${{ matrix.has-nvmrc }}' == 'nvmrc' ]; then
|
||||
nvm install
|
||||
fi
|
||||
- name: nvm install in 2 shell levels, ${{ matrix.has-nvmrc }}
|
||||
id: install-2
|
||||
if: ${{ matrix.shell-level == '2 shlvls' }}
|
||||
continue-on-error: ${{ matrix.ref == 'v0.40.0' && matrix.has-nvmrc == 'nvmrc' }}
|
||||
run: |
|
||||
if [ '${{ matrix.has-nvmrc }}' == 'nvmrc' ]; then
|
||||
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version && nvm install"
|
||||
else
|
||||
bash -c "set -ex && . $NVM_DIR/nvm.sh && echo nvm.sh sourced && nvm --version"
|
||||
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:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test]
|
||||
steps:
|
||||
- run: true
|
||||
@@ -3,11 +3,24 @@ name: Automatic Rebase
|
||||
on: [pull_request_target]
|
||||
|
||||
permissions:
|
||||
contents: write # for ljharb/rebase to push code to rebase
|
||||
pull-requests: read # for ljharb/rebase to get info about PR
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
_:
|
||||
uses: ljharb/actions/.github/workflows/rebase.yml@main
|
||||
secrets:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
permissions:
|
||||
contents: write
|
||||
name: "Automatic Rebase"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
api.github.com:443
|
||||
github.com:443
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ljharb/rebase@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -17,12 +17,9 @@ jobs:
|
||||
api.github.com:443
|
||||
objects.githubusercontent.com:443
|
||||
raw.githubusercontent.com:443
|
||||
release-assets.githubusercontent.com:443
|
||||
registry.npmjs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-tags: true
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "14"
|
||||
- run: npm install
|
||||
|
||||
@@ -8,11 +8,17 @@ permissions:
|
||||
jobs:
|
||||
_:
|
||||
permissions:
|
||||
pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR
|
||||
|
||||
pull-requests: read
|
||||
name: "Require “Allow Edits”"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: ljharb/require-allow-edits@main
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
api.github.com:443
|
||||
- uses: ljharb/require-allow-edits@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
github.com:443
|
||||
pkg-containers.githubusercontent.com:443
|
||||
formulae.brew.sh:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
- name: Install latest shellcheck
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
name: 'Tests: alpine'
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
fast:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Native runners per arch (no QEMU): arm64 uses the ubuntu-24.04-arm image.
|
||||
name: 'fast ${{ matrix.arch }} (alpine ${{ matrix.alpine }}, ${{ matrix.shell }})'
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
alpine:
|
||||
- '3.15'
|
||||
- '3.19'
|
||||
- '3'
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh (#574)
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
unofficial-builds.nodejs.org:443
|
||||
dl-cdn.alpinelinux.org:443
|
||||
dl-cdn.alpinelinux.org:80
|
||||
registry-1.docker.io:443
|
||||
auth.docker.io:443
|
||||
production.cloudflare.docker.com:443
|
||||
production.cloudfront.docker.com:443
|
||||
- uses: actions/checkout@v6
|
||||
id: checkout
|
||||
continue-on-error: true
|
||||
with:
|
||||
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
|
||||
name: 'npm install (on host; node_modules is mounted into the container)'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
- run: npm ls urchin
|
||||
- name: 'Run fast tests on Alpine ${{ matrix.alpine }} (${{ matrix.arch }})'
|
||||
run: |
|
||||
for i in 1 2 3 4 5; do
|
||||
docker pull alpine:${{ matrix.alpine }} && break
|
||||
echo "docker pull failed, attempt $i/5"; sleep $((i * 5))
|
||||
done
|
||||
docker run --rm \
|
||||
-v "${{ github.workspace }}:/workspace" \
|
||||
-w /workspace \
|
||||
-e "TEST_SHELL=${{ matrix.shell }}" \
|
||||
-e "TERM=xterm-256color" \
|
||||
-e "GITHUB_ACTIONS=true" \
|
||||
alpine:${{ matrix.alpine }} \
|
||||
sh -c '
|
||||
set -ex
|
||||
cat /etc/alpine-release; uname -m
|
||||
for i in 1 2 3 4 5; do
|
||||
apk add --no-cache \
|
||||
make bash zsh dash \
|
||||
grep sed gawk coreutils util-linux findutils ncurses \
|
||||
curl wget ca-certificates openssl tar xz gzip git \
|
||||
sudo su-exec libstdc++ libgcc && break
|
||||
echo "apk add failed, attempt $i/5"; sleep $((i * 5))
|
||||
done
|
||||
# Mirror the ubuntu runner: run the suite as a non-root user with
|
||||
# passwordless sudo and a PTY so the permission/terminal tests
|
||||
# behave the same. The user takes the mounted checkout uid so
|
||||
# files stay host-owned (no chown; post-checkout cleanup works).
|
||||
# No node is installed, so no active version skews the output.
|
||||
HOST_UID="$(stat -c %u /workspace)"
|
||||
adduser -D -u "$HOST_UID" tester 2>/dev/null || adduser -D tester
|
||||
echo "tester ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/tester
|
||||
chmod 0440 /etc/sudoers.d/tester
|
||||
export NVM_DIR=/workspace HOME=/home/tester
|
||||
unset NVM_BIN NVM_INC NVM_CD_FLAGS
|
||||
su-exec tester script -q -e -c "make TEST_SUITE=fast SHELL=$TEST_SHELL URCHIN=/workspace/node_modules/.bin/urchin test-$TEST_SHELL" /dev/null
|
||||
'
|
||||
|
||||
musl-binary:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Regression lock, same-era diagonal only: modern musl node needs a newer
|
||||
# libstdc++ than old Alpine ships, and arm64-musl exists only from
|
||||
# v20.20.1/v22.21.1/v24.9.0 (built on modern Alpine), so arm64 pins modern Alpine.
|
||||
name: 'musl-binary ${{ matrix.arch }} (alpine ${{ matrix.alpine }}, node ${{ matrix.node }})'
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { arch: x64, alpine: '3.10', node: v8.17.0 }
|
||||
- { arch: x64, alpine: '3.10', node: v10.24.1 }
|
||||
- { arch: x64, alpine: '3.12', node: v12.22.12 }
|
||||
- { arch: x64, alpine: '3.15', node: v14.21.3 }
|
||||
- { arch: x64, alpine: '3.16', node: v16.20.2 }
|
||||
- { arch: x64, alpine: '3.18', node: v18.20.4 }
|
||||
- { arch: x64, alpine: '3.20', node: v20.18.1 }
|
||||
- { arch: x64, alpine: '3', node: v22.12.0 }
|
||||
- { arch: arm64, alpine: '3.20', node: v20.20.1 }
|
||||
- { arch: arm64, alpine: '3', node: v22.21.1 }
|
||||
- { arch: arm64, alpine: '3', node: v24.9.0 }
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
unofficial-builds.nodejs.org:443
|
||||
dl-cdn.alpinelinux.org:443
|
||||
dl-cdn.alpinelinux.org:80
|
||||
registry-1.docker.io:443
|
||||
auth.docker.io:443
|
||||
production.cloudflare.docker.com:443
|
||||
production.cloudfront.docker.com:443
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: false
|
||||
- name: 'Install node ${{ matrix.node }} from a musl binary on Alpine ${{ matrix.alpine }}'
|
||||
run: |
|
||||
for i in 1 2 3 4 5; do
|
||||
docker pull alpine:${{ matrix.alpine }} && break
|
||||
echo "docker pull failed, attempt $i/5"; sleep $((i * 5))
|
||||
done
|
||||
docker run --rm \
|
||||
-v "${{ github.workspace }}:/workspace" \
|
||||
-w /workspace \
|
||||
-e "NODE_VERSION=${{ matrix.node }}" \
|
||||
-e "TERM=xterm-256color" \
|
||||
alpine:${{ matrix.alpine }} \
|
||||
sh -c '
|
||||
set -ex
|
||||
cat /etc/alpine-release; uname -m
|
||||
# libstdc++/libgcc are load-bearing: the unofficial musl node
|
||||
# binary dynamically links them. No build toolchain: -b forbids
|
||||
# the source fallback, so a missing binary is a hard failure.
|
||||
for i in 1 2 3 4 5; do
|
||||
apk add --no-cache \
|
||||
bash ca-certificates curl wget tar xz gzip \
|
||||
grep sed coreutils libstdc++ libgcc && break
|
||||
echo "apk add failed, attempt $i/5"; sleep $((i * 5))
|
||||
done
|
||||
export NVM_DIR=/workspace
|
||||
unset NVM_BIN NVM_INC NVM_CD_FLAGS
|
||||
# The default nodejs.org mirror serves no -musl artifacts; this one does.
|
||||
export NVM_NODEJS_ORG_MIRROR=https://unofficial-builds.nodejs.org/download/release
|
||||
. /workspace/nvm.sh --no-use
|
||||
nvm install -b --skip-default-packages "$NODE_VERSION"
|
||||
nvm use "$NODE_VERSION"
|
||||
[ "$(node -v)" = "$NODE_VERSION" ] || { echo "version mismatch: $(node -v)"; exit 1; }
|
||||
node -e "process.exit(0)"
|
||||
ldd "$(command -v node)" | grep -qi musl
|
||||
'
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all alpine tests'
|
||||
needs: [fast, musl-binary]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
@@ -1,111 +0,0 @@
|
||||
name: 'Tests: fast'
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
fast:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: 'fast (${{ matrix.shell }}, ${{ matrix.awk }})'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: 'script -q -e -c "${{ matrix.shell }} {0}"'
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh
|
||||
awk:
|
||||
- gawk
|
||||
- mawk
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
unofficial-builds.nodejs.org:443
|
||||
azure.archive.ubuntu.com:80
|
||||
packages.microsoft.com:443
|
||||
registry-1.docker.io:443
|
||||
auth.docker.io:443
|
||||
production.cloudflare.docker.com:443
|
||||
production.cloudfront.docker.com:443
|
||||
- uses: actions/checkout@v6
|
||||
id: checkout
|
||||
continue-on-error: true
|
||||
with:
|
||||
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
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y zsh ${{ matrix.awk }}
|
||||
if [ "${{ matrix.shell }}" != "sh" ] && [ "${{ matrix.shell }}" != "bash" ] && [ "${{ matrix.shell }}" != "zsh" ]; then
|
||||
sudo apt-get install -y ${{ matrix.shell }}
|
||||
fi
|
||||
# Set the selected awk as the default
|
||||
sudo update-alternatives --set awk /usr/bin/${{ matrix.awk }}
|
||||
shell: bash
|
||||
- run: sudo ${{ matrix.shell }} --version 2> /dev/null || dpkg -s ${{ matrix.shell }} 2> /dev/null || which ${{ matrix.shell }}
|
||||
- run: awk --version 2>&1 | head -1 || awk -W version 2>&1 | head -1
|
||||
- run: curl --version
|
||||
- run: wget --version
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'npm install && version checks'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
- run: npm ls urchin
|
||||
- run: npx which urchin
|
||||
- run: env
|
||||
- name: Hide system node
|
||||
run: |
|
||||
if [ -f /usr/local/bin/node ]; then sudo mv /usr/local/bin/node /usr/local/bin/node.bak; fi
|
||||
if [ -f /usr/local/bin/npm ]; then sudo mv /usr/local/bin/npm /usr/local/bin/npm.bak; fi
|
||||
if [ -f /usr/local/bin/npx ]; then sudo mv /usr/local/bin/npx /usr/local/bin/npx.bak; fi
|
||||
shell: bash
|
||||
- name: Run fast tests
|
||||
run: |
|
||||
URCHIN_PATH="$(npx which urchin)"
|
||||
unset NVM_CD_FLAGS NVM_BIN NVM_INC
|
||||
export NVM_DIR="${{ github.workspace }}"
|
||||
export PATH="$(echo "$PATH" | tr ':' '\n' | grep -v '\.nvm' | grep -v 'toolcache' | tr '\n' ':')"
|
||||
make TERM=xterm-256color TEST_SUITE="fast" SHELL="${{ matrix.shell }}" URCHIN="$URCHIN_PATH" test-${{ matrix.shell }}
|
||||
- name: Restore system node
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f /usr/local/bin/node.bak ]; then sudo mv /usr/local/bin/node.bak /usr/local/bin/node; fi
|
||||
if [ -f /usr/local/bin/npm.bak ]; then sudo mv /usr/local/bin/npm.bak /usr/local/bin/npm; fi
|
||||
if [ -f /usr/local/bin/npx.bak ]; then sudo mv /usr/local/bin/npx.bak /usr/local/bin/npx; fi
|
||||
shell: bash
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all fast tests'
|
||||
needs: [fast]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
@@ -1,142 +0,0 @@
|
||||
name: 'Tests: installation_iojs'
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
installation_iojs_without_curl:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: 'installation_iojs without curl (${{ matrix.shell }})'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: 'script -q -e -c "${{ matrix.shell }} {0}"'
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
azure.archive.ubuntu.com:80
|
||||
packages.microsoft.com:443
|
||||
- uses: actions/checkout@v6
|
||||
id: checkout
|
||||
continue-on-error: true
|
||||
with:
|
||||
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
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y zsh
|
||||
if [ "${{ matrix.shell }}" != "sh" ] && [ "${{ matrix.shell }}" != "bash" ] && [ "${{ matrix.shell }}" != "zsh" ]; then
|
||||
sudo apt-get install -y ${{ matrix.shell }}
|
||||
fi
|
||||
shell: bash
|
||||
- run: sudo ${{ matrix.shell }} --version 2> /dev/null || dpkg -s ${{ matrix.shell }} 2> /dev/null || which ${{ matrix.shell }}
|
||||
- run: wget --version
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'npm install && version checks'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
- run: npm ls urchin
|
||||
- run: npx which urchin
|
||||
- name: Remove curl
|
||||
run: sudo apt-get remove curl -y
|
||||
shell: bash
|
||||
- run: '! command -v curl'
|
||||
shell: bash
|
||||
- run: env
|
||||
- name: Hide system node
|
||||
run: |
|
||||
if [ -f /usr/local/bin/node ]; then sudo mv /usr/local/bin/node /usr/local/bin/node.bak; fi
|
||||
if [ -f /usr/local/bin/npm ]; then sudo mv /usr/local/bin/npm /usr/local/bin/npm.bak; fi
|
||||
if [ -f /usr/local/bin/npx ]; then sudo mv /usr/local/bin/npx /usr/local/bin/npx.bak; fi
|
||||
shell: bash
|
||||
- name: Run installation_iojs tests
|
||||
run: |
|
||||
URCHIN_PATH="$(npx which urchin)"
|
||||
unset NVM_CD_FLAGS NVM_BIN NVM_INC
|
||||
export NVM_DIR="${{ github.workspace }}"
|
||||
export PATH="$(echo "$PATH" | tr ':' '\n' | grep -v '\.nvm' | grep -v 'toolcache' | tr '\n' ':')"
|
||||
make TERM=xterm-256color TEST_SUITE="installation_iojs" SHELL="${{ matrix.shell }}" URCHIN="$URCHIN_PATH" test-${{ matrix.shell }}
|
||||
- name: Restore system node
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f /usr/local/bin/node.bak ]; then sudo mv /usr/local/bin/node.bak /usr/local/bin/node; fi
|
||||
if [ -f /usr/local/bin/npm.bak ]; then sudo mv /usr/local/bin/npm.bak /usr/local/bin/npm; fi
|
||||
if [ -f /usr/local/bin/npx.bak ]; then sudo mv /usr/local/bin/npx.bak /usr/local/bin/npx; fi
|
||||
shell: bash
|
||||
- name: Restore curl
|
||||
if: always()
|
||||
run: sudo apt-get install curl -y
|
||||
shell: bash
|
||||
|
||||
installation_iojs_source_compile:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: 'actually compile io.js from source (gcc 4.9 container)'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
mirror.gcr.io:443
|
||||
storage.googleapis.com:443
|
||||
iojs.org:443
|
||||
- uses: actions/checkout@v6
|
||||
# io.js requires python 2 and gcc <= 5 to compile; the gcc:4.9 image
|
||||
# (debian jessie) has both, plus curl/wget/xz and CA certificates that
|
||||
# still validate iojs.org - so the source-install tests run unmodified,
|
||||
# resolving, downloading, checksumming, and compiling for real.
|
||||
# The image is pulled through Google's Docker Hub mirror: it serves
|
||||
# manifests and blobs from a single stable hostname (Docker Hub's blob
|
||||
# CDN hostnames rotate, which the blocked-egress policy can not allow),
|
||||
# and it is not subject to Docker Hub's anonymous pull rate limits.
|
||||
- name: compile io.js from source, for real
|
||||
run: |
|
||||
docker run --rm -v "${PWD}:/nvm-under-test" -e NVM_DIR=/nvm-under-test mirror.gcr.io/library/gcc:4.9 bash -ec '
|
||||
cd "${NVM_DIR}/test/installation_iojs"
|
||||
sh "./install from source"
|
||||
sh "./install version specified in .nvmrc from source"
|
||||
'
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all installation_iojs tests'
|
||||
needs: [installation_iojs_without_curl, installation_iojs_source_compile]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
@@ -1,138 +0,0 @@
|
||||
name: 'Tests: installation_node'
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
installation_node:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: "installation_node (${{ matrix.shell }}${{ matrix.without_curl && ', without curl' || '' }})"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh
|
||||
without_curl:
|
||||
- false
|
||||
- true
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
azure.archive.ubuntu.com:80
|
||||
packages.microsoft.com:443
|
||||
archive.ubuntu.com:80
|
||||
security.ubuntu.com:80
|
||||
production.cloudflare.docker.com:443
|
||||
production.cloudfront.docker.com:443
|
||||
registry-1.docker.io:443
|
||||
auth.docker.io:443
|
||||
- uses: actions/checkout@v6
|
||||
id: checkout
|
||||
continue-on-error: true
|
||||
with:
|
||||
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
|
||||
name: 'npm install && version checks'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
- run: npm ls urchin
|
||||
- run: npx which urchin
|
||||
- name: Run installation_node tests in container
|
||||
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 \
|
||||
-v "${{ github.workspace }}:/workspace" \
|
||||
-w /workspace \
|
||||
-e "TEST_SHELL=${{ matrix.shell }}" \
|
||||
-e "TERM=xterm-256color" \
|
||||
-e "DEBIAN_FRONTEND=noninteractive" \
|
||||
-e "GITHUB_ACTIONS=true" \
|
||||
-e "WITHOUT_CURL=${{ matrix.without_curl }}" \
|
||||
ubuntu:16.04 \
|
||||
bash -c '
|
||||
set -ex
|
||||
|
||||
# Retry apt-get update up to 5 times due to flaky Ubuntu mirrors
|
||||
# apt-get update can return 0 even with partial failures, so check for warnings
|
||||
for i in 1 2 3 4 5; do
|
||||
if apt-get update 2>&1 | tee /tmp/apt-update.log | grep -qE "^(W:|E:|Err:)"; then
|
||||
echo "apt-get update had warnings/errors, attempt $i/5"
|
||||
cat /tmp/apt-update.log
|
||||
sleep $((i * 5))
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
apt-get install -y git curl wget make build-essential python zsh libssl-dev
|
||||
if [ "$TEST_SHELL" != "sh" ] && [ "$TEST_SHELL" != "bash" ]; then
|
||||
apt-get install -y $TEST_SHELL || true
|
||||
fi
|
||||
|
||||
# Use nvm to install Node.js for running urchin
|
||||
# Node 16 is the last version supporting GLIBC 2.23 (Ubuntu 16.04)
|
||||
export NVM_DIR="/workspace"
|
||||
. /workspace/nvm.sh
|
||||
nvm install 16
|
||||
nvm use 16
|
||||
|
||||
npm ls urchin
|
||||
URCHIN_PATH="$(npx which urchin)"
|
||||
|
||||
# Remove curl if testing without it
|
||||
if [ "$WITHOUT_CURL" = "true" ]; then
|
||||
apt-get remove curl -y
|
||||
! command -v curl
|
||||
fi
|
||||
|
||||
# Now clean up nvm state for the actual tests, but keep NVM_DIR set
|
||||
nvm deactivate || true
|
||||
nvm unalias default || true
|
||||
unset NVM_CD_FLAGS NVM_BIN NVM_INC
|
||||
export PATH="$(echo "$PATH" | tr ":" "\n" | grep -v "\.nvm" | grep -v "toolcache" | tr "\n" ":")"
|
||||
|
||||
# Clean any cached files from the nvm install above
|
||||
rm -rf "$NVM_DIR/.cache" "$NVM_DIR/versions" "$NVM_DIR/alias"
|
||||
|
||||
make TEST_SUITE="installation_node" SHELL="$TEST_SHELL" URCHIN="$URCHIN_PATH" test-$TEST_SHELL
|
||||
'
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all installation_node tests'
|
||||
needs: [installation_node]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
@@ -1,128 +0,0 @@
|
||||
name: 'Tests: xenial'
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
xenial:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: 'xenial (${{ matrix.shell }})'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@v2
|
||||
with:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
azure.archive.ubuntu.com:80
|
||||
packages.microsoft.com:443
|
||||
archive.ubuntu.com:80
|
||||
security.ubuntu.com:80
|
||||
production.cloudflare.docker.com:443
|
||||
production.cloudfront.docker.com:443
|
||||
registry-1.docker.io:443
|
||||
auth.docker.io:443
|
||||
- uses: actions/checkout@v6
|
||||
id: checkout
|
||||
continue-on-error: true
|
||||
with:
|
||||
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
|
||||
name: 'npm install && version checks'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
- run: npm ls urchin
|
||||
- run: npx which urchin
|
||||
- name: Run xenial tests in container
|
||||
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 \
|
||||
-v "${{ github.workspace }}:/workspace" \
|
||||
-w /workspace \
|
||||
-e "TEST_SHELL=${{ matrix.shell }}" \
|
||||
-e "TERM=xterm-256color" \
|
||||
-e "DEBIAN_FRONTEND=noninteractive" \
|
||||
-e "GITHUB_ACTIONS=true" \
|
||||
ubuntu:16.04 \
|
||||
bash -c '
|
||||
set -ex
|
||||
|
||||
# Retry apt-get update up to 5 times due to flaky Ubuntu mirrors
|
||||
# apt-get update can return 0 even with partial failures, so check for warnings
|
||||
for i in 1 2 3 4 5; do
|
||||
if apt-get update 2>&1 | tee /tmp/apt-update.log | grep -qE "^(W:|E:|Err:)"; then
|
||||
echo "apt-get update had warnings/errors, attempt $i/5"
|
||||
cat /tmp/apt-update.log
|
||||
sleep $((i * 5))
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
apt-get install -y git curl wget make build-essential python zsh libssl-dev
|
||||
if [ "$TEST_SHELL" != "sh" ] && [ "$TEST_SHELL" != "bash" ]; then
|
||||
apt-get install -y $TEST_SHELL || true
|
||||
fi
|
||||
|
||||
# Use nvm to install Node.js for running urchin
|
||||
# Node 16 is the last version supporting GLIBC 2.23 (Ubuntu 16.04)
|
||||
export NVM_DIR="/workspace"
|
||||
. /workspace/nvm.sh
|
||||
nvm install 16
|
||||
nvm use 16
|
||||
|
||||
npm ls urchin
|
||||
URCHIN_PATH="$(npx which urchin)"
|
||||
|
||||
# Now clean up nvm state for the actual tests, but keep NVM_DIR set
|
||||
nvm deactivate || true
|
||||
nvm unalias default || true
|
||||
unset NVM_CD_FLAGS NVM_BIN NVM_INC
|
||||
export PATH="$(echo "$PATH" | tr ":" "\n" | grep -v "\.nvm" | grep -v "toolcache" | tr "\n" ":")"
|
||||
|
||||
# Clean any cached files from the nvm install above
|
||||
rm -rf "$NVM_DIR/.cache" "$NVM_DIR/versions" "$NVM_DIR/alias"
|
||||
|
||||
make TEST_SUITE="xenial" SHELL="$TEST_SHELL" URCHIN="$URCHIN_PATH" test-$TEST_SHELL
|
||||
'
|
||||
|
||||
all:
|
||||
permissions:
|
||||
contents: none
|
||||
name: 'all xenial tests'
|
||||
needs: [xenial]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: true
|
||||
+12
-44
@@ -1,6 +1,6 @@
|
||||
name: urchin tests
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -8,11 +8,10 @@ permissions:
|
||||
jobs:
|
||||
tests:
|
||||
permissions:
|
||||
contents: read # for actions/checkout@v6
|
||||
contents: write
|
||||
|
||||
name: "tests"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
defaults:
|
||||
run:
|
||||
shell: 'script -q -e -c "${{ matrix.shell }} {0}"'
|
||||
@@ -20,26 +19,13 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
exclude:
|
||||
- shell: sh
|
||||
include:
|
||||
- shell: bash
|
||||
suite: install_script
|
||||
- shell: dash
|
||||
suite: install_script
|
||||
- shell: zsh
|
||||
suite: install_script
|
||||
- shell: ksh
|
||||
suite: install_script
|
||||
suite:
|
||||
- install_script
|
||||
- sourcing
|
||||
- slow
|
||||
- installation_iojs
|
||||
shell:
|
||||
- sh
|
||||
- bash
|
||||
- dash
|
||||
- zsh
|
||||
# - ksh
|
||||
# shell:
|
||||
# - bash
|
||||
# suite:
|
||||
# - install_script
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
@@ -51,37 +37,19 @@ jobs:
|
||||
raw.githubusercontent.com:443
|
||||
nodejs.org:443
|
||||
iojs.org:443
|
||||
azure.archive.ubuntu.com:80
|
||||
packages.microsoft.com:443
|
||||
- uses: actions/checkout@v6
|
||||
- run: sudo apt-get update; sudo apt-get install ${{ matrix.shell }}
|
||||
if: matrix.shell == 'zsh' || matrix.shell == 'ksh'
|
||||
# zsh (https://github.com/actions/runner-images/issues/264) and ksh are not in the ubuntu image
|
||||
shell: bash
|
||||
- uses: actions/checkout@v4
|
||||
- run: sudo ${{ matrix.shell }} --version 2> /dev/null || dpkg -s ${{ matrix.shell }} 2> /dev/null || which ${{ matrix.shell }}
|
||||
- run: curl --version
|
||||
- run: wget --version
|
||||
- uses: ljharb/actions/node/install@main
|
||||
- uses: ljharb/actions/node/run@main
|
||||
name: 'npm install && version checks'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
skip-ls-check: true
|
||||
shell-command: echo installed
|
||||
- run: npm ls urchin
|
||||
- run: npx which urchin
|
||||
- run: env
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
run: |
|
||||
for attempt in 1 2 3; do
|
||||
timeout 600 make TERM=xterm-256color TEST_SUITE="${{ matrix.suite }}" SHELL="${{ matrix.shell }}" URCHIN="$(npx which urchin)" test-${{ matrix.shell }} && exit 0
|
||||
EXIT_CODE=$?
|
||||
if [ $EXIT_CODE -ne 124 ]; then
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
echo "Attempt ${attempt} timed out; retrying..."
|
||||
done
|
||||
echo "All 3 attempts timed out."
|
||||
exit 1
|
||||
- run: make TERM=xterm-256color TEST_SUITE="${{ matrix.suite }}" SHELL="${{ matrix.shell }}" URCHIN="$(npx which urchin)" test-${{ matrix.shell }}
|
||||
|
||||
nvm:
|
||||
permissions:
|
||||
|
||||
@@ -20,8 +20,7 @@ jobs:
|
||||
allowed-endpoints:
|
||||
github.com:443
|
||||
registry.npmjs.org:443
|
||||
api.github.com:443
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# https://github.com/actions/checkout/issues/217#issue-599945005
|
||||
# pulls all commits (needed for lerna / semantic release to correctly version)
|
||||
@@ -29,9 +28,9 @@ jobs:
|
||||
|
||||
# pulls all tags (needed for lerna / semantic release to correctly version)
|
||||
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
||||
- uses: actions/setup-node@v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
node-version: '16'
|
||||
- run: npm install
|
||||
- run: npm run doctoc
|
||||
- name: commit changes
|
||||
|
||||
@@ -72,11 +72,8 @@ jobs:
|
||||
unset npm_config_prefix
|
||||
export NVM_INSTALL_GITHUB_REPO="$NVM_INSTALL_GITHUB_REPO"
|
||||
export NVM_INSTALL_VERSION="$NVM_INSTALL_VERSION"
|
||||
export HOME="$(cygpath -u "$USERPROFILE")"
|
||||
|
||||
echo "HOME is $HOME"
|
||||
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash
|
||||
ls -l $HOME/.nvm
|
||||
. "$HOME/.nvm/nvm.sh"
|
||||
nvm install --lts
|
||||
|
||||
@@ -94,8 +91,6 @@ jobs:
|
||||
bash.exe "%USERPROFILE%\setup.sh"
|
||||
|
||||
wsl_matrix:
|
||||
permissions:
|
||||
contents: none
|
||||
continue-on-error: true
|
||||
name: 'WSL nvm install'
|
||||
defaults:
|
||||
@@ -127,56 +122,14 @@ jobs:
|
||||
npm-node-version: '21'
|
||||
- wsl-distrib: Ubuntu-18.04
|
||||
npm-node-version: '18'
|
||||
# node v24+ doesn't work on WSL1 (exec format error)
|
||||
- wsl-distrib: Debian
|
||||
npm-node-version: '--lts'
|
||||
- wsl-distrib: Ubuntu-20.04
|
||||
npm-node-version: '--lts'
|
||||
method:
|
||||
- ''
|
||||
- 'script'
|
||||
steps:
|
||||
# For Ubuntu: install with packages directly
|
||||
- if: matrix.wsl-distrib != 'Debian'
|
||||
uses: Vampire/setup-wsl@v6
|
||||
- uses: Vampire/setup-wsl@v3
|
||||
with:
|
||||
distribution: ${{ matrix.wsl-distrib }}
|
||||
additional-packages: bash git curl ca-certificates wget
|
||||
|
||||
# For Debian: install without packages first (apt-get update fails due to stale sources.list)
|
||||
# see https://github.com/Vampire/setup-wsl/issues/76
|
||||
- if: matrix.wsl-distrib == 'Debian'
|
||||
uses: Vampire/setup-wsl@v6
|
||||
with:
|
||||
distribution: ${{ matrix.wsl-distrib }}
|
||||
- if: matrix.wsl-distrib == 'Debian'
|
||||
shell: 'wsl-bash {0}'
|
||||
run: 'sed -i s/ftp.debian.org/archive.debian.org/ /etc/apt/sources.list'
|
||||
- if: matrix.wsl-distrib == 'Debian'
|
||||
name: 'Install packages with retries'
|
||||
shell: 'wsl-bash {0}'
|
||||
run: |
|
||||
retry() {
|
||||
local n=0
|
||||
local max=3
|
||||
local delay=5
|
||||
while true; do
|
||||
"$@" && break || {
|
||||
n=$((n+1))
|
||||
if [ $n -lt $max ]; then
|
||||
echo "Command failed. Attempt $n/$max. Retrying in $delay seconds..."
|
||||
sleep $delay
|
||||
else
|
||||
echo "Command failed after $max attempts."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
done
|
||||
}
|
||||
retry apt-get update
|
||||
retry apt-get upgrade --yes
|
||||
retry apt-get install --yes bash git curl ca-certificates wget
|
||||
|
||||
- name: Retrieve nvm on WSL
|
||||
run: |
|
||||
if [ -z "${{ matrix.method }}" ]; then
|
||||
@@ -189,8 +142,6 @@ jobs:
|
||||
node -v
|
||||
|
||||
wsl_matrix_unofficial:
|
||||
permissions:
|
||||
contents: none
|
||||
continue-on-error: true
|
||||
name: 'WSL nvm install'
|
||||
defaults:
|
||||
@@ -218,11 +169,10 @@ jobs:
|
||||
- ''
|
||||
- 'script'
|
||||
steps:
|
||||
- uses: Vampire/setup-wsl@v6
|
||||
- uses: Vampire/setup-wsl@v3
|
||||
with:
|
||||
distribution: ${{ matrix.wsl-distrib }}
|
||||
additional-packages: bash git curl ca-certificates wget
|
||||
|
||||
- name: Retrieve nvm on WSL
|
||||
run: |
|
||||
if [ -z "${{ matrix.method }}" ]; then
|
||||
|
||||
@@ -9,7 +9,6 @@ test/bak
|
||||
.urchin.log
|
||||
.urchin_stdout
|
||||
test/**/test_output
|
||||
test/**/.nvmrc
|
||||
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
@@ -22,5 +21,3 @@ current
|
||||
npm-shrinkwrap.json
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
target/
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
[submodule "test/fixtures/nvmrc"]
|
||||
path = test/fixtures/nvmrc
|
||||
url = ../nvmrc.git
|
||||
url = git@github.com:nvm-sh/nvmrc.git
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
language: generic
|
||||
dist: focal
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- zsh
|
||||
# - ksh
|
||||
# - gcc-4.8
|
||||
# - g++-4.8
|
||||
|
||||
# https://gist.github.com/iedemam/9830045
|
||||
git:
|
||||
submodules: false
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/.cache
|
||||
- $TRAVIS_BUILD_DIR/node_modules
|
||||
before_install:
|
||||
- sudo sed -i 's/mozilla\/DST_Root_CA_X3.crt/!mozilla\/DST_Root_CA_X3.crt/g' /etc/ca-certificates.conf
|
||||
- sudo update-ca-certificates -f
|
||||
|
||||
# https://gist.github.com/iedemam/9830045
|
||||
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
|
||||
- git submodule update --init --recursive
|
||||
|
||||
- $SHELL --version 2> /dev/null || dpkg -s $SHELL 2> /dev/null || which $SHELL
|
||||
- curl --version
|
||||
- wget --version
|
||||
- bash --version | head
|
||||
- zsh --version
|
||||
- dpkg -s dash | grep ^Version | awk '{print $2}'
|
||||
# install python
|
||||
- pyenv install 2.7.18
|
||||
- pyenv local 2.7.18 || echo 'pyenv failed'
|
||||
- python -V
|
||||
install:
|
||||
- if [ -z "${SHELLCHECK-}" ]; then nvm install 16 && nvm unalias default && npm install && npm prune && npm ls urchin doctoc eclint dockerfile_lint; fi
|
||||
- '[ -z "$WITHOUT_CURL" ] || sudo apt-get remove curl -y'
|
||||
script:
|
||||
- if [ -n "${SHELL-}" ] && [ -n "${TEST_SUITE}" ]; then if [ "${TEST_SUITE}" = 'installation_iojs' ] || [ "${TEST_SUITE}" = 'xenial' ]; then travis_retry make TEST_SUITE=$TEST_SUITE URCHIN="$(npm bin)/urchin" test-$SHELL ; else make TEST_SUITE=$TEST_SUITE URCHIN="$(npm bin)/urchin" test-$SHELL; fi; fi
|
||||
before_cache:
|
||||
- if [ -n "$WITHOUT_CURL" ]; then sudo apt-get install curl -y ; fi
|
||||
jobs:
|
||||
include:
|
||||
- env: SHELL=bash TEST_SUITE=installation_node
|
||||
dist: xenial
|
||||
- env: SHELL=bash TEST_SUITE=installation_node WITHOUT_CURL=1
|
||||
dist: xenial
|
||||
- env: SHELL=sh TEST_SUITE=installation_node
|
||||
dist: xenial
|
||||
- env: SHELL=sh TEST_SUITE=installation_node WITHOUT_CURL=1
|
||||
dist: xenial
|
||||
- env: SHELL=dash TEST_SUITE=installation_node
|
||||
dist: xenial
|
||||
- env: SHELL=dash TEST_SUITE=installation_node WITHOUT_CURL=1
|
||||
dist: xenial
|
||||
- env: SHELL=zsh TEST_SUITE=installation_node
|
||||
dist: xenial
|
||||
- env: SHELL=zsh TEST_SUITE=installation_node WITHOUT_CURL=1
|
||||
dist: xenial
|
||||
#- env: SHELL=ksh TEST_SUITE=installation_node
|
||||
# dist: xenial
|
||||
#- env: SHELL=ksh TEST_SUITE=installation_node WITHOUT_CURL=1
|
||||
# dist: xenial
|
||||
- env: SHELL=bash TEST_SUITE=xenial
|
||||
dist: xenial
|
||||
- env: SHELL=sh TEST_SUITE=xenial
|
||||
dist: xenial
|
||||
- env: SHELL=dash TEST_SUITE=xenial
|
||||
dist: xenial
|
||||
- env: SHELL=zsh TEST_SUITE=xenial
|
||||
dist: xenial
|
||||
#- env: SHELL=ksh TEST_SUITE=xenial
|
||||
# dist: xenial
|
||||
env:
|
||||
global:
|
||||
- CXX=g++
|
||||
- CC=gcc
|
||||
- PATH="$(echo $PATH | sed 's/::/:/')"
|
||||
- PATH="/usr/lib/ccache/:$PATH"
|
||||
- NVM_DIR="${TRAVIS_BUILD_DIR}"
|
||||
matrix:
|
||||
- SHELL=sh TEST_SUITE=fast
|
||||
- SHELL=dash TEST_SUITE=fast
|
||||
- SHELL=bash TEST_SUITE=fast
|
||||
- SHELL=zsh TEST_SUITE=fast
|
||||
# - SHELL=ksh TEST_SUITE=fast
|
||||
- SHELL=sh TEST_SUITE=sourcing
|
||||
- SHELL=dash TEST_SUITE=sourcing
|
||||
- SHELL=bash TEST_SUITE=sourcing
|
||||
- SHELL=zsh TEST_SUITE=sourcing
|
||||
# - SHELL=ksh TEST_SUITE=sourcing
|
||||
- SHELL=sh TEST_SUITE=slow
|
||||
- SHELL=dash TEST_SUITE=slow
|
||||
- SHELL=bash TEST_SUITE=slow
|
||||
- SHELL=zsh TEST_SUITE=slow
|
||||
# - SHELL=ksh TEST_SUITE=slow
|
||||
- SHELL=sh TEST_SUITE=installation_iojs
|
||||
- SHELL=sh TEST_SUITE=installation_iojs WITHOUT_CURL=1
|
||||
- SHELL=dash TEST_SUITE=installation_iojs
|
||||
- SHELL=dash TEST_SUITE=installation_iojs WITHOUT_CURL=1
|
||||
- SHELL=bash TEST_SUITE=installation_iojs
|
||||
- SHELL=bash TEST_SUITE=installation_iojs WITHOUT_CURL=1
|
||||
- SHELL=zsh TEST_SUITE=installation_iojs
|
||||
- SHELL=zsh TEST_SUITE=installation_iojs WITHOUT_CURL=1
|
||||
# - SHELL=ksh TEST_SUITE=installation_iojs
|
||||
# - SHELL=ksh TEST_SUITE=installation_iojs WITHOUT_CURL=1
|
||||
@@ -1,447 +0,0 @@
|
||||
# nvm Coding Agent Instructions
|
||||
|
||||
This document provides guidance for AI coding agents when working with the Node Version Manager (nvm) codebase.
|
||||
|
||||
## Overview
|
||||
|
||||
nvm is a version manager for Node.js, implemented as a POSIX-compliant function that works across multiple shells (sh, dash, bash, ksh, zsh). The codebase is primarily written in shell script and emphasizes portability and compatibility.
|
||||
|
||||
### Core Architecture
|
||||
|
||||
- **Main script**: `nvm.sh` - Contains all core functionality and the main `nvm()` function
|
||||
- **Installation script**: `install.sh` - Handles downloading and installing nvm itself
|
||||
- **Execution wrapper**: `nvm-exec` - Allows running commands with specific Node.js versions
|
||||
- **Bash completion**: `bash_completion` - Provides tab completion for bash users
|
||||
- **Tests**: Comprehensive test suite in `test/` directory using the [urchin](https://www.npmjs.com/package/urchin) test framework
|
||||
|
||||
## Key Files and Their Purposes
|
||||
|
||||
### `nvm.sh`
|
||||
The core functionality file containing:
|
||||
- Main `nvm()` function (starts around line 3000)
|
||||
- All internal helper functions (prefixed with `nvm_`)
|
||||
- Command implementations for install, use, ls, etc.
|
||||
- Shell compatibility logic
|
||||
- POSIX compliance utilities
|
||||
|
||||
### `install.sh`
|
||||
Handles nvm installation via curl/wget/git:
|
||||
- Downloads nvm from GitHub
|
||||
- Sets up directory structure
|
||||
- Configures shell integration
|
||||
- Supports both git clone and script download methods
|
||||
|
||||
### `nvm-exec`
|
||||
Simple wrapper script that:
|
||||
- Sources nvm.sh with `--no-use` flag
|
||||
- Switches to specified Node version via `NODE_VERSION` env var or `.nvmrc`
|
||||
- Executes the provided command with that Node version
|
||||
|
||||
## Top-Level nvm Commands and Internal Functions
|
||||
|
||||
### Core Commands
|
||||
|
||||
#### `nvm install [version]`
|
||||
- **Internal functions**: `nvm_install_binary()`, `nvm_install_source()`, `nvm_download_artifact()`
|
||||
- Downloads and installs specified Node.js version
|
||||
- Automatically `nvm use`s that version after installation
|
||||
- Supports LTS versions, version ranges, and built-in aliases (like `node`, `stable`) and user-defined aliases
|
||||
- Can install from binary or compile from source
|
||||
- When compiling from source, accepts additional arguments that are passed to the compilation task
|
||||
|
||||
#### `nvm use [version]`
|
||||
- **Internal functions**: `nvm_resolve_alias()`, `nvm_version_path()`, `nvm_change_path()`
|
||||
- Switches current shell to use specified Node.js version
|
||||
- Updates PATH environment variable
|
||||
- Supports `.nvmrc` file integration
|
||||
|
||||
#### `nvm ls [pattern]`
|
||||
- **Internal functions**: `nvm_ls()`, `nvm_tree_contains_path()`
|
||||
- Lists installed Node.js versions
|
||||
- Supports pattern matching and filtering
|
||||
- Shows current version and aliases
|
||||
|
||||
#### `nvm ls-remote [pattern]`
|
||||
- **Internal functions**: `nvm_ls_remote()`, `nvm_download()`, `nvm_ls_remote_index_tab()`
|
||||
- Lists available Node.js versions from nodejs.org and iojs.org, or the env-var-configured mirrors
|
||||
- Supports LTS filtering and pattern matching
|
||||
- Downloads version index on-demand
|
||||
|
||||
#### `nvm alias [name] [version]`
|
||||
- **Internal functions**: `nvm_alias()`, `nvm_alias_path()`
|
||||
- Creates text files containing the mapped version, named as the alias name
|
||||
- Special aliases: `default`, `node`, `iojs`, `stable`, `unstable` (note: `stable` and `unstable` are deprecated, from node's pre-v1 release plan)
|
||||
- Stored in `$NVM_DIR/alias/` directory
|
||||
|
||||
#### `nvm current`
|
||||
- **Internal functions**: `nvm_ls_current()`
|
||||
- Shows currently active Node.js version
|
||||
- Returns "system" if using system Node.js
|
||||
|
||||
#### `nvm which [version]`
|
||||
- **Internal functions**: `nvm_version_path()`, `nvm_resolve_alias()`
|
||||
- Shows path to specified Node.js version
|
||||
- Resolves aliases and version strings
|
||||
|
||||
### Utility Commands
|
||||
|
||||
#### `nvm cache clear|dir`
|
||||
- Cache management for downloaded binaries and source code
|
||||
- Clears or shows cache directory path
|
||||
|
||||
#### `nvm debug`
|
||||
- Diagnostic information for troubleshooting
|
||||
- Shows environment, tool versions, and paths
|
||||
|
||||
#### `nvm deactivate`
|
||||
- Removes nvm modifications from current shell
|
||||
- Restores original PATH
|
||||
|
||||
#### `nvm unload`
|
||||
- Completely removes nvm from shell environment
|
||||
- Unsets all nvm functions and variables
|
||||
|
||||
### Internal Function Categories
|
||||
|
||||
#### Version Resolution
|
||||
- `nvm_resolve_alias()` - Resolves aliases to version numbers
|
||||
- `nvm_version()` - Finds best matching local version
|
||||
- `nvm_remote_version()` - Finds best matching remote version
|
||||
- `nvm_normalize_version()` - Standardizes version strings
|
||||
- `nvm_version_greater()` - Compares version numbers
|
||||
- `nvm_version_greater_than_or_equal_to()` - Version comparison with equality
|
||||
- `nvm_get_latest()` - Gets latest version from a list
|
||||
|
||||
#### Installation Helpers
|
||||
- `nvm_install_binary()` - Downloads and installs precompiled binaries
|
||||
- `nvm_install_source()` - Compiles Node.js from source
|
||||
- `nvm_download_artifact()` - Downloads tarballs or binaries
|
||||
- `nvm_compute_checksum()` - Verifies download integrity
|
||||
- `nvm_checksum()` - Checksum verification wrapper
|
||||
- `nvm_get_mirror()` - Gets appropriate download mirror
|
||||
- `nvm_get_arch()` - Determines system architecture
|
||||
|
||||
#### Path Management
|
||||
- `nvm_change_path()` - Updates PATH for version switching
|
||||
- `nvm_strip_path()` - Removes nvm paths from PATH
|
||||
- `nvm_version_path()` - Gets installation path for version
|
||||
- `nvm_version_dir()` - Gets version directory name
|
||||
- `nvm_prepend_path()` - Safely prepends to PATH
|
||||
|
||||
#### Shell Detection and Compatibility
|
||||
- `nvm_is_zsh()` - Shell detection for zsh
|
||||
- `nvm_is_iojs_version()` - Checks if version is io.js
|
||||
- `nvm_get_os()` - Operating system detection
|
||||
- `nvm_supports_source_options()` - Checks if shell supports source options
|
||||
|
||||
#### Network and Remote Operations
|
||||
- `nvm_download()` - Generic download function
|
||||
- `nvm_ls_remote()` - Lists remote versions
|
||||
- `nvm_ls_remote_iojs()` - Lists remote io.js versions
|
||||
- `nvm_ls_remote_index_tab()` - Parses remote version index
|
||||
|
||||
#### Utility Functions
|
||||
- `nvm_echo()`, `nvm_err()` - Output functions
|
||||
- `nvm_has()` - Checks if command exists
|
||||
- `nvm_sanitize_path()` - Cleans sensitive data from paths
|
||||
- `nvm_die_on_prefix()` - Validates npm prefix settings
|
||||
- `nvm_ensure_default_set()` - Ensures default alias is set
|
||||
- `nvm_auto()` - Automatic version switching from .nvmrc
|
||||
|
||||
#### Alias Management
|
||||
- `nvm_alias()` - Creates or lists aliases
|
||||
- `nvm_alias_path()` - Gets path to alias file
|
||||
- `nvm_unalias()` - Removes aliases
|
||||
- `nvm_resolve_local_alias()` - Resolves local aliases
|
||||
|
||||
#### Listing and Display
|
||||
- `nvm_ls()` - Lists local versions
|
||||
- `nvm_ls_current()` - Shows current version
|
||||
- `nvm_tree_contains_path()` - Checks if path is in nvm tree
|
||||
- `nvm_format_version()` - Formats version display
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Test Framework
|
||||
nvm uses the [urchin](https://www.npmjs.com/package/urchin) test framework for shell script testing.
|
||||
|
||||
### Test Structure
|
||||
```
|
||||
test/
|
||||
├── fast/ # Quick unit tests
|
||||
├── slow/ # Integration tests
|
||||
├── sourcing/ # Shell sourcing tests
|
||||
├── install_script/ # Installation script tests
|
||||
├── installation_node/ # Node installation tests
|
||||
├── installation_iojs/ # io.js installation tests
|
||||
└── common.sh # Shared test utilities
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
#### Install Dependencies
|
||||
```bash
|
||||
npm install # Installs urchin, semver, and replace tools
|
||||
```
|
||||
|
||||
#### Run All Tests
|
||||
```bash
|
||||
npm test # Runs tests in the current shell only (sh, bash, dash, zsh)
|
||||
make test # Runs tests in default shells (sh, bash, dash, zsh)
|
||||
make test-sh # Runs tests only in sh
|
||||
make test-bash # Runs tests only in bash
|
||||
make test-dash # Runs tests only in dash
|
||||
make test-zsh # Runs tests only in zsh
|
||||
make SHELLS=ksh test # Runs tests only in ksh (experimental, see issue #574)
|
||||
```
|
||||
|
||||
#### Run Specific Test Suites
|
||||
```bash
|
||||
npm run test/fast # Runs fast tests in the current shell
|
||||
npm run test/slow # Runs slow tests in the current shell
|
||||
npm run test/sourcing # Runs sourcing tests in the current shell
|
||||
npm run test/install_script # Runs install script tests in the current shell
|
||||
npm run test/installation # Runs installation tests (node + iojs) in the current shell
|
||||
npm run test/installation/node # Runs Node installation tests in the current shell
|
||||
npm run test/installation/iojs # Runs io.js installation tests in the current shell
|
||||
make TEST_SUITE=fast test # Only fast tests
|
||||
make TEST_SUITE=slow test # Only slow tests
|
||||
make SHELLS=bash test # Only bash shell
|
||||
```
|
||||
|
||||
#### Individual Test Execution
|
||||
```bash
|
||||
./test/fast/Unit\ tests/nvm_get_arch # Run single test (WARNING: This will exit/terminate your current shell session)
|
||||
./node_modules/.bin/urchin test/fast/ # Run fast test suite
|
||||
./node_modules/.bin/urchin 'test/fast/Unit tests/nvm_get_arch' # Run single test safely without shell termination
|
||||
./node_modules/.bin/urchin test/slow/ # Run slow test suite
|
||||
./node_modules/.bin/urchin test/sourcing/ # Run sourcing test suite
|
||||
./node_modules/.bin/urchin test/install_script/ # Run install script test suite
|
||||
./node_modules/.bin/urchin test/installation_node/ # Run Node installation test suite
|
||||
./node_modules/.bin/urchin test/installation_iojs/ # Run io.js installation test suite
|
||||
```
|
||||
|
||||
#### Linting and Docs Checks
|
||||
```bash
|
||||
npm run eclint # Checks EditorConfig compliance
|
||||
npm run doctoc:check # Verifies README table of contents
|
||||
npm run dockerfile_lint # Lints the Dockerfile
|
||||
npm run test:check-exec # Checks test files have executable permission
|
||||
npm run test:check-nonexec # Checks non-test files don't have executable permission
|
||||
npm run markdown-link-check # Validates markdown links (requires markdown-link-check)
|
||||
```
|
||||
|
||||
### Test Writing Guidelines
|
||||
- Tests should work across all supported shells (sh, bash, dash, zsh, ksh)
|
||||
- Define and use a `die()` function for test failures
|
||||
- Clean up after tests in cleanup functions
|
||||
- Mock external dependencies when needed
|
||||
- Place mocks in `test/mocks/` directory
|
||||
- Mock files should only be updated by the existing `update_test_mocks.sh` script, and any new mocks must be added to this script
|
||||
|
||||
## Shell Environment Setup
|
||||
|
||||
### Supported Shells
|
||||
- **bash** - Full feature support
|
||||
- **zsh** - Full feature support
|
||||
- **dash** - Basic POSIX support
|
||||
- **sh** - Basic POSIX support
|
||||
- **ksh** - Limited support (experimental)
|
||||
|
||||
### Installing Shell Environments
|
||||
|
||||
#### Ubuntu/Debian
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install bash zsh dash ksh
|
||||
# sh is typically provided by dash or bash and is available by default
|
||||
```
|
||||
|
||||
#### macOS
|
||||
```bash
|
||||
# bash and zsh are available by default, bash is not the default shell for new user accounts
|
||||
# Install other shells via Homebrew
|
||||
brew install dash ksh
|
||||
# For actual POSIX sh (not bash), install mksh which provides a true POSIX sh
|
||||
brew install mksh
|
||||
```
|
||||
|
||||
#### Manual Shell Testing
|
||||
```bash
|
||||
# Test in specific shell
|
||||
bash -c "source nvm.sh && nvm --version"
|
||||
zsh -c "source nvm.sh && nvm --version"
|
||||
dash -c ". nvm.sh && nvm --version"
|
||||
sh -c ". nvm.sh && nvm --version" # On macOS: mksh -c ". nvm.sh && nvm --version"
|
||||
ksh -c ". nvm.sh && nvm --version"
|
||||
```
|
||||
|
||||
### Shell-Specific Considerations
|
||||
- **zsh**: Requires basically any non-default zsh option to be temporarily unset to restore POSIX compliance
|
||||
- **dash**: Limited feature set, avoid bash-specific syntax
|
||||
- **ksh**: Some features may not work, primarily for compatibility testing
|
||||
|
||||
## CI Environment Details
|
||||
|
||||
### GitHub Actions Workflows
|
||||
|
||||
#### `.github/workflows/tests.yml`
|
||||
- Runs test suite across multiple shells and test suites
|
||||
- Uses `script` command for proper TTY simulation
|
||||
- Matrix strategy covers shell × test suite combinations
|
||||
- Excludes install_script tests from non-bash shells
|
||||
|
||||
#### `.github/workflows/shellcheck.yml`
|
||||
- Lints all shell scripts using shellcheck
|
||||
- Tests against multiple shell targets (bash, sh, dash, ksh)
|
||||
- Note: zsh is not included due to [shellcheck limitations](https://github.com/koalaman/shellcheck/issues/809)
|
||||
- Uses Homebrew to install latest shellcheck version
|
||||
|
||||
#### `.github/workflows/lint.yml`
|
||||
- Runs additional linting and formatting checks
|
||||
- Validates documentation and code style
|
||||
|
||||
### Travis CI (Legacy)
|
||||
- Configured in `.travis.yml`
|
||||
- Tests on multiple Ubuntu versions
|
||||
- Installs shell environments via apt packages
|
||||
|
||||
### CI Test Execution
|
||||
```bash
|
||||
# Simulate CI environment locally
|
||||
unset TRAVIS_BUILD_DIR # Disable Travis-specific logic
|
||||
unset GITHUB_ACTIONS # Disable GitHub Actions logic
|
||||
make test
|
||||
```
|
||||
|
||||
## Setting Up shellcheck Locally
|
||||
|
||||
### Installation
|
||||
|
||||
#### macOS (Homebrew)
|
||||
```bash
|
||||
brew install shellcheck
|
||||
```
|
||||
|
||||
#### Ubuntu/Debian
|
||||
```bash
|
||||
sudo apt-get install shellcheck
|
||||
```
|
||||
|
||||
#### From Source
|
||||
```bash
|
||||
# Download from https://github.com/koalaman/shellcheck/releases
|
||||
wget https://github.com/koalaman/shellcheck/releases/download/latest/shellcheck-latest.linux.x86_64.tar.xz
|
||||
tar -xf shellcheck-latest.linux.x86_64.tar.xz
|
||||
sudo cp shellcheck-latest/shellcheck /usr/local/bin/
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
#### Lint Main Files
|
||||
```bash
|
||||
shellcheck -s bash nvm.sh
|
||||
shellcheck -s bash install.sh
|
||||
shellcheck -s bash nvm-exec
|
||||
shellcheck -s bash bash_completion
|
||||
```
|
||||
|
||||
#### Lint Across Shell Types
|
||||
```bash
|
||||
shellcheck -s sh nvm.sh # POSIX sh
|
||||
shellcheck -s bash nvm.sh # Bash extensions
|
||||
shellcheck -s dash nvm.sh # Dash compatibility
|
||||
shellcheck -s ksh nvm.sh # Ksh compatibility
|
||||
```
|
||||
|
||||
#### Common shellcheck Directives in nvm
|
||||
- `# shellcheck disable=SC2039` - Allow bash extensions in POSIX mode
|
||||
- `# shellcheck disable=SC2016` - Allow literal `$` in single quotes
|
||||
- `# shellcheck disable=SC2001` - Allow sed usage instead of parameter expansion
|
||||
- `# shellcheck disable=SC3043` - Allow `local` keyword (bash extension)
|
||||
|
||||
### Fixing shellcheck Issues
|
||||
1. **Quoting**: Always quote variables: `"${VAR}"` instead of `$VAR`
|
||||
2. **POSIX compliance**: Avoid bash-specific features in portable sections
|
||||
3. **Array usage**: Use `set --` for positional parameters instead of arrays, which are not supported in POSIX
|
||||
4. **Local variables**: Declared with `local FOO` and then initialized on the next line (the latter is for ksh support)
|
||||
|
||||
## Development Best Practices
|
||||
|
||||
### Code Style
|
||||
- Use 2-space indentation
|
||||
- Follow POSIX shell guidelines for portability
|
||||
- Prefix internal functions with `nvm_`
|
||||
- Use `nvm_echo` instead of `echo` for output
|
||||
- Use `nvm_err` for error messages
|
||||
|
||||
### Compatibility
|
||||
- Test changes across all supported shells
|
||||
- Avoid bash-specific features in core functionality
|
||||
- Use `nvm_is_zsh` to check when zsh-specific behavior is needed
|
||||
- Mock external dependencies in tests
|
||||
|
||||
### Performance
|
||||
- Cache expensive operations (like remote version lists)
|
||||
- Use local variables to avoid scope pollution
|
||||
- Minimize subprocess calls where possible
|
||||
- Implement lazy loading for optional features
|
||||
|
||||
### Debugging
|
||||
- Use `nvm debug` command for environment information
|
||||
- Enable verbose output with `set -x` during development
|
||||
- Test with `NVM_DEBUG=1` environment variable
|
||||
- Check `$NVM_DIR/.cache` for cached data issues
|
||||
|
||||
## Common Gotchas
|
||||
|
||||
1. **PATH modification**: nvm modifies PATH extensively; be careful with restoration
|
||||
2. **Shell sourcing**: nvm must be sourced, not executed as a script
|
||||
3. **Version resolution**: Aliases, partial versions, and special keywords interact complexly
|
||||
4. **Platform differences**: Handle differences between Linux, macOS, and other Unix systems
|
||||
5. **Network dependencies**: Many operations require internet access for version lists
|
||||
6. **Concurrent access**: Multiple shells can conflict when installing versions simultaneously
|
||||
|
||||
## Windows Support
|
||||
|
||||
nvm works on Windows via several compatibility layers:
|
||||
|
||||
### WSL2 (Windows Subsystem for Linux)
|
||||
- Full nvm functionality available
|
||||
- **Important**: Ensure you're using WSL2, not WSL1 - see [Microsoft's WSL2 installation guide](https://docs.microsoft.com/en-us/windows/wsl/install) for up-to-date instructions
|
||||
- Install Ubuntu or other Linux distribution from Microsoft Store
|
||||
- Follow Linux installation instructions within WSL2
|
||||
|
||||
### Cygwin
|
||||
- POSIX-compatible environment for Windows
|
||||
- Download Cygwin from [cygwin.com](https://www.cygwin.com/install.html) and run the installer
|
||||
- During installation, include these packages: bash, curl, git, tar, and wget
|
||||
- May require additional PATH configuration
|
||||
|
||||
### Git Bash (MSYS2)
|
||||
- Comes with Git for Windows
|
||||
- Limited functionality compared to full Linux environment
|
||||
- Some features may not work due to path translation issues, including:
|
||||
- Binary extraction paths may be incorrectly translated
|
||||
- Symlink creation may fail
|
||||
- Some shell-specific features may behave differently
|
||||
- File permissions handling differs from Unix systems
|
||||
|
||||
### Setup Instructions for Windows
|
||||
|
||||
#### WSL2 (recommended)
|
||||
1. Install WSL2 using the official Microsoft guide: https://docs.microsoft.com/en-us/windows/wsl/install
|
||||
2. Install Ubuntu or preferred Linux distribution from Microsoft Store
|
||||
3. Follow standard Linux installation within WSL2
|
||||
|
||||
#### Git Bash
|
||||
1. Install Git for Windows (includes Git Bash) from https://git-scm.com/download/win
|
||||
2. Open Git Bash terminal
|
||||
3. Run nvm installation script
|
||||
|
||||
#### Cygwin
|
||||
1. Download and install Cygwin from https://www.cygwin.com/install.html
|
||||
2. Include bash, curl, git, tar, and wget packages during installation
|
||||
3. Run nvm installation in Cygwin terminal
|
||||
|
||||
This guide should help AI coding agents understand the nvm codebase structure, testing procedures, and development environment setup requirements.
|
||||
+2
-10
@@ -23,10 +23,10 @@ Explain the problem and include additional details to help maintainers reproduce
|
||||
* **Use a clear and descriptive title** for the issue to identify the problem.
|
||||
|
||||
* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining which command exactly you used in the terminal. When listing steps, **don't just say what you did, but explain how you did it**. For example, if you moved the cursor to the end of a line, explain if you used the mouse, or a keyboard shortcut or a command, and if so which one?
|
||||
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
|
||||
* **Provide specific examples to demonstrate the steps**. Include links to files or Github projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
|
||||
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
|
||||
* **Explain which behavior you expected to see instead and why.**
|
||||
* **Provide as much context as possible** in order to help others verify and ultimately fix the issue. This includes giving us as many details as possible about your environment, so we can more easily confirm the problem.
|
||||
* **Provide as much context as possible** in order to help others verify and ultimately fix the issue. This includes giving us as much details as possible about your environment, so we can more easily confirm the problem.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -113,11 +113,3 @@ Co-authored-by: Name Here <email@here>
|
||||
|
||||
# Where can I ask for help?
|
||||
If you have any questions, please contact [@LJHarb](mailto:ljharb@gmail.com).
|
||||
|
||||
# Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
- The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
|
||||
- The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
|
||||
- The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
|
||||
- I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
|
||||
|
||||
+7
-11
@@ -91,20 +91,16 @@ RUN echo 'nvm ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
# Switch to user "nvm" from now
|
||||
USER nvm
|
||||
|
||||
# Create a script file sourced by both interactive and non-interactive bash shells
|
||||
ENV BASH_ENV /home/nvm/.bash_env
|
||||
RUN touch "$BASH_ENV"
|
||||
RUN echo '. "$BASH_ENV"' >> "$HOME/.bashrc"
|
||||
|
||||
# nvm
|
||||
RUN echo 'export NVM_DIR="$HOME/.nvm"' >> "$BASH_ENV"
|
||||
RUN echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm' >> "$BASH_ENV"
|
||||
RUN echo '[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion' >> "$BASH_ENV"
|
||||
RUN echo 'export NVM_DIR="$HOME/.nvm"' >> "$HOME/.bashrc"
|
||||
RUN echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm' >> "$HOME/.bashrc"
|
||||
RUN echo '[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion' >> "$HOME/.bashrc"
|
||||
|
||||
# nodejs and tools
|
||||
RUN nvm install node
|
||||
RUN npm install -g doctoc urchin eclint dockerfile_lint
|
||||
RUN npm install --prefix "$HOME/.nvm/"
|
||||
RUN bash -c 'source $HOME/.nvm/nvm.sh && \
|
||||
nvm install node && \
|
||||
npm install -g doctoc urchin eclint dockerfile_lint && \
|
||||
npm install --prefix "$HOME/.nvm/"'
|
||||
|
||||
# Set WORKDIR to nvm directory
|
||||
WORKDIR /home/nvm/.nvm
|
||||
|
||||
@@ -40,14 +40,10 @@ list:
|
||||
# Note that preexisting NVM_* variables are unset to avoid interfering with tests, except when running the Travis tests (where NVM_DIR must be passed in and the env. is assumed to be pristine).
|
||||
.PHONY: $(SHELL_TARGETS)
|
||||
$(SHELL_TARGETS):
|
||||
@shell='$@'; shell=$${shell##*-}; \
|
||||
which "$$shell" >/dev/null || { printf '\033[0;31m%s\033[0m\n' "WARNING: Cannot test with shell '$$shell': not found." >&2; exit 0; } && \
|
||||
@shell='$@'; shell=$${shell##*-}; which "$$shell" >/dev/null || { printf '\033[0;31m%s\033[0m\n' "WARNING: Cannot test with shell '$$shell': not found." >&2; exit 0; } && \
|
||||
printf '\n\033[0;34m%s\033[0m\n' "Running tests in $$shell"; \
|
||||
[ -z "$$TRAVIS_BUILD_DIR" ] && [ -z "$$GITHUB_ACTIONS" ] && for v in $$(set | awk -F'=' '$$1 ~ "^NVM_" { print $$1 }'); do unset $$v; done && unset v; \
|
||||
for suite in $(TEST_SUITE); do \
|
||||
echo "Running test suite: $$suite"; \
|
||||
$(URCHIN) -f -s $$shell test/$$suite || exit; \
|
||||
done
|
||||
[ -z "$$TRAVIS_BUILD_DIR" ] && for v in $$(set | awk -F'=' '$$1 ~ "^NVM_" { print $$1 }'); do unset $$v; done && unset v; \
|
||||
for suite in $(TEST_SUITE); do $(URCHIN) -f -s $$shell test/$$suite || exit; done
|
||||
|
||||
# All-tests target: invokes the specified test suites for ALL shells defined in $(SHELLS).
|
||||
.PHONY: test
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</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` -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
@@ -18,8 +18,6 @@
|
||||
- [Installing and Updating](#installing-and-updating)
|
||||
- [Install & Update Script](#install--update-script)
|
||||
- [Additional Notes](#additional-notes)
|
||||
- [Installing in Docker](#installing-in-docker)
|
||||
- [Installing in Docker for CICD-Jobs](#installing-in-docker-for-cicd-jobs)
|
||||
- [Troubleshooting on Linux](#troubleshooting-on-linux)
|
||||
- [Troubleshooting on macOS](#troubleshooting-on-macos)
|
||||
- [Ansible](#ansible)
|
||||
@@ -31,8 +29,6 @@
|
||||
- [Usage](#usage)
|
||||
- [Long-term Support](#long-term-support)
|
||||
- [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)
|
||||
- [Default Global Packages From File While Installing](#default-global-packages-from-file-while-installing)
|
||||
- [io.js](#iojs)
|
||||
- [System Version of Node](#system-version-of-node)
|
||||
@@ -43,7 +39,6 @@
|
||||
- [Restoring PATH](#restoring-path)
|
||||
- [Set default node version](#set-default-node-version)
|
||||
- [Use a mirror of node binaries](#use-a-mirror-of-node-binaries)
|
||||
- [Pass Authorization header to mirror](#pass-authorization-header-to-mirror)
|
||||
- [.nvmrc](#nvmrc)
|
||||
- [Deeper Shell Integration](#deeper-shell-integration)
|
||||
- [Calling `nvm use` automatically in a directory with a `.nvmrc` file](#calling-nvm-use-automatically-in-a-directory-with-a-nvmrc-file)
|
||||
@@ -65,8 +60,6 @@
|
||||
- [macOS Troubleshooting](#macos-troubleshooting)
|
||||
- [WSL Troubleshooting](#wsl-troubleshooting)
|
||||
- [Maintainers](#maintainers)
|
||||
- [Project Support](#project-support)
|
||||
- [Enterprise Support](#enterprise-support)
|
||||
- [License](#license)
|
||||
- [Copyright notice](#copyright-notice)
|
||||
|
||||
@@ -78,25 +71,25 @@
|
||||
|
||||
**Example:**
|
||||
```sh
|
||||
$ nvm install 24
|
||||
Now using node v24.14.0 (npm v11.9.0)
|
||||
$ nvm use 16
|
||||
Now using node v16.9.1 (npm v7.21.1)
|
||||
$ node -v
|
||||
v24.14.0
|
||||
$ nvm use 22
|
||||
Now using node v22.22.1 (npm v10.9.4)
|
||||
v16.9.1
|
||||
$ nvm use 14
|
||||
Now using node v14.18.0 (npm v6.14.15)
|
||||
$ node -v
|
||||
v22.22.1
|
||||
$ nvm use 20
|
||||
Now using node v20.20.1 (npm v10.8.2)
|
||||
v14.18.0
|
||||
$ nvm install 12
|
||||
Now using node v12.22.6 (npm v6.14.5)
|
||||
$ node -v
|
||||
v20.20.1
|
||||
v12.22.6
|
||||
```
|
||||
|
||||
Simple as that!
|
||||
|
||||
|
||||
## About
|
||||
nvm is a version manager for [node.js](https://nodejs.org/en/), designed to be installed per-user, and invoked per-shell. `nvm` works on any POSIX-compliant shell (sh, dash, ksh, zsh, bash), in particular on these platforms: unix, macOS, and [Windows WSL](https://github.com/nvm-sh/nvm#important-notes).
|
||||
nvm is a version manager for [node.js](https://nodejs.org/en/), designed to be installed per-user, and invoked per-shell. `nvm` works on any POSIX-compliant shell (sh, dash, ksh, zsh, bash), in particular on these platforms: unix, macOS, and [windows WSL](https://github.com/nvm-sh/nvm#important-notes).
|
||||
|
||||
<a id="installation-and-update"></a>
|
||||
<a id="install-script"></a>
|
||||
@@ -106,13 +99,13 @@ 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:
|
||||
```sh
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
```
|
||||
```sh
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/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 (`~/.bash_profile`, `~/.zshrc`, `~/.profile`, or `~/.bashrc`).
|
||||
|
||||
<a id="profile_snippet"></a>
|
||||
```sh
|
||||
@@ -124,94 +117,14 @@ export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || pr
|
||||
|
||||
- If the environment variable `$XDG_CONFIG_HOME` is present, it will place the `nvm` files there.</sub>
|
||||
|
||||
- You can add `--no-use` to the end of the above script to postpone using `nvm` until you manually [`use`](#usage) it:
|
||||
|
||||
```sh
|
||||
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use # This loads nvm, without auto-using the default version
|
||||
```
|
||||
- You can add `--no-use` to the end of the above script (...`nvm.sh --no-use`) to postpone using `nvm` until you manually [`use`](#usage) it.
|
||||
|
||||
- You can customize the install source, directory, profile, and version using the `NVM_SOURCE`, `NVM_DIR`, `PROFILE`, and `NODE_VERSION` variables.
|
||||
Eg: `curl ... | NVM_DIR="path/to/nvm"`. Ensure that the `NVM_DIR` does not contain a trailing slash.
|
||||
|
||||
- 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.6/install.sh | bash'`
|
||||
|
||||
#### Installing in Docker
|
||||
|
||||
When invoking bash as a non-interactive shell, like in a Docker container, none of the regular profile files are sourced. In order to use `nvm`, `node`, and `npm` like normal, you can instead specify the special `BASH_ENV` variable, which bash sources when invoked non-interactively.
|
||||
|
||||
```Dockerfile
|
||||
# Use bash for the shell
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# Create a script file sourced by both interactive and non-interactive bash shells
|
||||
ENV BASH_ENV "${HOME}/.bash_env"
|
||||
RUN touch "${BASH_ENV}"
|
||||
RUN echo '. "${BASH_ENV}"' >> ~/.bashrc
|
||||
|
||||
# Download and install nvm
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | PROFILE="${BASH_ENV}" bash
|
||||
RUN echo node > .nvmrc
|
||||
RUN nvm install
|
||||
```
|
||||
|
||||
##### Installing in Docker for CICD-Jobs
|
||||
|
||||
More robust, works in CI/CD-Jobs. Can be run in interactive and non-interactive containers.
|
||||
See https://github.com/nvm-sh/nvm/issues/3531.
|
||||
|
||||
```Dockerfile
|
||||
FROM ubuntu:latest
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
# install curl
|
||||
RUN apt update && apt install curl -y
|
||||
|
||||
# install nvm
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
|
||||
|
||||
# set env
|
||||
ENV NVM_DIR=/root/.nvm
|
||||
|
||||
# install node
|
||||
RUN bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION"
|
||||
|
||||
# set ENTRYPOINT for reloading nvm-environment
|
||||
ENTRYPOINT ["bash", "-c", "source $NVM_DIR/nvm.sh && exec \"$@\"", "--"]
|
||||
|
||||
# set cmd to bash
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
```
|
||||
|
||||
This example defaults to installation of nodejs version 20.x.y. Optionally you can easily override the version with docker build args like:
|
||||
```
|
||||
docker build -t nvmimage --build-arg NODE_VERSION=19 .
|
||||
```
|
||||
|
||||
After creation of the image you can start container interactively and run commands, for example:
|
||||
```
|
||||
docker run --rm -it nvmimage
|
||||
|
||||
root@0a6b5a237c14:/# nvm -v
|
||||
0.40.6
|
||||
|
||||
root@0a6b5a237c14:/# node -v
|
||||
v19.9.0
|
||||
|
||||
root@0a6b5a237c14:/# npm -v
|
||||
9.6.3
|
||||
```
|
||||
|
||||
Noninteractive example:
|
||||
```
|
||||
user@host:/tmp/test $ docker run --rm -it nvmimage node -v
|
||||
v19.9.0
|
||||
user@host:/tmp/test $ docker run --rm -it nvmimage npm -v
|
||||
9.6.3
|
||||
```
|
||||
- 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.39.7/install.sh | bash'`
|
||||
|
||||
#### Troubleshooting on Linux
|
||||
|
||||
@@ -259,7 +172,7 @@ You can use a task:
|
||||
```yaml
|
||||
- name: Install nvm
|
||||
ansible.builtin.shell: >
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
args:
|
||||
creates: "{{ ansible_env.HOME }}/.nvm/nvm.sh"
|
||||
```
|
||||
@@ -280,7 +193,7 @@ which should output `nvm` if the installation was successful. Please note that `
|
||||
|
||||
If you're running a system without prepackaged binary available, which means you're going to install node or io.js from its source code, you need to make sure your system has a C++ compiler. For OS X, Xcode will work, for Debian/Ubuntu based GNU/Linux, the `build-essential` and `libssl-dev` packages work.
|
||||
|
||||
**Note:** `nvm` also supports Windows in some cases. It should work through WSL (Windows Subsystem for Linux) depending on the version of WSL. It should also work with [Git Bash](https://gitforwindows.org/) (MSYS) or [Cygwin](https://cygwin.com). Otherwise, for Windows, a few alternatives exist, which are neither supported nor developed by us:
|
||||
**Note:** `nvm` also supports Windows in some cases. It should work through WSL (Windows Subsystem for Linux) depending on the version of WSL. It should also work with [GitBash](https://gitforwindows.org/) (MSYS) or [Cygwin](https://cygwin.com). Otherwise, for Windows, a few alternatives exist, which are neither supported nor developed by us:
|
||||
|
||||
- [nvm-windows](https://github.com/coreybutler/nvm-windows)
|
||||
- [nodist](https://github.com/marcelklehr/nodist)
|
||||
@@ -291,7 +204,7 @@ If you're running a system without prepackaged binary available, which means you
|
||||
- [bass](https://github.com/edc/bass) allows you to use utilities written for Bash in fish shell
|
||||
- [fast-nvm-fish](https://github.com/brigand/fast-nvm-fish) only works with version numbers (not aliases) but doesn't significantly slow your shell startup
|
||||
- [plugin-nvm](https://github.com/derekstavis/plugin-nvm) plugin for [Oh My Fish](https://github.com/oh-my-fish/oh-my-fish), which makes nvm and its completions available in fish shell
|
||||
- [nvm.fish](https://github.com/jorgebucaran/nvm.fish) - The Node.js version manager you'll adore, crafted just for Fish
|
||||
- [fnm](https://github.com/fisherman/fnm) - [fisherman](https://github.com/fisherman/fisherman)-based version manager for fish
|
||||
- [fish-nvm](https://github.com/FabioAntunes/fish-nvm) - Wrapper around nvm for fish, delays sourcing nvm until it's actually used.
|
||||
|
||||
**Note:** We still have some problems with FreeBSD, because there is no official pre-built binary for FreeBSD, and building from source may need [patches](https://www.freshports.org/www/node/files/patch-deps_v8_src_base_platform_platform-posix.cc); see the issue ticket:
|
||||
@@ -311,7 +224,7 @@ If you're running a system without prepackaged binary available, which means you
|
||||
|
||||
Homebrew installation is not supported. If you have issues with homebrew-installed `nvm`, please `brew uninstall` it, and install it using the instructions below, before filing an issue.
|
||||
|
||||
**Note:** If you're using `zsh` you can easily install `nvm` as a zsh plugin. Install [`zsh-nvm`](https://github.com/lukechilds/zsh-nvm) and run `nvm upgrade` to upgrade ([you can set](https://github.com/lukechilds/zsh-nvm#auto-use) `NVM_AUTO_USE=true` to have it automatically detect and use `.nvmrc` files).
|
||||
**Note:** If you're using `zsh` you can easily install `nvm` as a zsh plugin. Install [`zsh-nvm`](https://github.com/lukechilds/zsh-nvm) and run `nvm upgrade` to upgrade.
|
||||
|
||||
**Note:** Git versions before v1.7 may face a problem of cloning `nvm` source from GitHub via https protocol, and there is also different behavior of git before v1.6, and git prior to [v1.17.10](https://github.com/git/git/commit/5a7d5b683f869d3e3884a89775241afa515da9e7) can not clone tags, so the minimum required git version is v1.7.10. If you are interested in the problem we mentioned here, please refer to GitHub's [HTTPS cloning errors](https://help.github.com/articles/https-cloning-errors/) article.
|
||||
|
||||
@@ -321,7 +234,7 @@ If you have `git` installed (requires git v1.7.10+):
|
||||
|
||||
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`
|
||||
1. `cd ~/.nvm` and check out the latest version with `git checkout v0.40.6`
|
||||
1. `cd ~/.nvm` and check out the latest version with `git checkout v0.39.7`
|
||||
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:
|
||||
@@ -430,7 +343,6 @@ 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/)
|
||||
- `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).
|
||||
- `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
|
||||
|
||||
@@ -446,7 +358,7 @@ Node has a [schedule](https://github.com/nodejs/Release#release-schedule) for lo
|
||||
|
||||
Any time your local copy of `nvm` connects to https://nodejs.org, it will re-create the appropriate local aliases for all available LTS lines. These aliases (stored under `$NVM_DIR/alias/lts`), are managed by `nvm`, and you should not modify, remove, or create these files - expect your changes to be undone, and expect meddling with these files to cause bugs that will likely not be supported.
|
||||
|
||||
To get the latest LTS version of node and migrate your existing installed packages, use:
|
||||
To get the latest LTS version of node and migrate your existing installed packages, use
|
||||
|
||||
```sh
|
||||
nvm install --reinstall-packages-from=current 'lts/*'
|
||||
@@ -484,33 +396,6 @@ 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.
|
||||
|
||||
### 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
|
||||
|
||||
If you've previously downloaded a node version (or it's still in the cache), you can install it without any network access using the `--offline` flag:
|
||||
|
||||
```sh
|
||||
nvm install --offline 14.7.0
|
||||
```
|
||||
|
||||
This resolves versions using only locally installed versions and cached downloads. It will not attempt to download anything. This is useful in air-gapped environments, on planes, or when you want to avoid network latency.
|
||||
|
||||
You can combine `--offline` with `--lts` to install the latest cached LTS version (as long as LTS aliases have been populated by a prior `nvm ls-remote --lts`):
|
||||
|
||||
```sh
|
||||
nvm install --offline --lts
|
||||
```
|
||||
|
||||
### Default Global Packages From File While Installing
|
||||
|
||||
@@ -526,10 +411,7 @@ stevemao/left-pad
|
||||
|
||||
### io.js
|
||||
|
||||
> [!WARNING]
|
||||
> io.js was a [fork of Node.js](https://en.wikipedia.org/wiki/Node.js#History), created in 2014 and merged back in 2015. io.js shipped v1, v2, and v3 release lines; post-merge, node.js began releasing with v4.
|
||||
|
||||
If you want to install io.js:
|
||||
If you want to install [io.js](https://github.com/iojs/io.js/):
|
||||
|
||||
```sh
|
||||
nvm install iojs
|
||||
@@ -648,17 +530,10 @@ NVM_IOJS_ORG_MIRROR=https://iojs.org/dist nvm install iojs-v1.0.3
|
||||
|
||||
`nvm use` will not, by default, create a "current" symlink. Set `$NVM_SYMLINK_CURRENT` to "true" to enable this behavior, which is sometimes useful for IDEs. Note that using `nvm` in multiple shell tabs with this environment variable enabled can cause race conditions.
|
||||
|
||||
#### Pass Authorization header to mirror
|
||||
To pass an Authorization header through to the mirror url, set `$NVM_AUTH_HEADER`
|
||||
|
||||
```sh
|
||||
NVM_AUTH_HEADER="Bearer secret-token" nvm install node
|
||||
```
|
||||
|
||||
### .nvmrc
|
||||
|
||||
You can create a `.nvmrc` file containing a node version number (or any other string that `nvm` understands; see `nvm --help` for details) in the project root directory (or any parent directory).
|
||||
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`.
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
@@ -703,7 +578,9 @@ Run [`npx nvmrc`](https://npmjs.com/nvmrc) to validate an `.nvmrc` file. If that
|
||||
|
||||
### Deeper Shell Integration
|
||||
|
||||
You can use [`nvshim`](https://github.com/iamogbz/nvshim) to shim the `node`, `npm`, and `npx` bins to automatically use the `nvm` config in the current directory. `nvshim` is **not** supported by the `nvm` maintainers. Please [report issues to the `nvshim` team](https://github.com/iamogbz/nvshim/issues/new).
|
||||
You can use [`avn`](https://github.com/wbyoung/avn) to deeply integrate into your shell and automatically invoke `nvm` when changing directories. `avn` is **not** supported by the `nvm` maintainers. Please [report issues to the `avn` team](https://github.com/wbyoung/avn/issues/new).
|
||||
|
||||
You can also use [`nvshim`](https://github.com/iamogbz/nvshim) to shim the `node`, `npm`, and `npx` bins to automatically use the `nvm` config in the current directory. `nvshim` is **not** supported by the `nvm` maintainers. Please [report issues to the `nvshim` team](https://github.com/iamogbz/nvshim/issues/new).
|
||||
|
||||
If you prefer a lighter-weight solution, the recipes below have been contributed by `nvm` users. They are **not** supported by the `nvm` maintainers. We are, however, accepting pull requests for more examples.
|
||||
|
||||
@@ -798,8 +675,6 @@ add-zsh-hook chpwd load-nvmrc
|
||||
load-nvmrc
|
||||
```
|
||||
|
||||
After saving the file, run `source ~/.zshrc` to reload the configuration with the latest changes made.
|
||||
|
||||
##### fish
|
||||
|
||||
This requires that you have [bass](https://github.com/edc/bass) installed.
|
||||
@@ -923,7 +798,7 @@ my_alias default v10.22.0 v12.18.3 v14.8.0
|
||||
|
||||
## Compatibility Issues
|
||||
|
||||
`nvm` will encounter some issues if you have some non-default settings set. (see [#606](https://github.com/nvm-sh/nvm/issues/606))
|
||||
`nvm` will encounter some issues if you have some non-default settings set. (see [#606](https://github.com/creationix/nvm/issues/606))
|
||||
The following are known to cause issues:
|
||||
|
||||
Inside `~/.npmrc`:
|
||||
@@ -953,18 +828,18 @@ Alpine Linux, unlike mainstream/traditional Linux distributions, is based on [Bu
|
||||
|
||||
There is a `-s` flag for `nvm install` which requests nvm download Node source and compile it locally.
|
||||
|
||||
If installing nvm on Alpine Linux *is* still what you want or need to do, you should be able to achieve this by running the following from your Alpine Linux shell, depending on which version you are using:
|
||||
If installing nvm on Alpine Linux *is* still what you want or need to do, you should be able to achieve this by running the following from you Alpine Linux shell, depending on which version you are using:
|
||||
|
||||
### Alpine Linux 3.13+
|
||||
```sh
|
||||
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.6/install.sh | bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
```
|
||||
|
||||
### Alpine Linux 3.5 - 3.12
|
||||
```sh
|
||||
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.6/install.sh | bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/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._
|
||||
@@ -998,13 +873,13 @@ export NVM_DIR="$HOME/.nvm"
|
||||
|
||||
## Docker For Development Environment
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
```sh
|
||||
$ docker build -t nvm-dev .
|
||||
```
|
||||
|
||||
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:
|
||||
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`:
|
||||
|
||||
```sh
|
||||
$ docker images
|
||||
@@ -1013,7 +888,7 @@ REPOSITORY TAG IMAGE ID CREATED S
|
||||
nvm-dev latest 9ca4c57a97d8 7 days ago 650 MB
|
||||
```
|
||||
|
||||
To start and enter a container based on this image:
|
||||
If you got no error message, now you can easily involve in:
|
||||
|
||||
```sh
|
||||
$ docker run -h nvm-dev -it nvm-dev
|
||||
@@ -1021,9 +896,12 @@ $ docker run -h nvm-dev -it nvm-dev
|
||||
nvm@nvm-dev:~/.nvm$
|
||||
```
|
||||
|
||||
It takes several minutes to build the image and the image size is about 650MB, so it's not suitable for production usage.
|
||||
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.
|
||||
|
||||
For more information and documentation about Docker, please refer to its [official website][docker-www] and [documentation][docker-docs]:
|
||||
For more information and documentation about docker, please refer to its official website:
|
||||
|
||||
- https://www.docker.com/
|
||||
- https://docs.docker.com/
|
||||
|
||||
## Problems
|
||||
|
||||
@@ -1064,13 +942,13 @@ 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)
|
||||
|
||||
[1]: https://github.com/nvm-sh/nvm.git
|
||||
[2]: https://github.com/nvm-sh/nvm/blob/v0.40.6/install.sh
|
||||
[3]: https://github.com/nvm-sh/nvm/actions/workflows/tests-fast.yml
|
||||
[4]: https://github.com/nvm-sh/nvm/releases/tag/v0.40.6
|
||||
[2]: https://github.com/nvm-sh/nvm/blob/v0.39.7/install.sh
|
||||
[3]: https://app.travis-ci.com/nvm-sh/nvm
|
||||
[4]: https://github.com/nvm-sh/nvm/releases/tag/v0.39.7
|
||||
[Urchin]: https://git.sdf.org/tlevine/urchin
|
||||
[Fish]: https://fishshell.com
|
||||
|
||||
**Homebrew makes zsh directories insecure**
|
||||
**Homebrew makes zsh directories unsecure**
|
||||
|
||||
```shell
|
||||
zsh compinit: insecure directories, run compaudit for list.
|
||||
@@ -1124,7 +1002,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.
|
||||
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.
|
||||
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.676)
|
||||
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.39.776)
|
||||
|
||||
- Exit back to your native shell.
|
||||
|
||||
@@ -1151,7 +1029,7 @@ Now you should be able to use node as usual.
|
||||
If you've encountered this error on WSL-2:
|
||||
|
||||
```sh
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.6/install.sh | bash
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
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
|
||||
@@ -1184,25 +1062,12 @@ You can check the contents of the file by running:
|
||||
|
||||
Currently, the sole maintainer is [@ljharb](https://github.com/ljharb) - more maintainers are quite welcome, and we hope to add folks to the team over time. [Governance](./GOVERNANCE.md) will be re-evaluated as the project evolves.
|
||||
|
||||
## Project Support
|
||||
|
||||
Only the latest version (v0.40.6 at this time) is supported.
|
||||
|
||||
## Enterprise Support
|
||||
|
||||
If you are unable to update to the latest version of `nvm`, our [partners](https://openjsf.org/ecosystem-sustainability-program) provide commercial security fixes for all unsupported versions:
|
||||
|
||||
- [HeroDevs Never-Ending Support](https://www.herodevs.com/support?utm_source=OpenJS&utm_medium=Link&utm_campaign=nvm_openjs)
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE.md](./LICENSE.md).
|
||||
|
||||
## Copyright notice
|
||||
|
||||
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/)
|
||||
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/). Node.js is a trademark of Joyent, Inc. and is used with its permission. 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.
|
||||
|
||||
<!-------------------------------------------------------------------->
|
||||
[docker-docs]: https://docs.docker.com/
|
||||
[docker-www]: https://www.docker.com/
|
||||
[The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [OpenJS Foundation Bylaws](https://bylaws.openjsf.org/) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)
|
||||
|
||||
+36
-74
@@ -6,18 +6,6 @@ nvm_has() {
|
||||
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() {
|
||||
command printf %s\\n "$*" 2>/dev/null
|
||||
}
|
||||
@@ -45,7 +33,7 @@ nvm_install_dir() {
|
||||
}
|
||||
|
||||
nvm_latest_version() {
|
||||
nvm_echo "v0.40.6"
|
||||
nvm_echo "v0.39.7"
|
||||
}
|
||||
|
||||
nvm_profile_is_bash_or_zsh() {
|
||||
@@ -79,7 +67,7 @@ nvm_source() {
|
||||
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
||||
|
||||
The default repository for this install is \`nvm-sh/nvm\`,
|
||||
but the environment variable \`\$NVM_INSTALL_GITHUB_REPO\` is
|
||||
but the environment variables \`\$NVM_INSTALL_GITHUB_REPO\` is
|
||||
currently set to \`${NVM_GITHUB_REPO}\`.
|
||||
|
||||
If this is not intentional, interrupt this installation and
|
||||
@@ -117,35 +105,21 @@ nvm_node_version() {
|
||||
}
|
||||
|
||||
nvm_download() {
|
||||
if nvm_has_executable "curl"; then
|
||||
command curl --fail --compressed -q "$@"
|
||||
elif nvm_has_executable "wget"; then
|
||||
if nvm_has "curl"; then
|
||||
curl --fail --compressed -q "$@"
|
||||
elif nvm_has "wget"; then
|
||||
# Emulate curl with wget
|
||||
local NVM_DOWNLOAD_WGET_COUNT
|
||||
NVM_DOWNLOAD_WGET_COUNT=$#
|
||||
local NVM_DOWNLOAD_WGET_SKIP
|
||||
NVM_DOWNLOAD_WGET_SKIP=0
|
||||
local NVM_DOWNLOAD_WGET_ARG
|
||||
for NVM_DOWNLOAD_WGET_ARG in "$@"; do
|
||||
if [ "${NVM_DOWNLOAD_WGET_SKIP}" = '1' ]; then
|
||||
NVM_DOWNLOAD_WGET_SKIP=0
|
||||
continue
|
||||
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}"
|
||||
command wget "$@"
|
||||
ARGS=$(nvm_echo "$@" | command sed -e 's/--progress-bar /--progress=bar /' \
|
||||
-e 's/--compressed //' \
|
||||
-e 's/--fail //' \
|
||||
-e 's/-L //' \
|
||||
-e 's/-I /--server-response /' \
|
||||
-e 's/-s /-q /' \
|
||||
-e 's/-sS /-nv /' \
|
||||
-e 's/-o /-O /' \
|
||||
-e 's/-C - /-c /')
|
||||
# shellcheck disable=SC2086
|
||||
eval wget $ARGS
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -175,10 +149,7 @@ install_nvm_from_git() {
|
||||
fetch_error="Failed to fetch origin with $NVM_VERSION. Please report this!"
|
||||
nvm_echo "=> Downloading nvm from git to '$INSTALL_DIR'"
|
||||
command printf '\r=> '
|
||||
mkdir -p "${INSTALL_DIR}" || {
|
||||
nvm_echo >&2 "Failed to create directory '${INSTALL_DIR}'"
|
||||
exit 2
|
||||
}
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
if [ "$(ls -A "${INSTALL_DIR}")" ]; then
|
||||
# Initializing repo
|
||||
command git init "${INSTALL_DIR}" || {
|
||||
@@ -192,7 +163,7 @@ install_nvm_from_git() {
|
||||
}
|
||||
else
|
||||
# Cloning repo
|
||||
command git clone -o origin "$(nvm_source)" --depth=1 "${INSTALL_DIR}" || {
|
||||
command git clone "$(nvm_source)" --depth=1 "${INSTALL_DIR}" || {
|
||||
nvm_echo >&2 'Failed to clone nvm repo. Please report this!'
|
||||
exit 2
|
||||
}
|
||||
@@ -245,7 +216,7 @@ nvm_install_node() {
|
||||
local CURRENT_NVM_NODE
|
||||
|
||||
CURRENT_NVM_NODE="$(nvm_version current)"
|
||||
if [ "$(nvm_version "$NODE_VERSION_LOCAL")" = "$CURRENT_NVM_NODE" ]; then
|
||||
if [ "$(nvm_version "$NODE_VERSION_LOCAL")" == "$CURRENT_NVM_NODE" ]; then
|
||||
nvm_echo "=> Node.js version $NODE_VERSION_LOCAL has been successfully installed"
|
||||
else
|
||||
nvm_echo >&2 "Failed to install Node.js $NODE_VERSION_LOCAL"
|
||||
@@ -263,10 +234,7 @@ install_nvm_as_script() {
|
||||
NVM_BASH_COMPLETION_SOURCE="$(nvm_source script-nvm-bash-completion)"
|
||||
|
||||
# Downloading to $INSTALL_DIR
|
||||
mkdir -p "$INSTALL_DIR" || {
|
||||
nvm_echo >&2 "Failed to create directory '$INSTALL_DIR'"
|
||||
return 1
|
||||
}
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
if [ -f "$INSTALL_DIR/nvm.sh" ]; then
|
||||
nvm_echo "=> nvm is already installed in $INSTALL_DIR, trying to update the script"
|
||||
else
|
||||
@@ -328,17 +296,17 @@ nvm_detect_profile() {
|
||||
DETECTED_PROFILE="$HOME/.bash_profile"
|
||||
fi
|
||||
elif [ "${SHELL#*zsh}" != "$SHELL" ]; then
|
||||
if [ -f "${ZDOTDIR:-${HOME}}/.zshrc" ]; then
|
||||
DETECTED_PROFILE="${ZDOTDIR:-${HOME}}/.zshrc"
|
||||
elif [ -f "${ZDOTDIR:-${HOME}}/.zprofile" ]; then
|
||||
DETECTED_PROFILE="${ZDOTDIR:-${HOME}}/.zprofile"
|
||||
if [ -f "$HOME/.zshrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zshrc"
|
||||
elif [ -f "$HOME/.zprofile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zprofile"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$DETECTED_PROFILE" ]; then
|
||||
for EACH_PROFILE in ".profile" ".bashrc" ".bash_profile" ".zprofile" ".zshrc"
|
||||
do
|
||||
if DETECTED_PROFILE="$(nvm_try_profile "${ZDOTDIR:-${HOME}}/${EACH_PROFILE}")"; then
|
||||
if DETECTED_PROFILE="$(nvm_try_profile "${HOME}/${EACH_PROFILE}")"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -390,7 +358,7 @@ nvm_check_global_modules() {
|
||||
command printf %s\\n "$NPM_GLOBAL_MODULES"
|
||||
nvm_echo '=> If you wish to uninstall them at a later point (or re-install them under your'
|
||||
# shellcheck disable=SC2016
|
||||
nvm_echo '=> `nvm` node installs), you can remove them from the system Node as follows:'
|
||||
nvm_echo '=> `nvm` Nodes), you can remove them from the system Node as follows:'
|
||||
nvm_echo
|
||||
nvm_echo ' $ nvm use system'
|
||||
nvm_echo ' $ npm uninstall -g a_module'
|
||||
@@ -406,10 +374,7 @@ nvm_do_install() {
|
||||
fi
|
||||
|
||||
if [ "${NVM_DIR}" = "$(nvm_default_install_dir)" ]; then
|
||||
mkdir "${NVM_DIR}" || {
|
||||
nvm_echo >&2 "Failed to create directory '${NVM_DIR}'"
|
||||
exit 2
|
||||
}
|
||||
mkdir "${NVM_DIR}"
|
||||
else
|
||||
nvm_echo >&2 "You have \$NVM_DIR set to \"${NVM_DIR}\", but that directory does not exist. Check your profile files and environment."
|
||||
exit 1
|
||||
@@ -427,7 +392,7 @@ nvm_do_install() {
|
||||
# Autodetect install method
|
||||
if nvm_has git; then
|
||||
install_nvm_from_git
|
||||
elif nvm_has_executable curl || nvm_has_executable wget; then
|
||||
elif nvm_has curl || nvm_has wget; then
|
||||
install_nvm_as_script
|
||||
else
|
||||
nvm_echo >&2 'You need git, curl, or wget to install nvm'
|
||||
@@ -440,7 +405,7 @@ nvm_do_install() {
|
||||
fi
|
||||
install_nvm_from_git
|
||||
elif [ "${METHOD}" = 'script' ]; then
|
||||
if ! nvm_has_executable curl && ! nvm_has_executable wget; then
|
||||
if ! nvm_has curl && ! nvm_has wget; then
|
||||
nvm_echo >&2 "You need curl or wget to install nvm"
|
||||
exit 1
|
||||
fi
|
||||
@@ -463,19 +428,16 @@ nvm_do_install() {
|
||||
COMPLETION_STR='[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion\n'
|
||||
BASH_OR_ZSH=false
|
||||
|
||||
if [ "${PROFILE-}" = '/dev/null' ] ; then
|
||||
# the user has specifically requested NOT to have nvm touch their profile
|
||||
echo
|
||||
elif [ -z "${NVM_PROFILE-}" ] ; then
|
||||
if [ -z "${NVM_PROFILE-}" ] ; then
|
||||
local TRIED_PROFILE
|
||||
if [ -n "${PROFILE}" ]; then
|
||||
TRIED_PROFILE="${PROFILE} (as defined in \$PROFILE), "
|
||||
TRIED_PROFILE="${NVM_PROFILE} (as defined in \$PROFILE), "
|
||||
fi
|
||||
nvm_echo "=> Profile not found. Tried ${TRIED_PROFILE-}~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.zshrc, and ~/.profile."
|
||||
nvm_echo "=> Create one of them and run this script again"
|
||||
nvm_echo " OR"
|
||||
nvm_echo "=> Append the following lines to the correct file yourself:"
|
||||
command printf '%b' "${SOURCE_STR}"
|
||||
command printf "${SOURCE_STR}"
|
||||
nvm_echo
|
||||
else
|
||||
if nvm_profile_is_bash_or_zsh "${NVM_PROFILE-}"; then
|
||||
@@ -483,14 +445,14 @@ nvm_do_install() {
|
||||
fi
|
||||
if ! command grep -qc '/nvm.sh' "$NVM_PROFILE"; then
|
||||
nvm_echo "=> Appending nvm source string to $NVM_PROFILE"
|
||||
command printf '%b' "${SOURCE_STR}" >> "$NVM_PROFILE"
|
||||
command printf "${SOURCE_STR}" >> "$NVM_PROFILE"
|
||||
else
|
||||
nvm_echo "=> nvm source string already in ${NVM_PROFILE}"
|
||||
fi
|
||||
# shellcheck disable=SC2016
|
||||
if ${BASH_OR_ZSH} && ! command grep -qc '$NVM_DIR/bash_completion' "$NVM_PROFILE"; then
|
||||
nvm_echo "=> Appending bash_completion source string to $NVM_PROFILE"
|
||||
command printf '%b' "$COMPLETION_STR" >> "$NVM_PROFILE"
|
||||
command printf "$COMPLETION_STR" >> "$NVM_PROFILE"
|
||||
else
|
||||
nvm_echo "=> bash_completion source string already in ${NVM_PROFILE}"
|
||||
fi
|
||||
@@ -511,7 +473,7 @@ nvm_do_install() {
|
||||
nvm_reset
|
||||
|
||||
nvm_echo "=> Close and reopen your terminal to start using nvm or run the following to use it now:"
|
||||
command printf '%b' "${SOURCE_STR}"
|
||||
command printf "${SOURCE_STR}"
|
||||
if ${BASH_OR_ZSH} ; then
|
||||
command printf "${COMPLETION_STR}"
|
||||
fi
|
||||
@@ -522,7 +484,7 @@ nvm_do_install() {
|
||||
# during the execution of the install script
|
||||
#
|
||||
nvm_reset() {
|
||||
unset -f nvm_has nvm_has_executable nvm_install_dir nvm_latest_version nvm_profile_is_bash_or_zsh \
|
||||
unset -f nvm_has 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 \
|
||||
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
|
||||
|
||||
@@ -9,12 +9,9 @@ unset NVM_CD_FLAGS
|
||||
|
||||
if [ -n "$NODE_VERSION" ]; then
|
||||
nvm use "$NODE_VERSION" > /dev/null || exit 127
|
||||
else
|
||||
{ NVM_RC_VERSION="$(nvm_rc_version 3>&1 1>&4)"; } 4>&1 && nvm_ensure_version_installed "$NVM_RC_VERSION";
|
||||
if ! nvm use >/dev/null 2>&1; then
|
||||
echo "No NODE_VERSION provided; no .nvmrc file found" >&2
|
||||
exit 127
|
||||
fi
|
||||
elif ! nvm use >/dev/null 2>&1; then
|
||||
echo "No NODE_VERSION provided; no .nvmrc file found" >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+4
-6
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nvm",
|
||||
"version": "0.40.6",
|
||||
"version": "0.39.7",
|
||||
"description": "Node Version Manager - Simple bash script to manage multiple active node.js versions",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
@@ -14,8 +14,6 @@
|
||||
"test/installation/node": "shell=$(basename -- $(ps -o comm= $(ps -o ppid= -p $PPID)) | sed 's/^-//'); make TEST_SUITE=installation_node test-$shell",
|
||||
"test/installation/iojs": "shell=$(basename -- $(ps -o comm= $(ps -o ppid= -p $PPID)) | sed 's/^-//'); make TEST_SUITE=installation_iojs test-$shell",
|
||||
"test/sourcing": "shell=$(basename -- $(ps -o comm= $(ps -o ppid= -p $PPID)) | sed 's/^-//'); make TEST_SUITE=sourcing test-$shell",
|
||||
"test:check-exec": "git -c core.quotePath=false ls-files test | while IFS= read -r file; do if [ ! -x \"$file\" ]; then case \"$file\" in test/fixtures/*|*.json|*.txt|*.sh|*.js|*.log|*.tab|*.gitkeep) ;; *) echo \"$file\" ;; esac; fi; done | tee /dev/stderr | awk 'END {if (NR > 0) exit 1}'",
|
||||
"test:check-nonexec": "(IFS=$'\\n'; for file in $(git ls-files test); do if [ -x \"$file\" ] && [ ! -d \"$file\" ] && { [[ \"$file\" =~ '\\.(json|txt|sh|js|log)$' ]] || [[ \"$file\" =~ '^test/(mocks|fixtures)/.*' ]]; }; then echo \"$file\"; fi; done) | tee /dev/stderr | awk 'END {if (NR > 0) exit 1}'",
|
||||
"doctoc": "doctoc --title='## Table of Contents' --github README.md",
|
||||
"predoctoc:check": "cp README.md v-README.md.orig && npm run doctoc",
|
||||
"doctoc:check": "diff -q README.md v-README.md.orig",
|
||||
@@ -43,11 +41,11 @@
|
||||
"homepage": "https://github.com/nvm-sh/nvm",
|
||||
"devDependencies": {
|
||||
"dockerfile_lint": "^0.3.4",
|
||||
"doctoc": "^2.5.0",
|
||||
"doctoc": "^2.2.1",
|
||||
"eclint": "^2.8.1",
|
||||
"markdown-link-check": "^3.14.2",
|
||||
"markdown-link-check": "^3.12.2",
|
||||
"replace": "^1.2.2",
|
||||
"semver": "^7.8.5",
|
||||
"semver": "^7.6.2",
|
||||
"urchin": "^0.0.5"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-62
@@ -1,41 +1,15 @@
|
||||
# Runs a command once and captures stdout and exit code.
|
||||
# Suppresses xtrace in the subshell. Discards stderr.
|
||||
#
|
||||
# Sets: CAPTURED_STDOUT, CAPTURED_EXIT_CODE
|
||||
#
|
||||
# Usage:
|
||||
# try nvm_version current
|
||||
# [ "$CAPTURED_STDOUT" = "v20.0.0" ] || die "wrong output"
|
||||
# [ "$CAPTURED_EXIT_CODE" = 0 ] || die "wrong exit code"
|
||||
try() {
|
||||
CAPTURED_STDOUT="$(set +x; "$@" 2>/dev/null)" && CAPTURED_EXIT_CODE=0 || CAPTURED_EXIT_CODE=$?
|
||||
}
|
||||
|
||||
# Runs a command once and captures stderr and exit code.
|
||||
# Suppresses xtrace in the subshell. Discards stdout.
|
||||
#
|
||||
# Sets: CAPTURED_STDERR, CAPTURED_EXIT_CODE
|
||||
#
|
||||
# Usage:
|
||||
# try_err nvm_alias
|
||||
# [ "$CAPTURED_STDERR" = "An alias is required." ] || die "wrong error"
|
||||
# [ "$CAPTURED_EXIT_CODE" = 1 ] || die "wrong exit code"
|
||||
try_err() {
|
||||
CAPTURED_STDERR="$(set +x; "$@" 2>&1 >/dev/null)" && CAPTURED_EXIT_CODE=0 || CAPTURED_EXIT_CODE=$?
|
||||
}
|
||||
|
||||
assert_ok() {
|
||||
local FUNCTION=$1
|
||||
shift
|
||||
|
||||
"$FUNCTION" "$@" || die '"'"$FUNCTION $@"'" should have succeeded, but failed'
|
||||
$($FUNCTION $@) || die '"'"$FUNCTION $@"'" should have succeeded, but failed'
|
||||
}
|
||||
|
||||
assert_not_ok() {
|
||||
local FUNCTION=$1
|
||||
shift
|
||||
|
||||
! "$FUNCTION" "$@" || die '"'"$FUNCTION $@"'" should have failed, but succeeded'
|
||||
! $($FUNCTION $@) || die '"'"$FUNCTION $@"'" should have failed, but succeeded'
|
||||
}
|
||||
|
||||
strip_colors() {
|
||||
@@ -46,43 +20,10 @@ strip_colors() {
|
||||
|
||||
make_echo() {
|
||||
echo "#!/bin/sh" > "$1"
|
||||
echo "echo \"${2}\"" >> "$1"
|
||||
echo "echo \"${2}\"" > "$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() {
|
||||
local VERSION
|
||||
VERSION="${1-}"
|
||||
|
||||
@@ -4,7 +4,6 @@ die() { echo "$@" ; exit 1; }
|
||||
|
||||
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||
|
||||
: nvm.sh
|
||||
\. "${NVM_DIR}/nvm.sh"
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
\. ../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
try_err nvm alias foo#bar baz
|
||||
OUTPUT="$(nvm alias foo#bar baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias with a hash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias with a hash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
try_err nvm alias foo# baz
|
||||
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias ending with a hash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias ending with a hash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
EXIT_CODE="$(nvm alias foo#bar baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias with a hash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
try_err nvm alias \#bar baz
|
||||
OUTPUT="$(nvm alias foo# baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias starting with a hash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias starting with a hash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias ending with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm alias foo# baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias ending with a hash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
OUTPUT="$(nvm alias \#bar baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases with a comment delimiter (#) are not supported."
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias starting with a hash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm alias \#bar baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias starting with a hash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
\. ../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
try_err nvm alias foo/bar baz
|
||||
OUTPUT="$(nvm alias foo/bar baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
try_err nvm alias foo/ baz
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias ending with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias ending with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
EXIT_CODE="$(nvm alias foo/bar baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
try_err nvm alias /bar baz
|
||||
OUTPUT="$(nvm alias foo/ baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias starting with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to create an alias starting with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias ending with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm alias foo/ baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias ending with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
OUTPUT="$(nvm alias /bar baz 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to create an alias starting with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm alias /bar baz >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to create an alias starting with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
\. ../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
try_err nvm unalias foo/bar
|
||||
OUTPUT="$(nvm unalias foo/bar 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to remove an alias with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
try_err nvm unalias foo/
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias ending with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to remove an alias ending with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
EXIT_CODE="$(nvm unalias foo/bar >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to remove an alias with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
try_err nvm unalias /bar
|
||||
OUTPUT="$(nvm unalias foo/ 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$CAPTURED_STDERR" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias starting with a slash should fail with '$EXPECTED_OUTPUT', got '$CAPTURED_STDERR'"
|
||||
[ "$CAPTURED_EXIT_CODE" = "1" ] || die "trying to remove an alias starting with a slash should fail with code 1, got '$CAPTURED_EXIT_CODE'"
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias ending with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm unalias foo/ >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to remove an alias ending with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
OUTPUT="$(nvm unalias /bar 2>&1)"
|
||||
EXPECTED_OUTPUT="Aliases in subdirectories are not supported."
|
||||
[ "$OUTPUT" = "$EXPECTED_OUTPUT" ] || die "trying to remove an alias starting with a slash should fail with '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
EXIT_CODE="$(nvm unalias /bar >/dev/null 2>&1 ; echo $?)"
|
||||
[ "$EXIT_CODE" = "1" ] || die "trying to remove an alias starting with a slash should fail with code 1, got '$EXIT_CODE'"
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
@@ -15,11 +14,11 @@ fi
|
||||
nvm alias test-stable-1 0.0.2 || die '`nvm alias test-stable-1 0.0.2` failed'
|
||||
|
||||
OUTPUT="$(nvm alias test-stable-1 | strip_colors)"
|
||||
EXPECTED_OUTPUT='test-stable-1 -> 0.0.2 (-> v0.0.2 *)'
|
||||
EXPECTED_OUTPUT='test-stable-1 -> 0.0.2 (-> v0.0.2)'
|
||||
echo "$OUTPUT" | \grep -F "$EXPECTED_OUTPUT" || die "nvm alias test-stable-1 0.0.2 did not set test-stable-1 to 0.0.2: got '$OUTPUT'"
|
||||
|
||||
nvm alias test-stable-1 0.0.1 || die '`nvm alias test-stable-1 0.0.1` failed'
|
||||
|
||||
OUTPUT="$(nvm alias test-stable-1 | strip_colors)"
|
||||
EXPECTED_OUTPUT='test-stable-1 -> 0.0.1 (-> v0.0.1 *)'
|
||||
EXPECTED_OUTPUT='test-stable-1 -> 0.0.1 (-> v0.0.1)'
|
||||
echo "$OUTPUT" | \grep -F "$EXPECTED_OUTPUT" || die "nvm alias test-stable-1 0.0.1 did not set test-stable-1 to 0.0.1: got '$OUTPUT'"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
[ $(nvm alias test-stable-1 | wc -l) = '2' ]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
@@ -10,18 +9,18 @@ NVM_ALIAS_OUTPUT=$(nvm alias | strip_colors)
|
||||
|
||||
EXPECTED_STABLE="$(nvm_print_implicit_alias local stable)"
|
||||
STABLE_VERSION="$(nvm_version "$EXPECTED_STABLE")"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "stable -> $EXPECTED_STABLE (-> $STABLE_VERSION *) (default)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "stable -> $EXPECTED_STABLE (-> $STABLE_VERSION) (default)" \
|
||||
|| die "nvm alias did not contain the default local stable node version; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "node -> stable (-> $STABLE_VERSION *) (default)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "node -> stable (-> $STABLE_VERSION) (default)" \
|
||||
|| die "nvm alias did not contain the default local stable node version under 'node'; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
EXPECTED_UNSTABLE="$(nvm_print_implicit_alias local unstable)"
|
||||
UNSTABLE_VERSION="$(nvm_version "$EXPECTED_UNSTABLE")"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "unstable -> $EXPECTED_UNSTABLE (-> $UNSTABLE_VERSION *) (default)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "unstable -> $EXPECTED_UNSTABLE (-> $UNSTABLE_VERSION) (default)" \
|
||||
|| die "nvm alias did not contain the default local unstable node version; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
EXPECTED_IOJS="$(nvm_print_implicit_alias local iojs)"
|
||||
IOJS_VERSION="$(nvm_version "$EXPECTED_IOJS")"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "iojs -> $EXPECTED_IOJS (-> $IOJS_VERSION *) (default)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F "iojs -> $EXPECTED_IOJS (-> $IOJS_VERSION) (default)" \
|
||||
|| die "nvm alias did not contain the default local iojs version; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
+4
-5
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
@@ -35,16 +34,16 @@ nvm alias iojs unstable
|
||||
|
||||
NVM_ALIAS_OUTPUT=$(nvm alias | strip_colors)
|
||||
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "stable -> $EXPECTED_UNSTABLE (-> $UNSTABLE_VERSION *)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "stable -> $EXPECTED_UNSTABLE (-> $UNSTABLE_VERSION)" \
|
||||
|| die "nvm alias did not contain the overridden 'stable' alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "unstable -> $EXPECTED_STABLE (-> $STABLE_VERSION *)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "unstable -> $EXPECTED_STABLE (-> $STABLE_VERSION)" \
|
||||
|| die "nvm alias did not contain the overridden 'unstable' alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "node -> stable (-> $UNSTABLE_VERSION *)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "node -> stable (-> $UNSTABLE_VERSION)" \
|
||||
|| die "nvm alias did not contain the overridden 'node' alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "iojs -> unstable (-> $STABLE_VERSION *)" \
|
||||
echo "$NVM_ALIAS_OUTPUT" | command grep -F "iojs -> unstable (-> $STABLE_VERSION)" \
|
||||
|| die "nvm alias did not contain the overridden 'iojs' alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
cleanup
|
||||
|
||||
@@ -1,49 +1,48 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
NVM_ALIAS_OUTPUT="$(nvm alias | strip_colors)"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-1 -> 0.0.1 (-> v0.0.1 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-1 -> 0.0.1 (-> v0.0.1)' \
|
||||
|| die "did not find test-stable-1 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-2 -> 0.0.2 (-> v0.0.2 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-2 -> 0.0.2 (-> v0.0.2)' \
|
||||
|| die "did not find test-stable-2 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-3 -> 0.0.3 (-> v0.0.3 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-3 -> 0.0.3 (-> v0.0.3)' \
|
||||
|| die "did not find test-stable-3 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-4 -> 0.0.4 (-> v0.0.4 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-4 -> 0.0.4 (-> v0.0.4)' \
|
||||
|| die "did not find test-stable-4 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-5 -> 0.0.5 (-> v0.0.5 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-5 -> 0.0.5 (-> v0.0.5)' \
|
||||
|| die "did not find test-stable-5 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-6 -> 0.0.6 (-> v0.0.6 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-6 -> 0.0.6 (-> v0.0.6)' \
|
||||
|| die "did not find test-stable-6 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-7 -> 0.0.7 (-> v0.0.7 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-7 -> 0.0.7 (-> v0.0.7)' \
|
||||
|| die "did not find test-stable-7 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-8 -> 0.0.8 (-> v0.0.8 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-8 -> 0.0.8 (-> v0.0.8)' \
|
||||
|| die "did not find test-stable-8 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-9 -> 0.0.9 (-> v0.0.9 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-9 -> 0.0.9 (-> v0.0.9)' \
|
||||
|| die "did not find test-stable-9 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-10 -> 0.0.10 (-> v0.0.10 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-stable-10 -> 0.0.10 (-> v0.0.10)' \
|
||||
|| die "did not find test-stable-10 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-1 -> 0.1.1 (-> v0.1.1 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-1 -> 0.1.1 (-> v0.1.1)' \
|
||||
|| die "did not find test-unstable-1 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-2 -> 0.1.2 (-> v0.1.2 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-2 -> 0.1.2 (-> v0.1.2)' \
|
||||
|| die "did not find test-unstable-2 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-3 -> 0.1.3 (-> v0.1.3 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-3 -> 0.1.3 (-> v0.1.3)' \
|
||||
|| die "did not find test-unstable-3 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-4 -> 0.1.4 (-> v0.1.4 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-4 -> 0.1.4 (-> v0.1.4)' \
|
||||
|| die "did not find test-unstable-4 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-5 -> 0.1.5 (-> v0.1.5 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-5 -> 0.1.5 (-> v0.1.5)' \
|
||||
|| die "did not find test-unstable-5 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-6 -> 0.1.6 (-> v0.1.6 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-6 -> 0.1.6 (-> v0.1.6)' \
|
||||
|| die "did not find test-unstable-6 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-7 -> 0.1.7 (-> v0.1.7 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-7 -> 0.1.7 (-> v0.1.7)' \
|
||||
|| die "did not find test-unstable-7 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-8 -> 0.1.8 (-> v0.1.8 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-8 -> 0.1.8 (-> v0.1.8)' \
|
||||
|| die "did not find test-unstable-8 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-9 -> 0.1.9 (-> v0.1.9 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-9 -> 0.1.9 (-> v0.1.9)' \
|
||||
|| die "did not find test-unstable-9 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-10 -> 0.1.10 (-> v0.1.10 *)' \
|
||||
echo "$NVM_ALIAS_OUTPUT" | \grep -F 'test-unstable-10 -> 0.1.10 (-> v0.1.10)' \
|
||||
|| die "did not find test-unstable-10 alias; got '$NVM_ALIAS_OUTPUT'"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
ALIAS="$(nvm_resolve_alias loopback | strip_colors)"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
ALIAS="$(nvm_resolve_local_alias loopback | strip_colors)"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
set -ex
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
\. ../../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
LTS_ALIAS_PATH="$(nvm_alias_path)/lts"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
LTS_ALIAS_PATH="$(nvm_alias_path)/lts"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/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"
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/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
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm alias default 0.1 >/dev/null || die "'nvm alias default 0.1' failed"
|
||||
@@ -14,7 +13,7 @@ nvm_ensure_default_set 0.3 || die "'nvm_ensure_default_set' with an existing def
|
||||
nvm unalias default || die "'nvm unalias default' failed"
|
||||
|
||||
OUTPUT="$(nvm_ensure_default_set 0.2)"
|
||||
EXPECTED_OUTPUT="Creating default alias: default -> 0.2 (-> iojs-v0.2.10 *)"
|
||||
EXPECTED_OUTPUT="Creating default alias: default -> 0.2 (-> iojs-v0.2.10)"
|
||||
EXIT_CODE="$?"
|
||||
|
||||
[ "_$(echo "$OUTPUT" | strip_colors)" = "_$EXPECTED_OUTPUT" ] || die "'nvm_ensure_default_set 0.2' did not output '$EXPECTED_OUTPUT', got '$OUTPUT'"
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
set -e
|
||||
|
||||
nvm_has_colors() { return 0; }
|
||||
|
||||
nvm_get_colors(){
|
||||
echo "0;95m"
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
set -e
|
||||
|
||||
# Force nvm_has_colors to return true so nvm_list_aliases sets NVM_HAS_COLORS=1
|
||||
nvm_has_colors() { return 0; }
|
||||
|
||||
nvm_alias_path() {
|
||||
nvm_echo "../../../alias"
|
||||
}
|
||||
|
||||
# nvm_list_aliases pipes through `sort`, which makes [ -t 1 ] false.
|
||||
# Before the fix in 2eb8bbd0, colors were lost inside the pipeline.
|
||||
# With the fix, NVM_HAS_COLORS is evaluated before the pipe and propagated.
|
||||
OUTPUT=$(nvm_list_aliases test-stable-1)
|
||||
COLORED_ARROW="$(command printf %b '\033[0;90m->\033[0m')"
|
||||
|
||||
case "${OUTPUT}" in
|
||||
*"${COLORED_ARROW}"*) : ;; # pass - colored arrow survived the pipeline
|
||||
*) die "Expected colored arrow in nvm_list_aliases output through pipeline, got >${OUTPUT}<" ;;
|
||||
esac
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () {
|
||||
@@ -11,8 +10,6 @@ die () {
|
||||
|
||||
set -e
|
||||
|
||||
nvm_has_colors() { return 0; }
|
||||
|
||||
nvm_get_colors(){
|
||||
echo "0;95m"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () {
|
||||
@@ -9,9 +8,6 @@ die () {
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
nvm_has_colors() { return 0; }
|
||||
|
||||
# # # expecting in red and two grays:
|
||||
OUTPUT=$(echo $(nvm_print_formatted_alias fakealias fakedest) | awk '{ print substr($0, 1, 21); }')
|
||||
EXPECTED_OUTPUT="$(command printf %b "\033[0;31mfakealias\033[0m ")"
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
die () {
|
||||
echo "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
# Override nvm_has_colors to always return false, simulating a pipeline context
|
||||
# where [ -t 1 ] is false (the bug condition from 2eb8bbd0)
|
||||
nvm_has_colors() { return 1; }
|
||||
|
||||
# Without NVM_HAS_COLORS, output should have no color codes (plain arrow)
|
||||
OUTPUT="$(nvm_print_formatted_alias fakealias fakedest)"
|
||||
case "${OUTPUT}" in
|
||||
*'\033['*) die "Expected no color codes without NVM_HAS_COLORS, got >${OUTPUT}<" ;;
|
||||
esac
|
||||
|
||||
# With NVM_HAS_COLORS=1, output should contain color codes even though
|
||||
# nvm_has_colors returns false (regression test for the pipeline fix)
|
||||
NVM_HAS_COLORS=1
|
||||
export NVM_HAS_COLORS
|
||||
OUTPUT="$(nvm_print_formatted_alias fakealias fakedest)"
|
||||
ARROW="$(command printf %b '\033[0;90m->\033[0m')"
|
||||
case "${OUTPUT}" in
|
||||
*"${ARROW}"*) : ;; # pass - colored arrow present
|
||||
*) die "Expected colored arrow with NVM_HAS_COLORS=1, got >${OUTPUT}<" ;;
|
||||
esac
|
||||
@@ -4,7 +4,6 @@ die () { echo "$@" ; exit 1; }
|
||||
|
||||
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||
|
||||
: nvm.sh
|
||||
\. "${NVM_DIR}/nvm.sh"
|
||||
|
||||
EXIT_CODE=$(nvm_resolve_alias ; echo $?)
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/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'
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/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
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
EXIT_CODE=$(nvm_resolve_local_alias ; echo $?)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh
|
||||
\. ../../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
# An alias whose name contains % should resolve directly
|
||||
try nvm_resolve_alias 'test-%s-alias'
|
||||
[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_alias test-%s-alias failed with exit code $CAPTURED_EXIT_CODE"
|
||||
[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_alias test-%s-alias was not v0.0.1; got $CAPTURED_STDOUT"
|
||||
|
||||
# An alias chain that passes through a %-containing alias name should resolve
|
||||
try nvm_resolve_alias test-pct-chain
|
||||
[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_alias test-pct-chain failed with exit code $CAPTURED_EXIT_CODE"
|
||||
[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_alias test-pct-chain was not v0.0.1; got $CAPTURED_STDOUT"
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh
|
||||
\. ../../../common.sh
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../../nvm.sh
|
||||
|
||||
# An alias whose name contains % should resolve directly
|
||||
try nvm_resolve_local_alias 'test-%s-alias'
|
||||
[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_local_alias test-%s-alias failed with exit code $CAPTURED_EXIT_CODE"
|
||||
[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_local_alias test-%s-alias was not v0.0.1; got $CAPTURED_STDOUT"
|
||||
|
||||
# An alias chain that passes through a %-containing alias name should resolve
|
||||
try nvm_resolve_local_alias test-pct-chain
|
||||
[ "$CAPTURED_EXIT_CODE" = "0" ] || die "nvm_resolve_local_alias test-pct-chain failed with exit code $CAPTURED_EXIT_CODE"
|
||||
[ "$CAPTURED_STDOUT" = "v0.0.1" ] || die "nvm_resolve_local_alias test-pct-chain was not v0.0.1; got $CAPTURED_STDOUT"
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo v0.0.1 > ../../../../alias/test-%s-alias
|
||||
echo test-%s-alias > ../../../../alias/test-pct-chain
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -f ../../../../alias/test-%s-alias
|
||||
rm -f ../../../../alias/test-pct-chain
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
export NVM_DIR="$(cd ../../.. && pwd)"
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -17,8 +17,3 @@ rm -f "../../../alias/iojs"
|
||||
rm -f "../../../alias/default"
|
||||
rm -f "../../../alias/test-blank-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"
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
rm -f "$(nvm_alias_path)/UPPER_ALIAS"
|
||||
rm -f "$(nvm_alias_path)/MixedCase"
|
||||
}
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
\. ../../common.sh
|
||||
|
||||
make_fake_node v0.0.1
|
||||
|
||||
# Uppercase alias should be created and readable
|
||||
nvm alias UPPER_ALIAS v0.0.1
|
||||
[ -f "$(nvm_alias_path)/UPPER_ALIAS" ] || die "uppercase alias file should exist"
|
||||
|
||||
try nvm_alias UPPER_ALIAS
|
||||
[ "${CAPTURED_EXIT_CODE}" = "0" ] || die "nvm_alias should succeed for uppercase alias, got exit code ${CAPTURED_EXIT_CODE}"
|
||||
[ "${CAPTURED_STDOUT}" = "v0.0.1" ] || die "nvm_alias UPPER_ALIAS should return v0.0.1, got ${CAPTURED_STDOUT}"
|
||||
|
||||
# Mixed case should also work
|
||||
nvm alias MixedCase v0.0.1
|
||||
[ -f "$(nvm_alias_path)/MixedCase" ] || die "mixed case alias file should exist"
|
||||
|
||||
try nvm_alias MixedCase
|
||||
[ "${CAPTURED_EXIT_CODE}" = "0" ] || die "nvm_alias should succeed for mixed case alias, got exit code ${CAPTURED_EXIT_CODE}"
|
||||
|
||||
# LTS names with uppercase should still be rejected
|
||||
try_err nvm_normalize_lts "lts/ARGON"
|
||||
[ "${CAPTURED_EXIT_CODE}" = "3" ] || die "uppercase LTS name should fail with exit code 3, got ${CAPTURED_EXIT_CODE}"
|
||||
[ "${CAPTURED_STDERR}" = "LTS names must be lowercase" ] || die "expected lowercase error, got ${CAPTURED_STDERR}"
|
||||
|
||||
cleanup
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm which nonexistent_version
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
cleanup() {
|
||||
rm -f "$(nvm_alias_path)/default"
|
||||
if [ -n "${SYSTEM_DIR-}" ]; then
|
||||
rm -rf "${SYSTEM_DIR}"
|
||||
fi
|
||||
if [ -n "${ORIG_PATH-}" ]; then
|
||||
PATH="${ORIG_PATH}"
|
||||
fi
|
||||
}
|
||||
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm_make_alias default system
|
||||
|
||||
ORIG_PATH="${PATH}"
|
||||
SYSTEM_DIR="$(mktemp -d)"
|
||||
cat > "${SYSTEM_DIR}/node" <<'EOF'
|
||||
#!/bin/sh
|
||||
echo v0.0.0
|
||||
EOF
|
||||
chmod +x "${SYSTEM_DIR}/node"
|
||||
PATH="${SYSTEM_DIR}:${PATH}"
|
||||
export PATH
|
||||
|
||||
EXPECTED_OUTPUT="$(command which node)"
|
||||
set +ex # since stderr is needed
|
||||
OUTPUT="$(nvm which default 2>&1)"
|
||||
set -ex
|
||||
[ "${OUTPUT}" = "${EXPECTED_OUTPUT}" ] || die "Could not use system via alias for nvm which. Got >${OUTPUT}<, expected >${EXPECTED_OUTPUT}<"
|
||||
|
||||
cleanup
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
cleanup () {
|
||||
rm -f "$(nvm_alias_path)/default"
|
||||
unset -f nvm_has_system_node node
|
||||
}
|
||||
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
nvm_make_alias default system
|
||||
nvm_has_system_node() { return 0; }
|
||||
node() { command printf 'v0.0.0'; }
|
||||
|
||||
OUTPUT="$(nvm ls default | strip_colors)"
|
||||
echo "${OUTPUT}" | command grep -q 'system' \
|
||||
|| die "Could not list system via alias. Got >${OUTPUT}<"
|
||||
echo "${OUTPUT}" | command grep -q 'v0.0.0' \
|
||||
|| die "Could not list system version via alias. Got >${OUTPUT}<"
|
||||
|
||||
cleanup
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm ls nonexistent_version
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm ls io
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
|
||||
nvm ls node_
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
-1
@@ -2,7 +2,6 @@
|
||||
|
||||
die () { echo "$@" ; exit 1; }
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
@@ -39,13 +38,7 @@ iojs-v0.10.2
|
||||
v0.12.9
|
||||
v0.12.87"
|
||||
if nvm_has_system_node || nvm_has_system_iojs; then
|
||||
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
|
||||
if [ -n "${SYSTEM_VERSION}" ]; then
|
||||
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
|
||||
system ${SYSTEM_VERSION}"
|
||||
else
|
||||
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
|
||||
EXPECTED_OUTPUT="${EXPECTED_OUTPUT}
|
||||
system"
|
||||
fi
|
||||
fi
|
||||
[ "${OUTPUT-}" = "${EXPECTED_OUTPUT-}" ] || die "expected >${EXPECTED_OUTPUT}<; got >${OUTPUT}<"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
: nvm.sh
|
||||
\. ../../../nvm.sh
|
||||
\. ../../common.sh
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user