Compare commits

..

36 Commits

Author SHA1 Message Date
Nodoubtz
dd872e126b Stripe
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 15:40:34 -04:00
Nodoubtz
7832bb85b2 feat: Bundle updates for improved performance and security
- Combined multiple scripts and stylesheets into single bundles
- Optimized load times and reduced HTTP requests
- Implemented code minification and compression
- Updated dependencies to latest versions
- Fixed security vulnerabilities in bundled code

This update enhances the overall performance and security of the application by reducing load times and minimizing potential security risks.
2025-03-27 13:56:24 -04:00
Nodoubtz
74d41508a6 Update CNAME 2025-03-27 12:40:47 -04:00
Nodoubtz
2356cf6429 Update CNAME 2025-03-27 12:39:39 -04:00
Nodoubtz
f7c78810df Update CNAME 2025-03-27 12:35:01 -04:00
Nodoubtz
23273b2731 Update CNAME 2025-03-27 12:32:41 -04:00
Nodoubtz
cfd596b276 Update CNAME 2025-03-27 10:30:29 -04:00
Nodoubtz
d1b2a8ca1a Update CNAME 2025-03-27 10:29:44 -04:00
Nodoubtz
878ee650ea Create CNAME 2025-03-27 10:29:00 -04:00
Nodoubtz
b2fbac7cf0 Delete update_test_mocks.sh
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:10:37 -04:00
Nodoubtz
63700dd9d4 Delete .github/SECURITY.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:10:06 -04:00
Nodoubtz
6e480e4fef Delete .github/THREAT_MODEL.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:09:47 -04:00
Nodoubtz
c821671ff0 Delete .github/workflows/windows-npm.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:09:17 -04:00
Nodoubtz
f38702fde5 Delete .github/external-threat-actor.png
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:08:42 -04:00
Nodoubtz
83c2eb798b Delete .github/workflows/latest-npm.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:08:21 -04:00
Nodoubtz
bc5139aaa9 Delete .github/workflows/lint.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:07:26 -04:00
Nodoubtz
fdd57e433c Delete .github/workflows/release.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:07:03 -04:00
Nodoubtz
40fce32017 Delete .github/workflows/rebase.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:06:29 -04:00
Nodoubtz
f07c2ad085 Delete .github/workflows/require-allow-edits.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:05:53 -04:00
Nodoubtz
c4a77a1ac2 Delete .github/FUNDING.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:05:26 -04:00
Nodoubtz
9a5483c78d Delete .github/insider-threat-actor-and-libs.png
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:05:08 -04:00
Nodoubtz
fcefa3d4b7 Delete rename_test.sh
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:04:21 -04:00
Nodoubtz
1d19be3d9e Delete .dockerignore
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:03:59 -04:00
Nodoubtz
4beb5bf8be Delete .editorconfig
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:03:19 -04:00
Nodoubtz
7fc954bffd Delete CONTRIBUTING.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:02:53 -04:00
Nodoubtz
72c35511aa Delete PROJECT_CHARTER.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:02:16 -04:00
Nodoubtz
dd310483c4 Delete LICENSE.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 09:01:15 -04:00
Nodoubtz
0f45c2ff34 Update README.md
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 08:57:59 -04:00
Nodoubtz
2934d0587d Delete .travis.yml
Signed-off-by: Nodoubtz <53144580+nodoubtz@users.noreply.github.com>
2025-03-27 08:22:21 -04:00
Nodoubtz
52f72a6f33 Create 5codeql.yml 2025-03-25 17:01:22 -04:00
Nodoubtz
b807ad7996 Create codeql.yml 2025-03-25 16:32:49 -04:00
Nodoubtz
d15dda9d09 Merge pull request #1 from Dimvy-Clothing-brand/master
Add Docker Publish Workflow and License
2025-03-24 18:41:44 -04:00
Nodoubtz
e8ac8518be Create LICENSE 2025-03-24 18:33:13 -04:00
Nodoubtz
d4cd67ad69 Merge branch 'nodoubtz:master' into master 2025-03-20 20:02:22 -04:00
Nodoubtz
424c4a702d Create npm-publish.yml 2025-03-13 10:12:07 -04:00
Nodoubtz
27cd578da1 Create docker-publish.yml 2025-01-26 09:58:50 -05:00
242 changed files with 4806 additions and 5544 deletions

View File

@@ -1,17 +0,0 @@
HEAD
.cache
v*
alias
# For testing
test/bak
.urchin.log
.urchin_stdout
test/**/test_output
test/**/.nvmrc
node_modules/
npm-debug.log
.DS_Store
current

View File

@@ -1,35 +0,0 @@
root = true
[*]
tab_width = 2
indent_size = 2
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.txt]
indent_size = false
[test/fast/Listing versions/Running 'nvm ls' calls into nvm_alias]
indent_size = false
[test/fast/Listing versions/Running 'nvm ls --no-alias' does not call into nvm_alias]
indent_size = false
[test/fast/Unit tests/mocks/**]
insert_final_newline = off
[test/**/.urchin*]
insert_final_newline = off
[Makefile]
indent_style = tab
[test/fixtures/nvmrc/**]
indent_style = off
insert_final_newline = off
[test/fixtures/actual/alias/empty]
insert_final_newline = off

12
.github/FUNDING.yml vendored
View File

@@ -1,12 +0,0 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/nvm
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -1,117 +0,0 @@
# Incident Response Process for **nvm**
## Reporting a Vulnerability
We take the security of **nvm** very seriously. If you believe youve 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 Well 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**: Well 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

35
.github/SECURITY.md vendored
View File

@@ -1,35 +0,0 @@
# 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.
## OpenSSF CII Best Practices
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/684/badge)](https://bestpractices.coreinfrastructure.org/projects/684)
There are three “tiers”: passing, silver, and gold.
### Passing
We meet 100% of the “passing” criteria.
### Silver
We meet 100% of the “silver” criteria.
### 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 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).

View File

@@ -1,109 +0,0 @@
# `nvm` Threat Model
## Introduction
Threat model analysis assists organizations to proactively identify potential security threats and vulnerabilities, enabling them to develop effective strategies to mitigate these risks before they are exploited by attackers.
Furthermore, this often helps to improve the overall security and resilience of a system or application.
The aim of this section is to facilitate the identification of potential security threats and vulnerabilities that may be exploited by adversaries, along with possible outcomes and appropriate mitigations.
## Relevant assets and threat actors
The following assets are considered important for the `nvm` project:
- `nvm` source code and project documentation
- Underlying `nvm` dependencies
- `nvm` development infrastructure
- `nvm` installed devices including servers
The following threat actors are considered relevant to the `nvm` application:
- External malicious attackers
- Internal malicious attackers
- Services
- Malicious insider actors
- Third-party libraries
## Attack surface for external/internal attackers and services
In threat modeling, an attack surface refers to any possible point of entry that an attacker might use to exploit a system or application.
This includes all the paths and interfaces that an attacker may use to access, manipulate or extract sensitive data from a system.
By understanding the attack surface, organizations are typically able to identify potential attack vectors and implement appropriate countermeasures to mitigate risks.
In the following diagrams, _External Malicious Attacker_ applies to threat actors who do not yet have direct access to the `nvm` application and the underlying operating system, while the _Internal Malicious Attacker_ applies to an attacker with access to the device (computer, server), potentially after successfully exploiting a threat from the _External Malicious Attacker_ scenario.
**Please note that some of the external threats may be also exploitable from internal threats and vice versa.**
<img src="./external-threat-actor.png" alt="Fig.: Possible attacks from internal and external threat actors and services" />
Fig.: Possible attacks from internal and external threat actors and services
## Identified threats
The identified threats against the `nvm` application are as follows:
### Threat ID 1: `nvm` commands
Overview: The `nvm` commands and subcommands take user input for handling and executing appropriate functions from the project directory (or any parent directory).
When user-controlled inputs are not adequately validated and later passed to the `nvm` functions as a part of a command, an attacker might be able to execute operating system commands triggered by any parsing functionality.
Possible Outcome: Attacks against `nvm` commands could lead to unauthorized access to user data or unauthorized access to the device (i.e. laptop or server, depending on where `nvm` is installed), resulting in loss of user private data stored on the device, among other possibilities.
Recommendation: Input validation should be implemented to prevent attackers from requesting operating system commands.
Similarly, secure coding practices ought to be in place to minimize the risk of buffer overflow vulnerabilities.
### Threat ID 2: URI scheme
Overview: `nvm` commands heavily use the [Secure HyperText Transfer](https://datatracker.ietf.org/doc/html/rfc2660) protocol for `nvm` related actions.
Missing [scheme](https://datatracker.ietf.org/doc/html/rfc3986#section-3.1) validation for any `nvm` command might result in file retrieval, enumeration, file overwrite, or [path traversal](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/05-Authorization_Testing/01-Testing_Directory_Traversal_File_Include) attacks.
An example of this could be path validation for [`nvm_download`](https://github.com/nvm-sh/nvm/blob/ef7fc2f2c06ad75fe7fbabf28d427561ae7b007d/nvm.sh#L118), among many other possibilities.
Possible Outcome: Security misconfiguration flaws for URI scheme may lead to unauthorized access to user data, as well as data integrity compromises.
Recommendation: Adequate input validation should be implemented to prevent attackers from enumerating, retrieving and writing to application files and paths.
### Threat ID 3: Communication channel
Overview: The `nvm` commands and its subcommands use network protocol to communicate with external services.
Insecure communication may allow malicious attackers to perform [_Man-in-the-Middle_](https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack) attacks in order to manipulate the data sent during the users active connection.
Possible Outcome: Usage of plaintext communication protocols, like HTTP could lead to data sniffing and modification through insecure communications channels.
Recommendation: Mitigation countermeasures such as data encryption should be in place to prevent data manipulation via insecure communication channels.
### Threat ID 4: Environment variables
Overview: Each `nvm` installation defines its environment variables, which should be secured from internal malicious attackers, preventing access control attack vectors.
Missing stringent restrictions on setting variables, might allow attackers to prepare various targeted attacks against other local users, who use `nvm` in their user space.
For example, [_Privilege Escalation_](https://owasp.org/Top10/A01_2021-Broken_Access_Control/), [_Command Injection_](https://cwe.mitre.org/data/definitions/77.html), as well as many other parser-related attacks.
Possible Outcome: Attacks against environment variables could lead to unauthorized access to the user space, resulting in the loss of user private data and disruptions in service availability.
Recommendation: Adequate hardening of configuration file permissions should be in place for all relevant configuration files, as this provides protection against attackers able to manipulate variables and inject malicious code.
## Attack surface for malicious insider actors and third-party libraries
The following diagram summarizes the main possible threats against the `nvm` project from malicious insider actors and third-party libraries:
<img src="./insider-threat-actor-and-libs.png" alt="Fig.: Possible attacks from insider threat actors and third-party libraries" />
Fig.: Possible attacks from insider threat actors and third-party libraries
The identified threats against the `nvm` project are as follows:
### Threat ID 1: Insider threat actor
**Overview**: An insider threat actor, such as an `nvm` project contributor or employee with access to the code base, might abuse their role in the organization to modify the `nvm` application source code.
For example, intentionally adding malicious code snippets, clearing logs after being written and/or modifying specific sections of the documentation.
**Possible Outcome**: Reputation damage, financial losses.
**Recommendation**: Secure coding practices, code reviews, automated code scanning and separation of duties (i.e. requiring at least two developers to approve any code change) are potentially useful security controls to identify and mitigate vulnerabilities that may be introduced by an insider threat actor.
### Threat ID 2: Third-party libraries
**Overview**: Please note that while `nvm` does not currently make use of any third-party libraries, this might become an attack vector if that changes in the future.
Third-party libraries may introduce potential risks related to maintaining security requirements by third-party vendors.
As a result, third-party libraries used by the `nvm` project, might contain vulnerabilities, such as [_Buffer Overflows_](https://owasp.org/www-community/vulnerabilities/Buffer_Overflow), [_Format String Vulnerabilities_](https://owasp.org/www-community/attacks/Format_string_attack), as well as many other types of weaknesses that, in a worst-case scenario may lead to _Remote Code Execution_ (_RCE_).
Additionally, the maintainer of a third-party dependency might introduce a vulnerability on purpose, or be compromised by an attacker that subsequently introduces vulnerable code.
**Possible Outcome**: Code vulnerabilities may lead to unauthorized access to user data, loss of user private data, service disruptions and reputation damage.
**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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

100
.github/workflows/5codeql.yml vendored Normal file
View File

@@ -0,0 +1,100 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: '44 18 * * 1'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

View File

@@ -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

100
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,100 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: '44 1 * * 4'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

98
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -0,0 +1,98 @@
name: Docker
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
schedule:
- cron: '35 2 * * *'
push:
branches: [ "master" ]
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
pull_request:
branches: [ "master" ]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
with:
cosign-release: 'v2.2.4'
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

View File

@@ -1,86 +0,0 @@
name: 'Tests: `nvm install-latest-npm`'
on: [pull_request, push]
permissions:
contents: read
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.set-matrix.outputs.requireds }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
iojs.org:443
nodejs.org:443
raw.githubusercontent.com:443
- uses: ljharb/actions/node/matrix@main
id: set-matrix
with:
versionsAsRoot: true
type: majors
preset: '>=1'
nodes:
needs: [matrix]
permissions:
contents: read
name: 'nvm install-latest-npm'
runs-on: ubuntu-latest
strategy:
fail-fast: false
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"
- node-version: "6.1"
- node-version: "5.9"
- node-version: "4.6"
- node-version: "4.5"
- node-version: "4.4"
- node-version: "0.12"
- node-version: "0.10"
steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
raw.githubusercontent.com:443
iojs.org:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v6
- uses: ljharb/actions/node/install@main
name: 'install node'
with:
node-version: ${{ matrix.node-version }}
skip-ls-check: true
skip-install: true
skip-latest-npm: true
- run: npm --version
- run: '. ./nvm.sh ; nvm install-latest-npm'
name: 'nvm install-latest-npm'
- run: npm --version
node:
permissions:
contents: none
name: 'nvm install-latest-npm'
needs: [nodes]
runs-on: ubuntu-latest
steps:
- run: true

View File

@@ -1,81 +0,0 @@
name: 'Tests: linting'
on: [pull_request, push]
permissions:
contents: read
jobs:
eclint:
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 ${{ matrix.node-version }} && npm install'
with:
node-version: 'lts/*'
- run: npm run eclint
dockerfile_lint:
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
ghcr.io:443
github.com:443
raw.githubusercontent.com:443
pkg-containers.githubusercontent.com:443
nodejs.org:443
registry.npmjs.org:443
- uses: actions/checkout@v6
- uses: ljharb/actions/node/install@main
name: 'nvm install ${{ matrix.node-version }} && npm install'
with:
node-version: 'lts/*'
- run: npm run dockerfile_lint
doctoc:
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 ${{ matrix.node-version }} && npm install'
with:
node-version: 'lts/*'
- run: npm run doctoc:check
test_naming:
runs-on: ubuntu-latest
steps:
- uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
raw.githubusercontent.com:443
- uses: actions/checkout@v6
- name: check tests filenames
run: ./rename_test.sh --check
all:
permissions:
contents: none
name: 'all linting'
needs: [eclint, dockerfile_lint, doctoc, test_naming]
runs-on: ubuntu-latest
steps:
- run: true

View File

@@ -1,164 +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 latest release.'
required: false
default: ''
permissions:
contents: read
jobs:
update-nodejs-org:
if: github.repository == 'nvm-sh/nvm' && github.actor == 'ljharb'
permissions:
contents: none
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 "repos/${GITHUB_REPOSITORY}/releases/latest" --jq '.tag_name')"
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')"
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 2>&1; 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 }}

33
.github/workflows/npm-publish.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: Node.js Package
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm test
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

View File

@@ -10,16 +10,13 @@ on:
required: false
default: 'HEAD'
permissions:
contents: read
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: matrix
@@ -58,7 +55,7 @@ jobs:
- 2 shlvls
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
- name: resolve HEAD to sha
run: |
if [ '${{ matrix.ref }}' = 'HEAD' ]; then

View File

@@ -1,17 +0,0 @@
name: Automatic Rebase
on: [pull_request_target]
permissions: read-all
jobs:
_:
name: "Automatic Rebase"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: ljharb/rebase@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,39 +0,0 @@
name: 'Tests: release process'
on: [pull_request, push]
permissions:
contents: read
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
with:
allowed-endpoints:
github.com:443
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
with:
node-version: "14"
- run: npm install
- name: Configure git
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git fetch --unshallow --tags -f || git fetch --tags -f
- name: Attempt `make release` process
run: echo proceed | make TAG=99.99.99 release
env:
GIT_EDITOR: "sed -i '1 s/^/99.99.99 make release test/'"
- name: Ensure tag is created
run: git tag | grep v99.99.99

View File

@@ -1,14 +0,0 @@
name: Require “Allow Edits”
on: [pull_request_target]
permissions: read-all
jobs:
_:
name: "Require “Allow Edits”"
runs-on: ubuntu-latest
steps:
- uses: ljharb/require-allow-edits@main

View File

@@ -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

View File

@@ -1,101 +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
- uses: actions/checkout@v6
with:
submodules: true
- 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

View File

@@ -1,99 +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
with:
submodules: true
- 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
all:
permissions:
contents: none
name: 'all installation_iojs tests'
needs: [installation_iojs_without_curl]
runs-on: ubuntu-latest
steps:
- run: true

View File

@@ -1,122 +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
registry-1.docker.io:443
auth.docker.io:443
- uses: actions/checkout@v6
with:
submodules: true
- 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: |
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

View File

@@ -1,112 +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
registry-1.docker.io:443
auth.docker.io:443
- uses: actions/checkout@v6
with:
submodules: true
- 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: |
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

View File

@@ -12,7 +12,6 @@ jobs:
name: "tests"
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: 'script -q -e -c "${{ matrix.shell }} {0}"'
@@ -53,7 +52,7 @@ jobs:
iojs.org:443
azure.archive.ubuntu.com:80
packages.microsoft.com:443
- uses: actions/checkout@v6
- uses: actions/checkout@v4
- 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
@@ -69,19 +68,7 @@ jobs:
- 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:

View File

@@ -21,7 +21,7 @@ jobs:
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,7 +29,7 @@ jobs:
# pulls all tags (needed for lerna / semantic release to correctly version)
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- uses: actions/setup-node@v6
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm install

View File

@@ -1,239 +0,0 @@
name: 'Tests on Windows: `nvm install`'
on: [pull_request, push]
permissions:
contents: read
env:
NVM_INSTALL_GITHUB_REPO: ${{ github.repository }}
NVM_INSTALL_VERSION: ${{ github.sha }}
jobs:
msys_fail_install:
# Default installation does not work due to npm_config_prefix set to C:\npm\prefix
permissions:
contents: none
name: 'MSYS fail prefix nvm install'
runs-on: windows-latest
steps:
- name: Retrieve nvm
shell: bash
run: |
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD=script bash
. "$HOME/.nvm/nvm.sh"
! nvm install --lts
msys_matrix:
permissions:
contents: none
name: 'MSYS nvm install'
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
npm-node-version:
- '--lts'
- '--default 12'
- '--no-progress 10'
steps:
- name: Retrieve nvm
shell: bash
run: |
unset npm_config_prefix
if [ "${{ matrix.npm-node-version }}" = "--lts" ]; then
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash
else
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD=script bash
fi
. "$HOME/.nvm/nvm.sh"
nvm install ${{ matrix.npm-node-version }}
cygwin_matrix:
continue-on-error: true
permissions:
contents: none
name: 'Cygwin nvm install'
runs-on: windows-latest
steps:
- name: Install Cygwin
shell: bash
run: |
export SITE='https://mirror.clarkson.edu/cygwin/' # see https://archlinux.org/mirrors/clarkson.edu/1603/ for uptime status
export SITE='https://mirrors.kernel.org/sourceware/cygwin/'
export LOCALDIR="$(pwd)"
export ROOTDIR="$USERPROFILE\\cygwin"
export PACKAGES='bash,git,curl'
curl -fsSLo setup-x86_64.exe 'https://cygwin.com/setup-x86_64.exe'
./setup-x86_64.exe --disable-buggy-antivirus -q -s "$SITE" -l "$LOCALDIR" -R "$ROOTDIR" -P "$PACKAGES"
cat >~/setup.sh <<EOM
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
nvm deactivate
rm -rf "$HOME/.nvm/nvm.sh"
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD=script bash
. "$HOME/.nvm/nvm.sh"
nvm install 9
EOM
- name: Retrieve nvm
shell: cmd
run: |
cd %USERPROFILE%\cygwin\bin
bash.exe "%USERPROFILE%\setup.sh"
wsl_matrix:
continue-on-error: true
name: 'WSL nvm install'
defaults:
run:
shell: wsl-bash {0}
runs-on: windows-latest
env:
WSLENV: NVM_INSTALL_GITHUB_REPO:NVM_INSTALL_VERSION:/p
strategy:
fail-fast: false
matrix:
wsl-distrib:
- Debian
# - Alpine # fails
- Ubuntu-20.04
- Ubuntu-18.04
npm-node-version:
- '--lts'
- '21'
- '18'
- '16'
- '14'
- '12'
- '10'
exclude:
- wsl-distrib: Ubuntu-18.04
npm-node-version: '--lts'
- wsl-distrib: Ubuntu-18.04
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
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
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash
else
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD="${{matrix.method}}" bash
fi
. "$HOME/.nvm/nvm.sh"
nvm install ${{ matrix.npm-node-version }}
node -v
wsl_matrix_unofficial:
continue-on-error: true
name: 'WSL nvm install'
defaults:
run:
shell: wsl-bash {0}
runs-on: windows-latest
env:
WSLENV: NVM_INSTALL_GITHUB_REPO:NVM_INSTALL_VERSION:/p
NVM_NODEJS_ORG_MIRROR: https://unofficial-builds.nodejs.org/download/release
strategy:
fail-fast: false
matrix:
wsl-distrib:
- Alpine
npm-node-version:
- '--lts'
- '21'
- '18'
- '16'
- '14'
- '12'
- '11'
- '10'
method:
- ''
- 'script'
steps:
- uses: Vampire/setup-wsl@v6
with:
distribution: ${{ matrix.wsl-distrib }}
additional-packages: bash git curl ca-certificates wget
- name: Retrieve nvm on WSL
run: |
if [ -z "${{ matrix.method }}" ]; then
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash
else
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD="${{matrix.method}}" bash
fi
. "$HOME/.nvm/nvm.sh"
NVM_NODEJS_ORG_MIRROR=${{ env.NVM_NODEJS_ORG_MIRROR }} nvm install ${{ matrix.npm-node-version }}
nvm_windows:
name: 'tests, on windows'
permissions:
contents: none
needs: [wsl_matrix, wsl_matrix_unofficial, cygwin_matrix, msys_matrix, msys_fail_install]
runs-on: ubuntu-latest
steps:
- run: true

447
AGENTS.md
View File

@@ -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.

3893
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
AGENTS.md

1
CNAME Normal file
View File

@@ -0,0 +1 @@
gtm-kqqwvx2-zgi2z.uc.r.appspot.com

View File

@@ -1,123 +0,0 @@
# Contributing
:+1::tada: First off, thanks for taking the time to contribute to `nvm`! :tada::+1:
We love pull requests and issues, they're our favorite.
The following is a set of guidelines for contributing to `nvm` managed by [@LJHarb](https://github.com/ljharb), which is hosted on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
However, before submitting, please review the following:
# How Can I Contribute?
There are lots of ways to get involved. Here are some suggestions of things we'd love some help with.
## Resolving existing issues
You can consider helping out with issues already requiring attention - look for a "help wanted" label.
### How Do I Submit a (Good) Bug Report? :bug:
Explain the problem and include additional details to help maintainers reproduce the problem:
* **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).
* **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.
## Documentation
We are happy to welcome contributions from anyone willing to improve documentation by adding missing information or making it more consistent and coherent.
# Dev Environment
Please refer to the [README](README.md) for complete instructions how to install, update, as well as troubleshoot `nvm` in your environment depending on your Operating System.
# Style Guide / Coding conventions
### Pull requests
#### Before creating a pull request
- Please include tests. Changes with tests will be merged very quickly.
- Please manually confirm that your changes work in `bash`, `sh`/`dash`, `ksh`, and `zsh`. Fast tests do run in these shells, but it's nice to manually verify also.
- Please maintain consistent whitespace - 2-space indentation, trailing newlines in all files, etc.
- Any time you make a change to your PR, please rebase freshly on top of the default branch. Nobody likes merge commits.
Even if you don't have all of these items covered, please still feel free to submit a PR/issue! Someone else may be inspired and volunteer to complete it for you.
#### How to create a pull request
Create a new branch
```
git checkout -b issue1234
```
Commit the changes to your branch, including a coherent commit message that follows our [standards](#commit-messages)
```
git commit -a
```
Before sending the pull request, make sure your code is running on the latest available code by rebasing onto the upstream source
```
git fetch upstream
git rebase upstream/main
```
Verify your changes
```
npm test
```
Push your changes
```
git push origin issue1234
```
Send the [pull request](https://docs.github.com/en/pull-requests), make requested changes, and get merged.
### Commit Messages
* Limit the first line of the commit message (message summary) to 72 characters or less.
* Use the present tense ("Add feature" not "Added feature") and imperative mood ("Move cursor to..." not "Moves cursor to...") when providing a description of what you did.
* If your PR addresses an issue, reference it in the body of the commit message.
* See the rest of the conventions [here](https://gist.github.com/ljharb/772b0334387a4bee89af24183114b3c7)
#### Commit message example
```
[Tag]: Short description of what you did
Longer description here if necessary
Fixes #1234
```
> **Note:** Add co-authors to your commit message for commits with multiple authors
```
Co-authored-by: Name Here <email@here>
```
# Code of Conduct
[Code of Conduct](https://github.com/nvm-sh/nvm/blob/HEAD/CODE_OF_CONDUCT.md)
# 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.

28
LICENSE Normal file
View File

@@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2025, DIMVY clothing brand
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2010 Tim Caswell
Copyright (c) 2014 Jordan Harband
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,49 +0,0 @@
# `nvm` Charter
nvm is a version manager for Node.js, 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.
## Section 0: Guiding Principles
The `nvm` project is part of the [OpenJS Foundation][openjs foundation], which operates transparently, openly, collaboratively, and ethically. Project proposals, timelines, and status must not merely be open, but also easily visible to outsiders.
## Section 1: Scope
`nvm` is a node version manager, focused on making it easy to install and manage multiple Node.js versions. Any features related to managing the installation and removal of Node.js on any node-supported platform are potentially in scope.
## Section 2: Relationship with OpenJS Foundation CPC.
Technical leadership for the projects within the [OpenJS Foundation][openjs foundation] is delegated to the projects through their project charters by the [OpenJS Foundation Cross-Project Council](https://openjsf.org/about/governance/) (CPC). In the case of the `nvm` project, it is delegated to the [`nvm` Maintainers](README.md#maintainers) (the “Maintainers”). The OpenJS Foundation's business leadership is the Board of Directors (the “Board”).
This `nvm` Charter reflects a carefully constructed balanced role for the Maintainers and the CPC in the governance of the OpenJS Foundation. The charter amendment process is for the Maintainers to propose changes using simple majority of the full Maintainers, the proposed changes being subject to review and approval by the CPC. The CPC may additionally make amendments to the project charter at any time, though the CPC will not interfere with day-to-day discussions, votes or meetings of the Maintainers.
### 2.1 Other Formal Project Relationships
Section Intentionally Left Blank
## Section 3: `nvm`'s Maintainers Governing Body
`nvm` is governed by its [maintainers](README.md#maintainers).
## Section 4: Roles & Responsibilities
The roles and responsibilities of `nvm`'s Maintainers are described in [GOVERNANCE.md](./GOVERNANCE.md).
### Section 4.1 Project Operations & Management
Section Intentionally Left Blank
### Section 4.2: Decision-making, Voting, and/or Elections
Section Intentionally Left Blank
### Section 4.3: Other Project Roles
Section Intentionally Left Blank
## Section 5: Definitions
- *Contributors*: contribute code or other artifacts, but do not have the right to commit to the codebase. Contributors work with the projects maintainers to have code committed to the code base. A Contributor may be promoted to a Maintainer by the Maintainers. Contributors should rarely be encumbered by the Maintainers and never by the CPC or OpenJS Foundation Board.
- *Maintainers*: Contributors with any kind of decision-making authority in the project.
[openjs foundation]: https://openjsf.org

1198
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@ nvm_install_dir() {
}
nvm_latest_version() {
nvm_echo "v0.40.4"
nvm_echo "v0.40.2"
}
nvm_profile_is_bash_or_zsh() {
@@ -67,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
@@ -149,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}" || {
@@ -166,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
}
@@ -219,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"
@@ -237,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
@@ -380,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
@@ -437,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
@@ -457,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
@@ -485,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

View File

@@ -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 "$@"

363
nvm.sh
View File

@@ -83,7 +83,7 @@ nvm_has_colors() {
if nvm_has tput; then
NVM_NUM_COLORS="$(command tput -T "${TERM:-vt100}" colors)"
fi
[ -t 1 ] && [ "${NVM_NUM_COLORS:--1}" -ge 8 ] && [ "${NVM_NO_COLORS-}" != '--no-colors' ]
[ "${NVM_NUM_COLORS:--1}" -ge 8 ] && [ "${NVM_NO_COLORS-}" != '--no-colors' ]
}
nvm_curl_libz_support() {
@@ -149,8 +149,7 @@ nvm_download() {
")
if [ -n "${NVM_AUTH_HEADER:-}" ]; then
sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")
ARGS="${ARGS} --header \"${sanitized_header}\""
ARGS="${ARGS} --header \"${NVM_AUTH_HEADER}\""
fi
# shellcheck disable=SC2086
eval wget $ARGS
@@ -357,19 +356,19 @@ nvm_install_latest_npm() {
if [ $NVM_IS_19_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 20.5.0; then
NVM_IS_20_5_OR_ABOVE=1
fi
local NVM_IS_20_17_OR_ABOVE
NVM_IS_20_17_OR_ABOVE=0
if [ $NVM_IS_20_5_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 20.17.0; then
NVM_IS_20_17_OR_ABOVE=1
local NVM_IS_20_17_or_ABOVE
NVM_IS_20_17_or_ABOVE=0
if [ $NVM_IS_20_5_OR_ABOVE -eq 1 ] && nvm_version_greater 20.17.0 "${NODE_VERSION}"; then
NVM_IS_20_17_or_ABOVE=1
fi
local NVM_IS_21_OR_ABOVE
NVM_IS_21_OR_ABOVE=0
if [ $NVM_IS_20_17_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 21.0.0; then
if [ $NVM_IS_20_17_or_ABOVE -eq 1 ] && nvm_version_greater 21.0.0 "${NODE_VERSION}"; then
NVM_IS_21_OR_ABOVE=1
fi
local NVM_IS_22_9_OR_ABOVE
NVM_IS_22_9_OR_ABOVE=0
if [ $NVM_IS_21_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 22.9.0; then
if [ $NVM_IS_21_OR_ABOVE -eq 1 ] && nvm_version_greater 22.9.0 "${NODE_VERSION}"; then
NVM_IS_22_9_OR_ABOVE=1
fi
@@ -421,7 +420,7 @@ nvm_install_latest_npm() {
nvm_echo '* `npm` `v9.x` is the last version that works on `node` `< v18.17`, `v19`, or `v20.0` - `v20.4`'
$NVM_NPM_CMD install -g npm@9
elif \
[ $NVM_IS_20_17_OR_ABOVE -eq 0 ] \
[ $NVM_IS_20_17_or_ABOVE -eq 0 ] \
|| { [ $NVM_IS_21_OR_ABOVE -eq 1 ] && [ $NVM_IS_22_9_OR_ABOVE -eq 0 ]; } \
; then
nvm_echo '* `npm` `v10.x` is the last version that works on `node` `< v20.17`, `v21`, or `v22.0` - `v22.8`'
@@ -602,6 +601,7 @@ EOF
}
nvm_rc_version() {
export NVM_RC_VERSION=''
local NVMRC_PATH
NVMRC_PATH="$(nvm_find_nvmrc)"
if [ ! -e "${NVMRC_PATH}" ]; then
@@ -611,7 +611,7 @@ nvm_rc_version() {
return 1
fi
local NVM_RC_VERSION
if ! NVM_RC_VERSION="$(nvm_process_nvmrc "${NVMRC_PATH}")"; then
return 1
fi
@@ -625,7 +625,6 @@ nvm_rc_version() {
if [ "${NVM_SILENT:-0}" -ne 1 ]; then
nvm_echo "Found '${NVMRC_PATH}' with version <${NVM_RC_VERSION}>"
fi
nvm_echo "${NVM_RC_VERSION}" >&3
}
nvm_clang_version() {
@@ -759,11 +758,6 @@ nvm_version() {
;;
esac
VERSION="$(nvm_ls "${PATTERN}" | command tail -1)"
case "${VERSION}" in
system[[:blank:]]*)
VERSION='system'
;;
esac
if [ -z "${VERSION}" ] || [ "_${VERSION}" = "_N/A" ]; then
nvm_echo "N/A"
return 3
@@ -787,15 +781,6 @@ nvm_remote_version() {
else
VERSION="$(NVM_LTS="${NVM_LTS-}" nvm_remote_versions "${PATTERN}" | command tail -1)"
fi
if [ -n "${PATTERN}" ] && [ "_${VERSION}" != "_N/A" ] && ! nvm_validate_implicit_alias "${PATTERN}" 2>/dev/null; then
local VERSION_NUM
VERSION_NUM="$(nvm_echo "${VERSION}" | command awk '{print $1}')"
if ! nvm_echo "${VERSION_NUM}" | nvm_grep -q "${PATTERN}"; then
VERSION='N/A'
fi
fi
if [ -n "${NVM_VERSION_ONLY-}" ]; then
command awk 'BEGIN {
n = split(ARGV[1], a);
@@ -878,10 +863,7 @@ ${NVM_LS_REMOTE_POST_MERGED_OUTPUT}" | nvm_grep -v "N/A" | command sed '/^ *$/d'
# the `sed` is to remove trailing whitespaces (see "weird behavior" ~25 lines up)
nvm_echo "${VERSIONS}" | command sed 's/ *$//g'
# shellcheck disable=SC2317
if [ "${NVM_LS_REMOTE_EXIT_CODE}" != '0' ]; then
return "${NVM_LS_REMOTE_EXIT_CODE}"
fi
return "${NVM_LS_REMOTE_IOJS_EXIT_CODE}"
return $NVM_LS_REMOTE_EXIT_CODE || $NVM_LS_REMOTE_IOJS_EXIT_CODE
}
nvm_is_valid_version() {
@@ -935,14 +917,10 @@ nvm_normalize_lts() {
fi
;;
*)
case "${LTS}" in
lts/*)
if [ "${LTS}" != "$(echo "${LTS}" | command tr '[:upper:]' '[:lower:]')" ]; then
nvm_err 'LTS names must be lowercase'
return 3
fi
;;
esac
if [ "${LTS}" != "$(echo "${LTS}" | command tr '[:upper:]' '[:lower:]')" ]; then
nvm_err 'LTS names must be lowercase'
return 3
fi
nvm_echo "${LTS}"
;;
esac
@@ -991,18 +969,13 @@ nvm_strip_path() {
nvm_err '${NVM_DIR} not set!'
return 1
fi
local RESULT
RESULT="$(command printf %s "${1-}" | command awk -v NVM_DIR="${NVM_DIR}" -v RS=: '
command printf %s "${1-}" | command awk -v NVM_DIR="${NVM_DIR}" -v RS=: '
index($0, NVM_DIR) == 1 {
path = substr($0, length(NVM_DIR) + 1)
if (path ~ "^(/versions/[^/]*)?/[^/]*'"${2-}"'.*$") { next }
}
{ printf "%s%s", sep, $0; sep=RS }')"
# mawk does not support RT, so preserve trailing colon manually
case "${1-}" in
*:) command printf '%s:' "${RESULT}" ;;
*) command printf '%s' "${RESULT}" ;;
esac
# The final RT will contain a colon if the input has a trailing colon, or a null string otherwise
{ printf "%s%s", sep, $0; sep=RS } END { printf "%s", RT }'
}
nvm_change_path() {
@@ -1160,7 +1133,7 @@ nvm_print_formatted_alias() {
fi
local ARROW
ARROW='->'
if [ "${NVM_HAS_COLORS-}" = 1 ] || nvm_has_colors; then
if nvm_has_colors; then
ARROW='\033[0;90m->\033[0m'
if [ "_${DEFAULT}" = '_true' ]; then
NEWLINE=" \033[${DEFAULT_COLOR}(default)\033[0m\n"
@@ -1261,17 +1234,11 @@ nvm_list_aliases() {
return $?
fi
local NVM_HAS_COLORS
NVM_HAS_COLORS=0
if nvm_has_colors; then
NVM_HAS_COLORS=1
fi
nvm_is_zsh && unsetopt local_options nomatch
(
local ALIAS_PATH
for ALIAS_PATH in "${NVM_ALIAS_DIR}/${ALIAS}"*; do
NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_HAS_COLORS="${NVM_HAS_COLORS}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}" &
NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}" &
done
wait
) | command sort
@@ -1282,7 +1249,7 @@ nvm_list_aliases() {
{
# shellcheck disable=SC2030,SC2031 # (https://github.com/koalaman/shellcheck/issues/2217)
if [ ! -f "${NVM_ALIAS_DIR}/${ALIAS_NAME}" ] && { [ -z "${ALIAS}" ] || [ "${ALIAS_NAME}" = "${ALIAS}" ]; }; then
NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_HAS_COLORS="${NVM_HAS_COLORS}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_default_alias "${ALIAS_NAME}"
NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_default_alias "${ALIAS_NAME}"
fi
} &
done
@@ -1294,7 +1261,7 @@ nvm_list_aliases() {
# shellcheck disable=SC2030,SC2031 # (https://github.com/koalaman/shellcheck/issues/2217)
for ALIAS_PATH in "${NVM_ALIAS_DIR}/lts/${ALIAS}"*; do
{
LTS_ALIAS="$(NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_HAS_COLORS="${NVM_HAS_COLORS}" NVM_LTS=true nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}")"
LTS_ALIAS="$(NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_LTS=true nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}")"
if [ -n "${LTS_ALIAS}" ]; then
nvm_echo "${LTS_ALIAS}"
fi
@@ -1327,7 +1294,7 @@ nvm_alias() {
return 2
fi
command sed 's/#.*//; s/[[:space:]]*$//' "${NVM_ALIAS_PATH}" | command awk 'NF'
command awk 'NF' "${NVM_ALIAS_PATH}"
}
nvm_ls_current() {
@@ -1372,7 +1339,7 @@ nvm_resolve_alias() {
break
fi
if command printf '%b' "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then
if command printf "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then
ALIAS="∞"
break
fi
@@ -1481,18 +1448,6 @@ nvm_ls() {
PATTERN="${PATTERN}-"
;;
*)
local ALIAS_TARGET
ALIAS_TARGET="$(nvm_resolve_alias "${PATTERN}" 2>/dev/null || nvm_echo)"
if [ "_${ALIAS_TARGET}" = '_system' ] && (nvm_has_system_iojs || nvm_has_system_node); then
local SYSTEM_VERSION
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
if [ -n "${SYSTEM_VERSION}" ]; then
nvm_echo "system ${SYSTEM_VERSION}"
else
nvm_echo "system"
fi
return
fi
if nvm_resolve_local_alias "${PATTERN}"; then
return
fi
@@ -1574,7 +1529,7 @@ nvm_ls() {
PATTERN='v'
SEARCH_PATTERN='.*'
else
SEARCH_PATTERN="$(nvm_echo "${PATTERN}" | command sed 's#\.#\\\.#g; s|#|\\#|g')"
SEARCH_PATTERN="$(nvm_echo "${PATTERN}" | command sed 's#\.#\\\.#g;')"
fi
if [ -n "${NVM_DIRS_TO_SEARCH1}${NVM_DIRS_TO_SEARCH2}${NVM_DIRS_TO_SEARCH3}" ]; then
VERSIONS="$(command find "${NVM_DIRS_TO_SEARCH1}"/* "${NVM_DIRS_TO_SEARCH2}"/* "${NVM_DIRS_TO_SEARCH3}"/* -name . -o -type d -prune -o -path "${PATTERN}*" \
@@ -1596,24 +1551,13 @@ nvm_ls() {
fi
if [ "${NVM_ADD_SYSTEM-}" = true ]; then
local SYSTEM_VERSION
SYSTEM_VERSION="$(nvm deactivate >/dev/null 2>&1 && node -v 2>/dev/null)"
case "${PATTERN}" in
'' | v)
if [ -n "${SYSTEM_VERSION}" ]; then
VERSIONS="${VERSIONS}
system ${SYSTEM_VERSION}"
else
VERSIONS="${VERSIONS}
VERSIONS="${VERSIONS}
system"
fi
;;
system)
if [ -n "${SYSTEM_VERSION}" ]; then
VERSIONS="system ${SYSTEM_VERSION}"
else
VERSIONS="system"
fi
VERSIONS="system"
;;
esac
fi
@@ -1955,7 +1899,6 @@ BEGIN {
fmt_latest_lts = has_colors && latest_lts_color ? ("\033[" latest_lts_color " (Latest LTS: %s)\033[0m") : " (Latest LTS: %s)";
fmt_old_lts = has_colors && old_lts_color ? ("\033[" old_lts_color " (LTS: %s)\033[0m") : " (LTS: %s)";
fmt_system_target = has_colors && system_color ? (" (\033[" system_color "-> %s\033[0m)") : " (-> %s)";
split(remote_versions, lines, "|");
split(installed_versions, installed, "|");
@@ -1987,8 +1930,6 @@ BEGIN {
if (cols == 1) {
formatted = sprintf(fmt_version, version);
} else if (version == "system" && cols >= 2) {
formatted = sprintf((fmt_version fmt_system_target), version, fields[2]);
} else if (cols == 2) {
formatted = sprintf((fmt_version padding fmt_old_lts), version, fields[2]);
} else if (cols == 3 && fields[3] == "*") {
@@ -2166,7 +2107,7 @@ nvm_get_arch() {
# If running a 64bit ARM kernel but a 32bit ARM userland,
# change ARCH to 32bit ARM (armv7l) if /sbin/init is 32bit executable
if [ "$(command uname)" = "Linux" ] \
if [ "$(uname)" = "Linux" ] \
&& [ "${NVM_ARCH}" = arm64 ] \
&& [ "$(command od -An -t x1 -j 4 -N 1 "/sbin/init" 2>/dev/null)" = ' 01' ]\
; then
@@ -2175,10 +2116,7 @@ nvm_get_arch() {
fi
if [ -f "/etc/alpine-release" ]; then
# Alpine Linux uses musl libc; only x64-musl binaries are available
case "${NVM_ARCH}" in
x64) NVM_ARCH=x64-musl ;;
esac
NVM_ARCH=x64-musl
fi
nvm_echo "${NVM_ARCH}"
@@ -2254,7 +2192,7 @@ nvm_get_mirror() {
esac
if ! nvm_echo "${NVM_MIRROR}" | command awk '{ if ($0 !~ /^https?:\/\/[a-zA-Z0-9.\/_-]+$/) exit 1 }'; then
if ! nvm_echo "${NVM_MIRROR}" | command awk '{ $0 ~ "^https?://[a-zA-Z0-9./_-]+$" }'; then
nvm_err '$NVM_NODEJS_ORG_MIRROR and $NVM_IOJS_ORG_MIRROR may only contain a URL'
return 2
fi
@@ -2286,7 +2224,7 @@ nvm_install_binary_extract() {
command mkdir -p "${TMPDIR}" && \
VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" || return 1
# For Windows system (Git Bash with MSYS, Cygwin)
# For Windows system (GitBash with MSYS, Cygwin)
if [ "${NVM_OS}" = 'win' ]; then
VERSION_PATH="${VERSION_PATH}/bin"
command unzip -q "${TARBALL}" -d "${TMPDIR}" || return 1
@@ -2378,7 +2316,7 @@ nvm_install_binary() {
# Read nosource from arguments
if [ "${nosource-}" = '1' ]; then
nvm_err 'Binary download failed. Download from source aborted.'
return 2
return 0
fi
nvm_err 'Binary download failed, trying source.'
@@ -2506,35 +2444,22 @@ nvm_download_artifact() {
local COMPRESSION
COMPRESSION="$(nvm_get_artifact_compression "${VERSION}")"
local CHECKSUM
CHECKSUM="$(nvm_get_checksum "${FLAVOR}" "${TYPE}" "${VERSION}" "${SLUG}" "${COMPRESSION}")"
local tmpdir
if [ "${KIND}" = 'binary' ]; then
tmpdir="$(nvm_cache_dir)/bin/${SLUG}"
else
tmpdir="$(nvm_cache_dir)/src/${SLUG}"
fi
command mkdir -p "${tmpdir}/files" || (
nvm_err "creating directory ${tmpdir}/files failed"
return 3
)
local TARBALL
TARBALL="${tmpdir}/${SLUG}.${COMPRESSION}"
if [ "${NVM_OFFLINE-}" = 1 ]; then
# In offline mode, use cached tarball without checksum or download
if [ -r "${TARBALL}" ]; then
nvm_err "Offline: using cached archive $(nvm_sanitize_path "${TARBALL}")"
nvm_echo "${TARBALL}"
return 0
fi
nvm_err "Offline: no cached archive found for ${SLUG}"
return 4
fi
local CHECKSUM
CHECKSUM="$(nvm_get_checksum "${FLAVOR}" "${TYPE}" "${VERSION}" "${SLUG}" "${COMPRESSION}")"
command mkdir -p "${tmpdir}/files" || {
nvm_err "creating directory ${tmpdir}/files failed"
return 3
}
local TARBALL_URL
if nvm_version_greater_than_or_equal_to "${VERSION}" 0.1.14; then
TARBALL_URL="${MIRROR}/${VERSION}/${SLUG}.${COMPRESSION}"
@@ -2556,11 +2481,11 @@ nvm_download_artifact() {
command rm -rf "${TARBALL}"
fi
nvm_err "Downloading ${TARBALL_URL}..."
nvm_download -L -C - "${PROGRESS_BAR}" "${TARBALL_URL}" -o "${TARBALL}" || {
nvm_download -L -C - "${PROGRESS_BAR}" "${TARBALL_URL}" -o "${TARBALL}" || (
command rm -rf "${TARBALL}" "${tmpdir}"
nvm_err "download from ${TARBALL_URL} failed"
return 4
}
)
if nvm_grep '404 Not Found' "${TARBALL}" >/dev/null; then
command rm -rf "${TARBALL}" "${tmpdir}"
@@ -2568,10 +2493,10 @@ nvm_download_artifact() {
return 5
fi
nvm_compare_checksum "${TARBALL}" "${CHECKSUM}" || {
nvm_compare_checksum "${TARBALL}" "${CHECKSUM}" || (
command rm -rf "${tmpdir}/files"
return 6
}
)
nvm_echo "${TARBALL}"
}
@@ -2708,24 +2633,18 @@ nvm_install_source() {
NVM_OS="$(nvm_get_os)"
local make
make='make'
local MAKE_CXX
# For old Node.js versions (< 0.12), explicitly set SHELL=/bin/sh to avoid
# issues with zsh's strict glob handling in Makefiles with unquoted globs
local MAKE_SHELL_OVERRIDE
if nvm_version_greater "0.12.0" "${VERSION}"; then
MAKE_SHELL_OVERRIDE=' SHELL=/bin/sh'
fi
make="make${MAKE_SHELL_OVERRIDE-}"
case "${NVM_OS}" in
'freebsd' | 'openbsd')
make="gmake${MAKE_SHELL_OVERRIDE-}"
make='gmake'
MAKE_CXX="CC=${CC:-cc} CXX=${CXX:-c++}"
;;
'darwin')
MAKE_CXX="CC=${CC:-cc} CXX=${CXX:-c++}"
;;
'aix')
make="gmake${MAKE_SHELL_OVERRIDE-}"
make='gmake'
;;
esac
if nvm_has "clang++" && nvm_has "clang" && nvm_version_greater_than_or_equal_to "$(nvm_clang_version)" 3.5; then
@@ -2971,7 +2890,7 @@ nvm_iojs_version_has_solaris_binary() {
IOJS_VERSION="$1"
local STRIPPED_IOJS_VERSION
STRIPPED_IOJS_VERSION="$(nvm_strip_iojs_prefix "${IOJS_VERSION}")"
if [ "_${STRIPPED_IOJS_VERSION}" = "_${IOJS_VERSION}" ]; then
if [ "_${STRIPPED_IOJS_VERSION}" = "${IOJS_VERSION}" ]; then
return 1
fi
@@ -3066,8 +2985,7 @@ nvm_check_file_permissions() {
if [ ! -L "${FILE}" ] && ! nvm_check_file_permissions "${FILE}"; then
return 2
fi
elif [ -e "$FILE" ] && [ ! -w "$FILE" ] && [ -z "$(command find "${FILE}" -prune -user "$(command id -u)")" ]; then
# ^ file ownership check from https://www.shellcheck.net/wiki/SC3067
elif [ -e "$FILE" ] && [ ! -w "$FILE" ] && [ ! -O "$FILE" ]; then
nvm_err "file is not writable or self-owned: $(nvm_sanitize_path "$FILE")"
return 1
fi
@@ -3079,57 +2997,6 @@ nvm_cache_dir() {
nvm_echo "${NVM_DIR}/.cache"
}
# args: pattern
# Lists versions available in the local cache (not yet installed).
# Returns version numbers like "v18.20.4", one per line, sorted.
nvm_ls_cached() {
local PATTERN
PATTERN="${1-}"
local CACHE_BIN_DIR
CACHE_BIN_DIR="$(nvm_cache_dir)/bin"
if [ ! -d "${CACHE_BIN_DIR}" ]; then
return
fi
local NVM_OS
NVM_OS="$(nvm_get_os)"
local NVM_ARCH
NVM_ARCH="$(nvm_get_arch)"
local SUFFIX
SUFFIX="${NVM_OS}-${NVM_ARCH}"
# shellcheck disable=SC2010
command ls -1 "${CACHE_BIN_DIR}" \
| nvm_grep "^node-v.*-${SUFFIX}\$" \
| command sed "s/^node-\\(v[0-9][0-9.]*\\)-${SUFFIX}\$/\\1/" \
| nvm_grep "$(nvm_ensure_version_prefix "${PATTERN}")" \
| command sort -t. -u -k 1.2,1n -k 2,2n -k 3,3n
}
# args: pattern
# Resolves a version pattern to a single version using only locally
# installed versions and cached downloads. No network access.
nvm_offline_version() {
local PATTERN
PATTERN="${1-}"
# First try locally installed versions
local VERSION
VERSION="$(nvm_version "${PATTERN}")"
if [ "_${VERSION}" != '_N/A' ]; then
nvm_echo "${VERSION}"
return 0
fi
# Then try cached downloads
VERSION="$(nvm_ls_cached "${PATTERN}" | command tail -1)"
if [ -n "${VERSION}" ]; then
nvm_echo "${VERSION}"
return 0
fi
nvm_echo 'N/A'
return 3
}
nvm() {
if [ "$#" -lt 1 ]; then
nvm --help
@@ -3210,7 +3077,6 @@ nvm() {
nvm_echo ' --skip-default-packages When installing, skip the default-packages file if it exists'
nvm_echo ' --latest-npm After installing, attempt to upgrade to the latest working npm on the given node version'
nvm_echo ' --no-progress Disable the progress bar on any downloads'
nvm_echo ' --offline Install from cache only, without downloading anything'
nvm_echo ' --alias=<name> After installing, set the alias specified to the version specified. (same as: nvm alias <name> <version>)'
nvm_echo ' --default After installing, set default alias to the version specified. (same as: nvm alias default <version>)'
nvm_echo ' --save After installing, write the specified version to .nvmrc'
@@ -3336,10 +3202,10 @@ nvm() {
nvm_err "\${HOME}: ${HOME}"
nvm_err "\${NVM_DIR}: '$(nvm_sanitize_path "${NVM_DIR}")'"
nvm_err "\${PATH}: $(nvm_sanitize_path "${PATH}")"
nvm_err "\$PREFIX: '$(nvm_sanitize_path "${PREFIX-}")'"
nvm_err "\${NPM_CONFIG_PREFIX}: '$(nvm_sanitize_path "${NPM_CONFIG_PREFIX-}")'"
nvm_err "\$NVM_NODEJS_ORG_MIRROR: '${NVM_NODEJS_ORG_MIRROR-}'"
nvm_err "\$NVM_IOJS_ORG_MIRROR: '${NVM_IOJS_ORG_MIRROR-}'"
nvm_err "\$PREFIX: '$(nvm_sanitize_path "${PREFIX}")'"
nvm_err "\${NPM_CONFIG_PREFIX}: '$(nvm_sanitize_path "${NPM_CONFIG_PREFIX}")'"
nvm_err "\$NVM_NODEJS_ORG_MIRROR: '${NVM_NODEJS_ORG_MIRROR}'"
nvm_err "\$NVM_IOJS_ORG_MIRROR: '${NVM_IOJS_ORG_MIRROR}'"
nvm_err "shell version: '$(${SHELL} --version | command head -n 1)'"
nvm_err "uname -a: '$(command uname -a | command awk '{$2=""; print}' | command xargs)'"
nvm_err "checksum binary: '$(nvm_get_checksum_binary 2>/dev/null)'"
@@ -3416,6 +3282,11 @@ nvm() {
local NVM_OS
NVM_OS="$(nvm_get_os)"
if ! nvm_has "curl" && ! nvm_has "wget"; then
nvm_err 'nvm needs curl or wget to proceed.'
return 1
fi
if [ $# -lt 1 ]; then
version_not_provided=1
fi
@@ -3423,11 +3294,9 @@ nvm() {
local nobinary
local nosource
local noprogress
local NVM_OFFLINE
nobinary=0
noprogress=0
nosource=0
NVM_OFFLINE=0
local LTS
local ALIAS
local NVM_UPGRADE_NPM
@@ -3449,7 +3318,7 @@ nvm() {
shift # consume "-s"
nobinary=1
if [ $nosource -eq 1 ]; then
nvm_err '-s and -b cannot be set together since they would skip install from both binary and source'
nvm err '-s and -b cannot be set together since they would skip install from both binary and source'
return 6
fi
;;
@@ -3457,7 +3326,7 @@ nvm() {
shift # consume "-b"
nosource=1
if [ $nobinary -eq 1 ]; then
nvm_err '-s and -b cannot be set together since they would skip install from both binary and source'
nvm err '-s and -b cannot be set together since they would skip install from both binary and source'
return 6
fi
;;
@@ -3470,10 +3339,6 @@ nvm() {
noprogress=1
shift
;;
--offline)
NVM_OFFLINE=1
shift
;;
--lts)
LTS='*'
shift
@@ -3550,11 +3415,6 @@ nvm() {
esac
done
if [ "${NVM_OFFLINE}" != 1 ] && ! nvm_has "curl" && ! nvm_has "wget"; then
nvm_err 'nvm needs curl or wget to proceed.'
return 1
fi
local provided_version
provided_version="${1-}"
@@ -3570,11 +3430,14 @@ nvm() {
shift
fi
else
{ provided_version="$(nvm_rc_version 3>&1 1>&4)"; } 4>&1
if [ $version_not_provided -eq 1 ] && [ -z "${provided_version}" ]; then
nvm_rc_version
if [ $version_not_provided -eq 1 ] && [ -z "${NVM_RC_VERSION}" ]; then
unset NVM_RC_VERSION
>&2 nvm --help
return 127
fi
provided_version="${NVM_RC_VERSION}"
unset NVM_RC_VERSION
fi
elif [ $# -gt 0 ]; then
shift
@@ -3592,27 +3455,8 @@ nvm() {
esac
local EXIT_CODE
if [ "${NVM_OFFLINE}" = 1 ]; then
local OFFLINE_PATTERN
OFFLINE_PATTERN="${provided_version}"
if [ -n "${LTS-}" ]; then
if [ "${LTS}" = '*' ]; then
OFFLINE_PATTERN="$(nvm_resolve_alias 'lts/*' 2>/dev/null || nvm_echo)"
else
OFFLINE_PATTERN="$(nvm_resolve_alias "lts/${LTS}" 2>/dev/null || nvm_echo)"
fi
if [ -z "${OFFLINE_PATTERN}" ]; then
nvm_err "LTS alias '${LTS}' not found locally. Run \`nvm ls-remote --lts\` first to populate LTS aliases."
return 3
fi
fi
VERSION="$(nvm_offline_version "${OFFLINE_PATTERN}")"
EXIT_CODE="$?"
else
VERSION="$(NVM_VERSION_ONLY=true NVM_LTS="${LTS-}" nvm_remote_version "${provided_version}")"
EXIT_CODE="$?"
fi
VERSION="$(NVM_VERSION_ONLY=true NVM_LTS="${LTS-}" nvm_remote_version "${provided_version}")"
EXIT_CODE="$?"
if [ "${VERSION}" = 'N/A' ] || [ $EXIT_CODE -ne 0 ]; then
local LTS_MSG
@@ -3628,17 +3472,9 @@ nvm() {
return 3
fi
else
if [ "${NVM_OFFLINE}" = 1 ]; then
REMOTE_CMD='nvm ls'
else
REMOTE_CMD='nvm ls-remote'
fi
fi
if [ "${NVM_OFFLINE}" = 1 ]; then
nvm_err "Version '${provided_version}' ${LTS_MSG-}not found locally or in cache - try \`${REMOTE_CMD}\` to browse available versions."
else
nvm_err "Version '${provided_version}' ${LTS_MSG-}not found - try \`${REMOTE_CMD}\` to browse available versions."
REMOTE_CMD='nvm ls-remote'
fi
nvm_err "Version '${provided_version}' ${LTS_MSG-}not found - try \`${REMOTE_CMD}\` to browse available versions."
return 3
fi
@@ -3778,7 +3614,7 @@ nvm() {
# skip binary install if "nobinary" option specified.
if [ $nobinary -ne 1 ] && nvm_binary_available "${VERSION}"; then
NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" NVM_OFFLINE="${NVM_OFFLINE}" nvm_install_binary "${FLAVOR}" std "${VERSION}" "${nosource}"
NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_binary "${FLAVOR}" std "${VERSION}" "${nosource}"
EXIT_CODE=$?
else
EXIT_CODE=-1
@@ -3797,7 +3633,7 @@ nvm() {
nvm_err 'Installing from source on non-WSL Windows is not supported'
EXIT_CODE=87
else
NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" NVM_OFFLINE="${NVM_OFFLINE}" nvm_install_source "${FLAVOR}" std "${VERSION}" "${NVM_MAKE_JOBS}" "${ADDITIONAL_PARAMETERS}"
NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_source "${FLAVOR}" std "${VERSION}" "${NVM_MAKE_JOBS}" "${ADDITIONAL_PARAMETERS}"
EXIT_CODE=$?
fi
fi
@@ -3862,13 +3698,7 @@ nvm() {
fi
if ! nvm_is_version_installed "${VERSION}"; then
local REQUESTED_VERSION
REQUESTED_VERSION="${PATTERN}"
if [ "_${VERSION}" != "_N/A" ] && [ "_${VERSION}" != "_${PATTERN}" ]; then
nvm_err "Version '${VERSION}' (inferred from ${PATTERN}) is not installed."
else
nvm_err "Version '${REQUESTED_VERSION}' is not installed."
fi
nvm_err "${VERSION} version is not installed..."
return
fi
@@ -3910,7 +3740,7 @@ nvm() {
nvm_echo "${NVM_SUCCESS_MSG}"
# rm any aliases that point to uninstalled version.
for ALIAS in $(nvm_grep -l "${VERSION}" "$(nvm_alias_path)"/* 2>/dev/null); do
for ALIAS in $(nvm_grep -l "${VERSION}" "$(nvm_alias_path)/*" 2>/dev/null); do
nvm unalias "$(command basename "${ALIAS}")"
done
;;
@@ -4005,11 +3835,13 @@ nvm() {
if [ -n "${NVM_LTS-}" ]; then
VERSION="$(nvm_match_version "lts/${NVM_LTS:-*}")"
elif [ -z "${PROVIDED_VERSION-}" ]; then
{ PROVIDED_VERSION="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1
if [ -n "${PROVIDED_VERSION}" ]; then
NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version
if [ -n "${NVM_RC_VERSION-}" ]; then
PROVIDED_VERSION="${NVM_RC_VERSION}"
IS_VERSION_FROM_NVMRC=1
VERSION="$(nvm_version "${PROVIDED_VERSION}")"
fi
unset NVM_RC_VERSION
if [ -z "${VERSION}" ]; then
nvm_err 'Please see `nvm --help` or https://github.com/nvm-sh/nvm#nvmrc for more information.'
return 127
@@ -4137,11 +3969,11 @@ nvm() {
done
if [ $# -lt 1 ] && [ -z "${NVM_LTS-}" ]; then
local NVM_RC_VERSION
{ NVM_RC_VERSION="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
if [ -n "${NVM_RC_VERSION}" ]; then
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1
if [ -n "${NVM_RC_VERSION-}" ]; then
VERSION="$(nvm_version "${NVM_RC_VERSION-}")" ||:
fi
unset NVM_RC_VERSION
if [ "${VERSION:-N/A}" = 'N/A' ]; then
>&2 nvm --help
return 127
@@ -4155,11 +3987,12 @@ nvm() {
if [ "_${VERSION:-N/A}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then
provided_version=''
if [ $has_checked_nvmrc -ne 1 ]; then
{ NVM_RC_VERSION="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1
fi
provided_version="${NVM_RC_VERSION}"
IS_VERSION_FROM_NVMRC=1
VERSION="$(nvm_version "${NVM_RC_VERSION}")" ||:
unset NVM_RC_VERSION
else
shift
fi
@@ -4220,7 +4053,9 @@ nvm() {
elif [ -n "${provided_version}" ]; then
VERSION="$(nvm_version "${provided_version}")" ||:
if [ "_${VERSION}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then
{ provided_version="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1 && has_checked_nvmrc=1
NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1
provided_version="${NVM_RC_VERSION}"
unset NVM_RC_VERSION
VERSION="$(nvm_version "${provided_version}")" ||:
else
shift
@@ -4351,10 +4186,12 @@ nvm() {
shift
done
if [ -z "${provided_version-}" ]; then
{ provided_version="$(NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version 3>&1 1>&4)"; } 4>&1
if [ -n "${provided_version}" ]; then
VERSION=$(nvm_version "${provided_version}") ||:
NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version
if [ -n "${NVM_RC_VERSION}" ]; then
provided_version="${NVM_RC_VERSION}"
VERSION=$(nvm_version "${NVM_RC_VERSION}") ||:
fi
unset NVM_RC_VERSION
elif [ "${provided_version}" != 'system' ]; then
VERSION="$(nvm_version "${provided_version}")" ||:
else
@@ -4378,7 +4215,7 @@ nvm() {
nvm_err 'System version of node not found.'
return 127
elif [ "${VERSION}" = '∞' ]; then
nvm_err "The alias \"${provided_version}\" leads to an infinite loop. Aborting."
nvm_err "The alias \"${2}\" leads to an infinite loop. Aborting."
return 8
fi
@@ -4601,7 +4438,7 @@ nvm() {
NVM_VERSION_ONLY=true NVM_LTS="${NVM_LTS-}" nvm_remote_version "${PATTERN:-node}"
;;
"--version" | "-v")
nvm_echo '0.40.4'
nvm_echo '0.40.2'
;;
"unload")
nvm deactivate >/dev/null 2>&1
@@ -4624,7 +4461,7 @@ nvm() {
nvm_binary_available nvm_change_path nvm_strip_path \
nvm_num_version_groups nvm_format_version nvm_ensure_version_prefix \
nvm_normalize_version nvm_is_valid_version nvm_normalize_lts \
nvm_ensure_version_installed nvm_cache_dir nvm_ls_cached nvm_offline_version \
nvm_ensure_version_installed nvm_cache_dir \
nvm_version_path nvm_alias_path nvm_version_dir \
nvm_find_nvmrc nvm_find_up nvm_find_project_dir nvm_tree_contains_path \
nvm_version_greater nvm_version_greater_than_or_equal_to \
@@ -4649,7 +4486,7 @@ nvm() {
nvm_process_nvmrc nvm_nvmrc_invalid_msg \
nvm_write_nvmrc \
>/dev/null 2>&1
unset NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR \
NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS \
NVM_COLORS INSTALLED_COLOR SYSTEM_COLOR \
CURRENT_COLOR NOT_INSTALLED_COLOR DEFAULT_COLOR LTS_COLOR \
@@ -4677,9 +4514,9 @@ nvm_get_default_packages() {
NVM_DEFAULT_PACKAGE_FILE="${NVM_DIR}/default-packages"
if [ -f "${NVM_DEFAULT_PACKAGE_FILE}" ]; then
command awk -v filename="${NVM_DEFAULT_PACKAGE_FILE}" '
/^[ \t]*#/ { next } # Skip lines that begin with #
/^[ \t]*$/ { next } # Skip empty lines
/[ \t]/ && !/^[ \t]*#/ {
/^[[:space:]]*#/ { next } # Skip lines that begin with #
/^[[:space:]]*$/ { next } # Skip empty lines
/[[:space:]]/ && !/^[[:space:]]*#/ {
print "Only one package per line is allowed in `" filename "`. Please remove any lines with multiple space-separated values." > "/dev/stderr"
err = 1
exit 1
@@ -4781,7 +4618,7 @@ nvm_auto() {
else
return 0
fi
elif nvm_rc_version 3>/dev/null >/dev/null 2>&1; then
elif nvm_rc_version >/dev/null 2>&1; then
nvm use --silent >/dev/null
fi
else
@@ -4793,7 +4630,7 @@ nvm_auto() {
VERSION="$(nvm_alias default 2>/dev/null || nvm_echo)"
if [ -n "${VERSION}" ] && [ "_${VERSION}" != '_N/A' ] && nvm_is_valid_version "${VERSION}"; then
nvm install "${VERSION}" >/dev/null
elif nvm_rc_version 3>/dev/null >/dev/null 2>&1; then
elif nvm_rc_version >/dev/null 2>&1; then
nvm install >/dev/null
else
return 0

View File

@@ -1,6 +1,6 @@
{
"name": "nvm",
"version": "0.40.4",
"version": "0.40.2",
"description": "Node Version Manager - Simple bash script to manage multiple active node.js versions",
"directories": {
"test": "test"
@@ -45,9 +45,9 @@
"dockerfile_lint": "^0.3.4",
"doctoc": "^2.2.1",
"eclint": "^2.8.1",
"markdown-link-check": "^3.14.2",
"markdown-link-check": "^3.13.7",
"replace": "^1.2.2",
"semver": "^7.7.3",
"semver": "^7.7.1",
"urchin": "^0.0.5"
}
}

View File

@@ -1,52 +0,0 @@
#! /usr/bin/env bash
find_name(){
find test -name "*[\\/:\*\?\"<>\|]*" -o -name "*."
}
check_name() {
if [ "$(find_name | wc -l)" != "0" ]; then
printf '%s\n\n' "The following filenames contain unwanted characters:"
find_name
printf '\n%s\n%s\n' "Please run ./rename_test.sh" "If the problem persist, please open an issue."
exit 1
else
echo "Ok"
fi
}
rename_test() {
local filename
local new_filename
while read -r filename; do
# Even though it looks < and > are replaced by the same < and >, the latters are not ASCII code
# If you check with 'cat -v rename_test.sh' you would see 's/</M-KM-^B/g' and 's/>/M-KM-^C/g'
# M-KM-^B -> U+02C2
# M-KM-^C -> U+02C3
new_filename=$(echo "$filename" | sed -r \
-e "s/\"/'/g" \
-e 's/</˂/g' \
-e 's/>/˃/g' \
-e 's/^(.*)\.$/\1/'
)
printf '%s\n%s\n\n' "$filename" "$new_filename"
[ "$filename" != "$new_filename" ] && git mv "$filename" "$new_filename"
done < <(find_name)
if [ "$(find_name | wc -l)" != "0" ]; then
echo "Still some files to treat:"
find_name
else
echo "Done"
fi
}
main() {
if [ "$1" = "--check" ]; then
check_name
else
rename_test
fi
}
main "$@"

View File

@@ -1,29 +1,3 @@
# 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

View File

@@ -4,7 +4,6 @@ die() { echo "$@" ; exit 1; }
export NVM_DIR="$(cd ../../.. && pwd)"
: nvm.sh
\. "${NVM_DIR}/nvm.sh"
\. ../../common.sh

View File

@@ -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'"

View File

@@ -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'"

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
die () { echo "$@" ; exit 1; }

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
die () { echo "$@" ; exit 1; }

View File

@@ -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'"

View File

@@ -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'"

View File

@@ -1,5 +1,4 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
[ $(nvm alias test-stable-1 | wc -l) = '2' ]

View File

@@ -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'"

View File

@@ -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

View File

@@ -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'"

View File

@@ -3,7 +3,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../../nvm.sh
ALIAS="$(nvm_resolve_alias loopback | strip_colors)"

View File

@@ -3,7 +3,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../../nvm.sh
ALIAS="$(nvm_resolve_local_alias loopback | strip_colors)"

View File

@@ -2,7 +2,6 @@
set -ex
: nvm.sh
\. ../../../../nvm.sh
\. ../../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../../nvm.sh
LTS_ALIAS_PATH="$(nvm_alias_path)/lts"

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../../nvm.sh
LTS_ALIAS_PATH="$(nvm_alias_path)/lts"

View File

@@ -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'"

View File

@@ -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"
}

View File

@@ -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

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
die () {

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
die () {

View File

@@ -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"
}

View File

@@ -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 ")"

View File

@@ -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

View File

@@ -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 $?)

View File

@@ -2,7 +2,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
EXIT_CODE=$(nvm_resolve_local_alias ; echo $?)

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +0,0 @@
#!/bin/sh
echo v0.0.1 > ../../../../alias/test-%s-alias
echo test-%s-alias > ../../../../alias/test-pct-chain

View File

@@ -1,4 +0,0 @@
#!/bin/sh
rm -f ../../../../alias/test-%s-alias
rm -f ../../../../alias/test-pct-chain

View File

@@ -2,7 +2,6 @@
export NVM_DIR="$(cd ../../.. && pwd)"
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -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

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
nvm which nonexistent_version

View File

@@ -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

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -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

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
nvm ls nonexistent_version

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
nvm ls io

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
nvm ls node_

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -2,7 +2,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -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}<"

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -2,7 +2,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -2,7 +2,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -2,7 +2,6 @@
export NVM_DIR="$(cd ../../.. && pwd)"
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh
@@ -37,13 +36,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}<"

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -2,7 +2,6 @@
die () { echo "$@" ; exit 1; }
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -1,6 +1,5 @@
#!/bin/sh
: nvm.sh
\. ../../../nvm.sh
\. ../../common.sh

View File

@@ -4,7 +4,6 @@ set -ex
export NVM_DIR="$(cd ../.. && pwd)"
: nvm.sh
\. ../../nvm.sh
nvm alias test v0.1.2

Some files were not shown because too many files have changed in this diff Show More