Skip to content

Commit 2063c20

Browse files
Copilotljharb
andcommitted
Add comprehensive .github/copilot-instructions.md
Co-authored-by: ljharb <[email protected]>
1 parent 8f9112e commit 2063c20

File tree

1 file changed

+334
-0
lines changed

1 file changed

+334
-0
lines changed

.github/copilot-instructions.md

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
# nvm Copilot Instructions
2+
3+
This document provides guidance for GitHub Copilot when working with the Node Version Manager (nvm) codebase.
4+
5+
## Overview
6+
7+
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.
8+
9+
### Core Architecture
10+
11+
- **Main script**: `nvm.sh` - Contains all core functionality and the main `nvm()` function
12+
- **Installation script**: `install.sh` - Handles downloading and installing nvm itself
13+
- **Execution wrapper**: `nvm-exec` - Allows running commands with specific Node.js versions
14+
- **Bash completion**: `bash_completion` - Provides tab completion for bash users
15+
- **Tests**: Comprehensive test suite in `test/` directory using the urchin test framework
16+
17+
## Key Files and Their Purposes
18+
19+
### `nvm.sh`
20+
The core functionality file containing:
21+
- Main `nvm()` function (starts around line 3000)
22+
- All internal helper functions (prefixed with `nvm_`)
23+
- Command implementations for install, use, ls, etc.
24+
- Shell compatibility logic
25+
- POSIX compliance utilities
26+
27+
### `install.sh`
28+
Handles nvm installation via curl/wget:
29+
- Downloads nvm from GitHub
30+
- Sets up directory structure
31+
- Configures shell integration
32+
- Supports both git clone and script download methods
33+
34+
### `nvm-exec`
35+
Simple wrapper script that:
36+
- Sources nvm.sh with `--no-use` flag
37+
- Switches to specified Node version via `NODE_VERSION` env var or `.nvmrc`
38+
- Executes the provided command with that Node version
39+
40+
## Top-Level nvm Commands and Internal Functions
41+
42+
### Core Commands
43+
44+
#### `nvm install [version]`
45+
- **Internal functions**: `nvm_install_binary()`, `nvm_install_source()`, `nvm_download_artifact()`
46+
- Downloads and installs specified Node.js version
47+
- Supports LTS versions, version ranges, and aliases
48+
- Can install from binary or compile from source
49+
50+
#### `nvm use [version]`
51+
- **Internal functions**: `nvm_resolve_alias()`, `nvm_version_path()`, `nvm_change_path()`
52+
- Switches current shell to use specified Node.js version
53+
- Updates PATH environment variable
54+
- Supports `.nvmrc` file integration
55+
56+
#### `nvm ls [pattern]`
57+
- **Internal functions**: `nvm_ls()`, `nvm_tree_contains_path()`
58+
- Lists installed Node.js versions
59+
- Supports pattern matching and filtering
60+
- Shows current version and aliases
61+
62+
#### `nvm ls-remote [pattern]`
63+
- **Internal functions**: `nvm_ls_remote()`, `nvm_download()`, `nvm_ls_remote_index_tab()`
64+
- Lists available Node.js versions from nodejs.org
65+
- Supports LTS filtering and pattern matching
66+
- Downloads version index on-demand
67+
68+
#### `nvm alias [name] [version]`
69+
- **Internal functions**: `nvm_alias()`, `nvm_alias_path()`
70+
- Creates symbolic links for version aliases
71+
- Special aliases: `default`, `node`, `stable`, `unstable`
72+
- Stored in `$NVM_DIR/alias/` directory
73+
74+
#### `nvm current`
75+
- **Internal functions**: `nvm_ls_current()`
76+
- Shows currently active Node.js version
77+
- Returns "system" if using system Node.js
78+
79+
#### `nvm which [version]`
80+
- **Internal functions**: `nvm_version_path()`, `nvm_resolve_alias()`
81+
- Shows path to specified Node.js version
82+
- Resolves aliases and version strings
83+
84+
### Utility Commands
85+
86+
#### `nvm cache clear|dir`
87+
- Cache management for downloaded binaries
88+
- Clears or shows cache directory path
89+
90+
#### `nvm debug`
91+
- Diagnostic information for troubleshooting
92+
- Shows environment, tool versions, and paths
93+
94+
#### `nvm deactivate`
95+
- Removes nvm modifications from current shell
96+
- Restores original PATH
97+
98+
#### `nvm unload`
99+
- Completely removes nvm from shell environment
100+
- Unsets all nvm functions and variables
101+
102+
### Internal Function Categories
103+
104+
#### Version Resolution
105+
- `nvm_resolve_alias()` - Resolves aliases to version numbers
106+
- `nvm_version()` - Finds best matching local version
107+
- `nvm_remote_version()` - Finds best matching remote version
108+
- `nvm_normalize_version()` - Standardizes version strings
109+
110+
#### Installation Helpers
111+
- `nvm_install_binary()` - Downloads and installs precompiled binaries
112+
- `nvm_install_source()` - Compiles Node.js from source
113+
- `nvm_download_artifact()` - Downloads tarballs or binaries
114+
- `nvm_compute_checksum()` - Verifies download integrity
115+
116+
#### Path Management
117+
- `nvm_change_path()` - Updates PATH for version switching
118+
- `nvm_strip_path()` - Removes nvm paths from PATH
119+
- `nvm_version_path()` - Gets installation path for version
120+
121+
#### Utility Functions
122+
- `nvm_echo()`, `nvm_err()` - Output functions
123+
- `nvm_has()` - Checks if command exists
124+
- `nvm_is_zsh()` - Shell detection
125+
- `nvm_sanitize_path()` - Cleans sensitive data from paths
126+
127+
## Running Tests
128+
129+
### Test Framework
130+
nvm uses the **urchin** test framework for shell script testing.
131+
132+
### Test Structure
133+
```
134+
test/
135+
├── fast/ # Quick unit tests
136+
├── slow/ # Integration tests
137+
├── sourcing/ # Shell sourcing tests
138+
├── install_script/ # Installation script tests
139+
├── installation_node/ # Node installation tests
140+
└── common.sh # Shared test utilities
141+
```
142+
143+
### Running Tests
144+
145+
#### Install Dependencies
146+
```bash
147+
npm install # Installs urchin, semver, and replace tools
148+
```
149+
150+
#### Run All Tests
151+
```bash
152+
npm test # Runs tests in current shell
153+
make test # Runs tests in all supported shells
154+
make test-bash # Runs tests only in bash
155+
make test-zsh # Runs tests only in zsh
156+
```
157+
158+
#### Run Specific Test Suites
159+
```bash
160+
make TEST_SUITE=fast test # Only fast tests
161+
make TEST_SUITE=slow test # Only slow tests
162+
make SHELLS=bash test # Only bash shell
163+
```
164+
165+
#### Individual Test Execution
166+
```bash
167+
./test/fast/Unit\ tests/nvm_get_arch # Run single test
168+
urchin test/fast/ # Run fast test suite
169+
```
170+
171+
### Test Writing Guidelines
172+
- Tests should work across all supported shells (sh, bash, dash, zsh)
173+
- Use `die()` function for test failures
174+
- Clean up after tests in cleanup functions
175+
- Mock external dependencies when needed
176+
- Place mocks in `test/mocks/` directory
177+
178+
## Shell Environment Setup
179+
180+
### Supported Shells
181+
- **bash** - Full feature support
182+
- **zsh** - Full feature support
183+
- **dash** - Basic POSIX support
184+
- **sh** - Basic POSIX support
185+
- **ksh** - Limited support (experimental)
186+
187+
### Installing Shell Environments
188+
189+
#### Ubuntu/Debian
190+
```bash
191+
sudo apt-get update
192+
sudo apt-get install bash zsh dash ksh
193+
```
194+
195+
#### macOS
196+
```bash
197+
# zsh is default, install others via Homebrew
198+
brew install bash dash ksh
199+
```
200+
201+
#### Manual Shell Testing
202+
```bash
203+
# Test in specific shell
204+
bash -c "source nvm.sh && nvm --version"
205+
zsh -c "source nvm.sh && nvm --version"
206+
dash -c ". nvm.sh && nvm --version"
207+
```
208+
209+
### Shell-Specific Considerations
210+
- **zsh**: Requires `setopt local_options shwordsplit` for word splitting
211+
- **dash**: Limited feature set, avoid bash-specific syntax
212+
- **ksh**: Some features may not work, primarily for compatibility testing
213+
214+
## CI Environment Details
215+
216+
### GitHub Actions Workflows
217+
218+
#### `.github/workflows/tests.yml`
219+
- Runs test suite across multiple shells and test suites
220+
- Uses `script` command for proper TTY simulation
221+
- Matrix strategy covers shell × test suite combinations
222+
- Excludes install_script tests from non-bash shells
223+
224+
#### `.github/workflows/shellcheck.yml`
225+
- Lints all shell scripts using shellcheck
226+
- Tests against multiple shell targets (bash, sh, dash, ksh)
227+
- Uses Homebrew to install latest shellcheck version
228+
229+
#### `.github/workflows/lint.yml`
230+
- Runs additional linting and formatting checks
231+
- Validates documentation and code style
232+
233+
### Travis CI (Legacy)
234+
- Configured in `.travis.yml`
235+
- Tests on multiple Ubuntu versions
236+
- Installs shell environments via apt packages
237+
238+
### CI Test Execution
239+
```bash
240+
# Simulate CI environment locally
241+
export TRAVIS_BUILD_DIR="" # Disable Travis-specific logic
242+
export GITHUB_ACTIONS="" # Disable GitHub Actions logic
243+
make test
244+
```
245+
246+
## Setting Up shellcheck Locally
247+
248+
### Installation
249+
250+
#### macOS (Homebrew)
251+
```bash
252+
brew install shellcheck
253+
```
254+
255+
#### Ubuntu/Debian
256+
```bash
257+
sudo apt-get install shellcheck
258+
```
259+
260+
#### From Source
261+
```bash
262+
# Download from https://github.com/koalaman/shellcheck/releases
263+
wget https://github.com/koalaman/shellcheck/releases/download/latest/shellcheck-latest.linux.x86_64.tar.xz
264+
tar -xf shellcheck-latest.linux.x86_64.tar.xz
265+
sudo cp shellcheck-latest/shellcheck /usr/local/bin/
266+
```
267+
268+
### Usage
269+
270+
#### Lint Main Files
271+
```bash
272+
shellcheck -s bash nvm.sh
273+
shellcheck -s bash install.sh
274+
shellcheck -s bash nvm-exec
275+
shellcheck -s bash bash_completion
276+
```
277+
278+
#### Lint Across Shell Types
279+
```bash
280+
shellcheck -s sh nvm.sh # POSIX sh
281+
shellcheck -s bash nvm.sh # Bash extensions
282+
shellcheck -s dash nvm.sh # Dash compatibility
283+
shellcheck -s ksh nvm.sh # Ksh compatibility
284+
```
285+
286+
#### Common shellcheck Directives in nvm
287+
- `# shellcheck disable=SC2039` - Allow bash extensions in POSIX mode
288+
- `# shellcheck disable=SC2016` - Allow literal `$` in single quotes
289+
- `# shellcheck disable=SC2001` - Allow sed usage instead of parameter expansion
290+
- `# shellcheck disable=SC3043` - Allow `local` keyword (bash extension)
291+
292+
### Fixing shellcheck Issues
293+
1. **Quoting**: Always quote variables: `"${VAR}"` instead of `$VAR`
294+
2. **POSIX compliance**: Avoid bash-specific features in portable sections
295+
3. **Array usage**: Use `set --` for positional parameters instead of arrays
296+
4. **Local variables**: Mark as bash-specific or avoid in POSIX functions
297+
298+
## Development Best Practices
299+
300+
### Code Style
301+
- Use 2-space indentation
302+
- Follow POSIX shell guidelines for portability
303+
- Prefix internal functions with `nvm_`
304+
- Use `nvm_echo` instead of `echo` for output
305+
- Use `nvm_err` for error messages
306+
307+
### Compatibility
308+
- Test changes across all supported shells
309+
- Avoid bash-specific features in core functionality
310+
- Use `nvm_is_zsh` checks when zsh-specific behavior needed
311+
- Mock external dependencies in tests
312+
313+
### Performance
314+
- Cache expensive operations (like remote version lists)
315+
- Use local variables to avoid scope pollution
316+
- Minimize subprocess calls where possible
317+
- Implement lazy loading for optional features
318+
319+
### Debugging
320+
- Use `nvm debug` command for environment information
321+
- Enable verbose output with `set -x` during development
322+
- Test with `NVM_DEBUG=1` environment variable
323+
- Check `$NVM_DIR/.cache` for cached data issues
324+
325+
## Common Gotchas
326+
327+
1. **PATH modification**: nvm modifies PATH extensively; be careful with restoration
328+
2. **Shell sourcing**: nvm must be sourced, not executed as a script
329+
3. **Version resolution**: Aliases, partial versions, and special keywords interact complexly
330+
4. **Platform differences**: Handle differences between Linux, macOS, and other Unix systems
331+
5. **Network dependencies**: Many operations require internet access for version lists
332+
6. **Concurrent access**: Multiple shells can conflict when installing versions simultaneously
333+
334+
This guide should help GitHub Copilot understand the nvm codebase structure, testing procedures, and development environment setup requirements.

0 commit comments

Comments
 (0)