feat: add --reinstall-packages-from flag to fnm install#1505
feat: add --reinstall-packages-from flag to fnm install#1505amanthanvi wants to merge 13 commits into
Conversation
Copies global npm packages from a specified installed Node version to a newly installed version. Resolves the source version's global packages via `npm ls`, filters out builtins (npm, corepack), and installs them on the target version. Closes Schniz#620 Refs Schniz#703, Schniz#481
🦋 Changeset detectedLatest commit: f3c174f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@amanthanvi is attempting to deploy a commit to the Gal Schlezinger's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
This PR adds the highly requested --reinstall-packages-from flag to the fnm install command, bringing feature parity with nvm. This addresses a major pain point where users lose their global CLI tools (eslint, prettier, typescript, etc.) when installing new Node versions.
Changes:
- Added
--reinstall-packages-fromflag tofnm installthat copies global npm packages from a source Node version to the newly installed target version - Implemented package listing using
npm ls --global --parseable --longwith proper filtering of built-in packages (npm, corepack) - Added comprehensive e2e tests covering success, error, and edge cases
- Updated documentation and added changeset
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/commands/install.rs | Core implementation including package listing, reinstallation logic, parser for npm output, cross-platform path handling, error types, and unit tests |
| e2e/reinstall-packages-from.test.ts | E2e tests for Bash and PowerShell covering package reinstallation, error handling when source not installed, and graceful handling of empty package lists |
| e2e/snapshots/reinstall-packages-from.test.ts.snap | Jest snapshots for the e2e tests |
| docs/commands.md | Documentation for the new --reinstall-packages-from flag |
| .changeset/shiny-ducks-reinstall.md | Changeset documenting this minor version feature addition |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
CI note (fork PR):\n- Rust workflow is currently "action_required" (needs maintainer approval to run).\n- Vercel status fails with "Authorization required to deploy" for forks.\n- Copilot code review run failed during artifact cleanup due to fork permissions.\nLocal checks passed: cargo build/test/clippy/fmt + pnpm test -- e2e/reinstall-packages-from.test.ts. |
… the same Avoids a wasteful no-op reinstall cycle when a user passes the same version to --reinstall-packages-from as the version being installed. Adds an e2e test proving the guard works.
The npm path and PATH env setup was duplicated between list_global_packages and reinstall_packages.
Also adds a clarifying comment on the scoped package '@' filter logic.
Extracts the multi-assertion output verification into a helper function with shell-specific implementations for Bash/Zsh, Fish, and PowerShell.
Follow up on --reinstall-packages-from by listing global packages from the installed Node directory instead of calling npm ls. This avoids npm output and exit-code quirks while preserving behavior for scoped packages and npm/corepack filtering.
Ignore symlinked entries when scanning global packages for --reinstall-packages-from and log a warning for skipped items. This avoids trying to reinstall locally linked packages that may not exist in registries.
Windows global npm packages may live under %APPDATA%\npm\node_modules. Scan that location in addition to the Node installation path so --reinstall-packages-from consistently finds and reinstalls globals in Windows CI.
Add a Windows-specific discovery path for --reinstall-packages-from using npm ls --global --depth=0 --json, with an inline rationale that npm prefix location is not reliably derivable from fnm install paths. Keep filesystem scanning for non-Windows platforms.
Keep a single changeset for this PR by folding follow-up filesystem discovery, symlink handling, and Windows package discovery notes into the original reinstall-packages-from entry.
Summary
Adds
--reinstall-packages-from=<version>flag tofnm install. When specified,global npm packages from the source Node version are copied to the newly installed
version. This is the nvm-equivalent feature that has been the most requested
migration aid since 2022.
Motivation
a new version, they lose all their CLI tools (eslint, prettier, typescript, etc.)
until manually reinstalled. This is the Unzip and untar #1 friction point for nvm-to-fnm migration.
--reinstall-packages-fromfor years; this brings parity.--reinstall-packages-from=argument for fnm install #510, addressing all maintainer feedback:cross-platform Windows support, comprehensive e2e tests, and proper error handling.
Implementation
Package listing (source version)
npm ls --global --parseable --long --loglevel=errorin the source version'scontext using
std::process::Commandwith PATH set to the source version's bin dirname@versionpairsnpmandcorepack(ship with Node, should not be reinstalled)Package installation (target version)
npm install --global <packages>viaExec::new_for_version()on the newlyinstalled target version
Error handling
ReinstallPackagesErrorwith contextCross-platform
bin/npmpathsnpm.cmdpaths,;PATH separatorcfg!(windows)guards matching the existingenable_corepack()patternUsage
Testing
--reinstall-packages-from=A, verify package present on BChecklist
cargo testpassescargo clippy --all-targetscleancargo fmt --checkclean--reinstall-packages-from=argument for fnm install #510 review