mirror of
https://github.com/nvm-sh/nvm.git
synced 2025-09-02 02:34:43 +00:00
Compare commits
20 Commits
0297a1d822
...
601e9b7625
Author | SHA1 | Date | |
---|---|---|---|
![]() |
601e9b7625 | ||
![]() |
9602f4f959 | ||
![]() |
c3d674f8f9 | ||
![]() |
0215ef8203 | ||
![]() |
f28584cecf | ||
![]() |
fc4a98b771 | ||
![]() |
dd28eb4932 | ||
![]() |
206a14297c | ||
![]() |
f99c9f30cd | ||
![]() |
c02964100e | ||
![]() |
e71918ec8c | ||
![]() |
594f8c0a80 | ||
![]() |
54a5777ff8 | ||
![]() |
858eda58c4 | ||
![]() |
f2b7583b6b | ||
![]() |
b16b4ee6ad | ||
![]() |
9f4dd6477a | ||
![]() |
c390144c1e | ||
![]() |
37811e0d7d | ||
![]() |
48fe276e36 |
427
.github/copilot-instructions.md
vendored
Normal file
427
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,427 @@
|
||||
# nvm Copilot Instructions
|
||||
|
||||
This document provides guidance for GitHub Copilot 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 current shell (sh, bash, dash, zsh, ksh)
|
||||
make test # Runs tests in all supported shells (sh, bash, dash, zsh, ksh)
|
||||
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 test-ksh # Runs tests only in ksh
|
||||
```
|
||||
|
||||
#### Run Specific Test Suites
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
### 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 GitHub Copilot understand the nvm codebase structure, testing procedures, and development environment setup requirements.
|
3
.github/workflows/windows-npm.yml
vendored
3
.github/workflows/windows-npm.yml
vendored
@@ -72,8 +72,11 @@ jobs:
|
||||
unset npm_config_prefix
|
||||
export NVM_INSTALL_GITHUB_REPO="$NVM_INSTALL_GITHUB_REPO"
|
||||
export NVM_INSTALL_VERSION="$NVM_INSTALL_VERSION"
|
||||
export HOME="$(cygpath -u "$USERPROFILE")"
|
||||
|
||||
echo "HOME is $HOME"
|
||||
curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash
|
||||
ls -l $HOME/.nvm
|
||||
. "$HOME/.nvm/nvm.sh"
|
||||
nvm install --lts
|
||||
|
||||
|
@@ -150,7 +150,7 @@ RUN touch "${BASH_ENV}"
|
||||
RUN echo '. "${BASH_ENV}"' >> ~/.bashrc
|
||||
|
||||
# Download and install nvm
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | PROFILE="${BASH_ENV}" bash
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | PROFILE="${BASH_ENV}" bash
|
||||
RUN echo node > .nvmrc
|
||||
RUN nvm install
|
||||
```
|
||||
|
120
nvm.sh
120
nvm.sh
@@ -1883,68 +1883,84 @@ nvm_print_versions() {
|
||||
fi
|
||||
|
||||
command awk \
|
||||
-v remote_versions="$(printf '%s' "${1-}" | tr '\n' '|')" \
|
||||
-v remote_versions="$(printf '%s' "${1-}" | tr '\n' '|')" -v min="${NVM_MIN:-v0}" \
|
||||
-v installed_versions="$(nvm_ls | tr '\n' '|')" -v current="$NVM_CURRENT" \
|
||||
-v installed_color="$INSTALLED_COLOR" -v system_color="$SYSTEM_COLOR" \
|
||||
-v current_color="$CURRENT_COLOR" -v default_color="$DEFAULT_COLOR" \
|
||||
-v old_lts_color="$DEFAULT_COLOR" -v has_colors="$NVM_HAS_COLORS" '
|
||||
function alen(arr, i, len) { len=0; for(i in arr) len++; return len; }
|
||||
BEGIN {
|
||||
fmt_installed = has_colors ? (installed_color ? "\033[" installed_color "%15s\033[0m" : "%15s") : "%15s *";
|
||||
fmt_system = has_colors ? (system_color ? "\033[" system_color "%15s\033[0m" : "%15s") : "%15s *";
|
||||
fmt_current = has_colors ? (current_color ? "\033[" current_color "->%13s\033[0m" : "%15s") : "->%13s *";
|
||||
function alen(arr, i, len) { len=0; for(i in arr) len++; return len; }
|
||||
function v2a(v, a) { sub(/^(iojs-)?v/, "", v); split(v, a, "."); }
|
||||
function v2m(v, a) { sub(/^(iojs-)?v/, "", v); split(v, a, "."); return a[1]; }
|
||||
function vcmp(v1,v2,a1,a2,i,d) { v2a(v1,a1); v2a(v2,a2); for(i=1;i<4;i++) { d = a1[i] - a2[i]; if(d!=0) return d; } return 0; }
|
||||
BEGIN {
|
||||
fmt_installed = has_colors ? (installed_color ? "\033[" installed_color "%15s\033[0m" : "%15s") : "%15s *";
|
||||
fmt_system = has_colors ? (system_color ? "\033[" system_color "%15s\033[0m" : "%15s") : "%15s *";
|
||||
fmt_current = has_colors ? (current_color ? "\033[" current_color "->%13s\033[0m" : "%15s") : "->%13s *";
|
||||
|
||||
latest_lts_color = current_color;
|
||||
sub(/0;/, "1;", latest_lts_color);
|
||||
latest_lts_color = current_color;
|
||||
sub(/0;/, "1;", latest_lts_color);
|
||||
|
||||
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_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)";
|
||||
|
||||
split(remote_versions, lines, "|");
|
||||
split(installed_versions, installed, "|");
|
||||
rows = alen(lines);
|
||||
|
||||
for (n = 1; n <= rows; n++) {
|
||||
split(lines[n], fields, "[[:blank:]]+");
|
||||
cols = alen(fields);
|
||||
version = fields[1];
|
||||
is_installed = 0;
|
||||
|
||||
for (i in installed) {
|
||||
if (version == installed[i]) {
|
||||
is_installed = 1;
|
||||
break;
|
||||
split(remote_versions, lines, "|");
|
||||
split(installed_versions, installed, "|");
|
||||
rows = alen(lines);
|
||||
filter_on = (vcmp("v0.0.0", min) != 0);
|
||||
current_major = -1;
|
||||
for (m = n = 1; n <= rows; n++) {
|
||||
split(lines[n], fields, "[[:blank:]]+");
|
||||
cols = alen(fields);
|
||||
version = fields[1];
|
||||
is_installed = 0;
|
||||
for (i in installed) {
|
||||
if (version == installed[i]) {
|
||||
is_installed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filter_on != 0) {
|
||||
if (is_installed) {
|
||||
current_major = v2m(version);
|
||||
} else if (vcmp(version, min) >= 0) {
|
||||
filter_on = 0;
|
||||
} else if (v2m(version) != current_major) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fmt_version = "%15s";
|
||||
if (version == current) {
|
||||
fmt_version = fmt_current;
|
||||
} else if (version == "system") {
|
||||
fmt_version = fmt_system;
|
||||
} else if (is_installed) {
|
||||
fmt_version = fmt_installed;
|
||||
}
|
||||
|
||||
padding = (is_installed && !has_colors) ? "" : " ";
|
||||
if (cols == 1) {
|
||||
formatted = sprintf(fmt_version, version);
|
||||
} else if (cols == 2) {
|
||||
formatted = sprintf((fmt_version padding fmt_old_lts), version, fields[2]);
|
||||
} else if (cols == 3 && fields[3] == "*") {
|
||||
formatted = sprintf((fmt_version padding fmt_latest_lts), version, fields[2]);
|
||||
}
|
||||
|
||||
output[m++] = formatted;
|
||||
}
|
||||
|
||||
fmt_version = "%15s";
|
||||
if (version == current) {
|
||||
fmt_version = fmt_current;
|
||||
} else if (version == "system") {
|
||||
fmt_version = fmt_system;
|
||||
} else if (is_installed) {
|
||||
fmt_version = fmt_installed;
|
||||
for (n = 1; n < m; n++) {
|
||||
print output[n]
|
||||
}
|
||||
|
||||
padding = (!has_colors && is_installed) ? "" : " ";
|
||||
|
||||
if (cols == 1) {
|
||||
formatted = sprintf(fmt_version, version);
|
||||
} else if (cols == 2) {
|
||||
formatted = sprintf((fmt_version padding fmt_old_lts), version, fields[2]);
|
||||
} else if (cols == 3 && fields[3] == "*") {
|
||||
formatted = sprintf((fmt_version padding fmt_latest_lts), version, fields[2]);
|
||||
if (rows > --m) {
|
||||
printf("[INFO] showing %d (of %d) versions.\n", m, rows) > "/dev/stderr"
|
||||
}
|
||||
|
||||
output[n] = formatted;
|
||||
}
|
||||
|
||||
for (n = 1; n <= rows; n++) {
|
||||
print output[n]
|
||||
}
|
||||
|
||||
exit
|
||||
}'
|
||||
exit
|
||||
}'
|
||||
}
|
||||
|
||||
nvm_validate_implicit_alias() {
|
||||
@@ -3106,6 +3122,7 @@ nvm() {
|
||||
nvm_echo ' nvm ls-remote [<version>] List remote versions available for install, matching a given <version> if provided'
|
||||
nvm_echo ' --lts When listing, only show LTS (long-term support) versions'
|
||||
nvm_echo ' --lts=<LTS name> When listing, only show versions for a specific LTS line'
|
||||
nvm_echo ' --min=<version> When listing, only show versions greater than or equal to <version>, including minor/patch updates for installed versions'
|
||||
nvm_echo ' --no-colors Suppress colored output'
|
||||
nvm_echo ' nvm version <version> Resolve the given description to a single local version'
|
||||
nvm_echo ' nvm version-remote <version> Resolve the given description to a single remote version'
|
||||
@@ -4124,6 +4141,10 @@ nvm() {
|
||||
local NVM_LTS
|
||||
local PATTERN
|
||||
local NVM_NO_COLORS
|
||||
local NVM_MIN_ENV
|
||||
NVM_MIN_ENV="${NVM_MIN-}"
|
||||
local NVM_MIN
|
||||
NVM_MIN="${NVM_MIN_ENV-}"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "${1-}" in
|
||||
@@ -4134,6 +4155,9 @@ nvm() {
|
||||
--lts=*)
|
||||
NVM_LTS="${1##--lts=}"
|
||||
;;
|
||||
--min=*)
|
||||
NVM_MIN="${1##--min=}"
|
||||
;;
|
||||
--no-colors) NVM_NO_COLORS="${1}" ;;
|
||||
--*)
|
||||
nvm_err "Unsupported option \"${1}\"."
|
||||
|
146
test/fast/Unit tests/nvm_print_versions
Executable file
146
test/fast/Unit tests/nvm_print_versions
Executable file
@@ -0,0 +1,146 @@
|
||||
#!/bin/sh
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
unset -f nvm_remote_versions nvm_ls nvm_ls_current
|
||||
if [ -n "$TEMP_NVM_MIN" ]; then
|
||||
export NVM_MIN="$TEMP_NVM_MIN"
|
||||
unset TEMP_NVM_MIN
|
||||
fi
|
||||
}
|
||||
|
||||
\. ../../../nvm.sh
|
||||
|
||||
|
||||
if [ -n "$NVM_MIN" ]; then
|
||||
TEMP_NVM_MIN="$NVM_MIN"
|
||||
unset NVM_MIN
|
||||
fi
|
||||
|
||||
# mock currently installed versions
|
||||
nvm_ls() {
|
||||
echo "v16.20.2
|
||||
v18.20.3
|
||||
system"
|
||||
}
|
||||
|
||||
# mock currently active version
|
||||
nvm_ls_current() {
|
||||
echo "v18.20.3"
|
||||
}
|
||||
|
||||
nvm_remote_versions() {
|
||||
echo "v16.0.0
|
||||
v16.20.2 Gallium
|
||||
v16.20.3 Gallium *
|
||||
v17.0.0
|
||||
v17.9.1
|
||||
v18.0.0
|
||||
v18.1.0
|
||||
v18.20.2 Hydrogen
|
||||
v18.20.3 Hydrogen *
|
||||
v19.0.0
|
||||
v19.9.0
|
||||
v20.0.0
|
||||
v20.8.1
|
||||
v20.9.0 Iron *
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
}
|
||||
|
||||
|
||||
# nvm_print_versions should print all versions from nvm_remote_versions
|
||||
OUTPUT="$(NVM_NO_COLORS='--no-colors' nvm_print_versions "$(nvm_remote_versions)" | sed -r 's/^[ \t]+//')"
|
||||
EXPECTED_OUTPUT="v16.0.0
|
||||
v16.20.2 * (LTS: Gallium)
|
||||
v16.20.3 (Latest LTS: Gallium)
|
||||
v17.0.0
|
||||
v17.9.1
|
||||
v18.0.0
|
||||
v18.1.0
|
||||
v18.20.2 (LTS: Hydrogen)
|
||||
-> v18.20.3 * (Latest LTS: Hydrogen)
|
||||
v19.0.0
|
||||
v19.9.0
|
||||
v20.0.0
|
||||
v20.8.1
|
||||
v20.9.0 (Latest LTS: Iron)
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
|
||||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "(1) nvm_print_versions did not output all expected versions; got $OUTPUT"
|
||||
|
||||
|
||||
# versions lower than 18 should be filtered out, but v16.20.2 should be kept since it's installed
|
||||
OUTPUT="$(NVM_NO_COLORS='--no-colors' NVM_MIN=v18 nvm_print_versions "$(nvm_remote_versions)" | sed -r 's/^[ \t]+//')"
|
||||
EXPECTED_OUTPUT="v16.20.2 * (LTS: Gallium)
|
||||
v16.20.3 (Latest LTS: Gallium)
|
||||
v18.0.0
|
||||
v18.1.0
|
||||
v18.20.2 (LTS: Hydrogen)
|
||||
-> v18.20.3 * (Latest LTS: Hydrogen)
|
||||
v19.0.0
|
||||
v19.9.0
|
||||
v20.0.0
|
||||
v20.8.1
|
||||
v20.9.0 (Latest LTS: Iron)
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
|
||||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "(2) NVM_MIN=18 nvm_print_versions did not output all expected versions; got $OUTPUT"
|
||||
|
||||
|
||||
# versions lower than 19 should be filtered out
|
||||
OUTPUT="$(NVM_NO_COLORS='--no-colors' NVM_MIN=19 nvm_print_versions "$(nvm_remote_versions)" | sed -r 's/^[ \t]+//')"
|
||||
EXPECTED_OUTPUT="v16.20.2 * (LTS: Gallium)
|
||||
v16.20.3 (Latest LTS: Gallium)
|
||||
-> v18.20.3 * (Latest LTS: Hydrogen)
|
||||
v19.0.0
|
||||
v19.9.0
|
||||
v20.0.0
|
||||
v20.8.1
|
||||
v20.9.0 (Latest LTS: Iron)
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
|
||||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "(3) NVM_MIN=19 nvm_print_versions did not output all expected versions; got $OUTPUT"
|
||||
|
||||
|
||||
# versions lower than 20.1 should be filtered out, so v20.0.0 is out
|
||||
OUTPUT="$(NVM_NO_COLORS='--no-colors' NVM_MIN=v20.1 nvm_print_versions "$(nvm_remote_versions)" | sed -r 's/^[ \t]+//')"
|
||||
EXPECTED_OUTPUT="v16.20.2 * (LTS: Gallium)
|
||||
v16.20.3 (Latest LTS: Gallium)
|
||||
-> v18.20.3 * (Latest LTS: Hydrogen)
|
||||
v20.8.1
|
||||
v20.9.0 (Latest LTS: Iron)
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
|
||||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "(4) NVM_MIN=20.1 nvm_print_versions did not output all expected versions; got $OUTPUT"
|
||||
|
||||
|
||||
# assume v18.20.3 is NOT installed, so now it should be filtered out
|
||||
nvm_ls() {
|
||||
echo "v16.20.2
|
||||
system"
|
||||
}
|
||||
|
||||
nvm_ls_current() {
|
||||
echo "v16.20.2"
|
||||
}
|
||||
|
||||
OUTPUT="$(NVM_NO_COLORS='--no-colors' NVM_MIN=20.1 nvm_print_versions "$(nvm_remote_versions)" | sed -r 's/^[ \t]+//')"
|
||||
EXPECTED_OUTPUT="-> v16.20.2 * (LTS: Gallium)
|
||||
v16.20.3 (Latest LTS: Gallium)
|
||||
v20.8.1
|
||||
v20.9.0 (Latest LTS: Iron)
|
||||
v21.0.0
|
||||
v21.1.0"
|
||||
|
||||
[ "_$OUTPUT" = "_$EXPECTED_OUTPUT" ] || die "(5) NVM_MIN=20.1 nvm_print_versions did not output all expected versions; got $OUTPUT"
|
||||
|
||||
|
||||
cleanup
|
Reference in New Issue
Block a user