Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/shiny-ducks-reinstall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"fnm": minor
---

Added `--reinstall-packages-from` flag to `fnm install`. When specified, global npm packages from the given Node version are automatically reinstalled on the newly installed version. Analogous to nvm's `--reinstall-packages-from` flag.

Package discovery now uses filesystem scanning on non-Windows platforms and `npm ls --global --depth=0 --json` on Windows; symlinked global package entries are skipped to avoid reinstalling locally linked packages.
16 changes: 16 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -126,6 +127,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -188,6 +190,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -269,6 +272,10 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--reinstall-packages-from <version>
Reinstall global packages from a specified Node version after installing. Analogous to nvm's --reinstall-packages-from flag

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -341,6 +348,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -418,6 +426,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -485,6 +494,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -554,6 +564,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -620,6 +631,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -688,6 +700,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -750,6 +763,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -824,6 +838,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down Expand Up @@ -892,6 +907,7 @@ Options:
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

[env: FNM_ARCH]
[possible values: x86, x64, x64-musl, x64-glibc217, arm64, armv7l, ppc64le, ppc64, s390x]

--version-file-strategy <VERSION_FILE_STRATEGY>
A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation
Expand Down
165 changes: 165 additions & 0 deletions e2e/__snapshots__/reinstall-packages-from.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Bash errors when source version is not installed: Bash 1`] = `
"set -e
eval "$(fnm env --log-level=error)"
(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1) | grep 'Version v18.20.0 is not installed' || (echo "Expected output to contain 'Version v18.20.0 is not installed'" && exit 1)"
`;

exports[`Bash reinstall packages from another version: Bash 1`] = `
"set -e
eval "$(fnm env)"
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
fnm use v18.20.0
npm install -g is-odd
(npm list -g --depth=0) | grep 'is-odd' || (echo "Expected output to contain 'is-odd'" && exit 1)
__out__="$(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1)"
echo "$__out__" | grep 'is-odd@' || (echo "Expected output to contain 'is-odd@'" && exit 1)
if echo "$__out__" | grep -q ' - npm@'; then
echo "Expected output to not contain 'npm@'"
exit 1
fi
if echo "$__out__" | grep -q ' - corepack@'; then
echo "Expected output to not contain 'corepack@'"
exit 1
fi
echo "$__out__" | grep 'Successfully reinstalled' || (echo "Expected output to contain 'Successfully reinstalled'" && exit 1)

fnm use v20.11.0
(npm list -g --depth=0) | grep 'is-odd' || (echo "Expected output to contain 'is-odd'" && exit 1)"
`;

exports[`Bash skips reinstall when source and target are the same version: Bash 1`] = `
"set -e
eval "$(fnm env)"
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
(fnm install v18.20.0 --reinstall-packages-from=v18.20.0) | grep 'Skipping package reinstallation' || (echo "Expected output to contain 'Skipping package reinstallation'" && exit 1)"
`;

exports[`Bash source has no global packages: Bash 1`] = `
"set -e
eval "$(fnm env)"
fnm install v18.20.0
(fnm install v20.11.0 --reinstall-packages-from=v18.20.0) | grep 'No global packages found in' || (echo "Expected output to contain 'No global packages found in'" && exit 1)"
`;

exports[`Fish errors when source version is not installed: Fish 1`] = `
"fnm env --log-level=error | source
begin; fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1; end | grep 'Version v18.20.0 is not installed'; or echo "Expected output to contain 'Version v18.20.0 is not installed'" && exit 1"
`;

exports[`Fish reinstall packages from another version: Fish 1`] = `
"fnm env | source
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
fnm use v18.20.0
npm install -g is-odd
begin; npm list -g --depth=0; end | grep 'is-odd'; or echo "Expected output to contain 'is-odd'" && exit 1
set __out__ (fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1)
echo $__out__ | grep 'is-odd@'; or begin; echo "Expected output to contain 'is-odd@'"; exit 1; end
echo $__out__ | grep ' - npm@'; and begin; echo "Expected output to not contain 'npm@'"; exit 1; end
echo $__out__ | grep ' - corepack@'; and begin; echo "Expected output to not contain 'corepack@'"; exit 1; end
echo $__out__ | grep 'Successfully reinstalled'; or begin; echo "Expected output to contain 'Successfully reinstalled'"; exit 1; end

fnm use v20.11.0
begin; npm list -g --depth=0; end | grep 'is-odd'; or echo "Expected output to contain 'is-odd'" && exit 1"
`;

exports[`Fish skips reinstall when source and target are the same version: Fish 1`] = `
"fnm env | source
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
begin; fnm install v18.20.0 --reinstall-packages-from=v18.20.0; end | grep 'Skipping package reinstallation'; or echo "Expected output to contain 'Skipping package reinstallation'" && exit 1"
`;

exports[`Fish source has no global packages: Fish 1`] = `
"fnm env | source
fnm install v18.20.0
begin; fnm install v20.11.0 --reinstall-packages-from=v18.20.0; end | grep 'No global packages found in'; or echo "Expected output to contain 'No global packages found in'" && exit 1"
`;

exports[`PowerShell errors when source version is not installed: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env --log-level=error | Out-String | Invoke-Expression
$($__out__ = $(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1 | Select-String 'Version v18.20.0 is not installed'); if ($__out__ -eq $null) { exit 1 } else { $__out__ })"
`;

exports[`PowerShell reinstall packages from another version: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env | Out-String | Invoke-Expression
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
fnm use v18.20.0
npm install -g is-odd
$($__out__ = $(npm list -g --depth=0 | Select-String 'is-odd'); if ($__out__ -eq $null) { exit 1 } else { $__out__ })
$__out__ = fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1 | Out-String
if ($__out__ -notmatch "is-odd@") { exit 1 }
if ($__out__ -match " - npm@") { exit 1 }
if ($__out__ -match " - corepack@") { exit 1 }
if ($__out__ -notmatch "Successfully reinstalled") { exit 1 }

fnm use v20.11.0
$($__out__ = $(npm list -g --depth=0 | Select-String 'is-odd'); if ($__out__ -eq $null) { exit 1 } else { $__out__ })"
`;

exports[`PowerShell skips reinstall when source and target are the same version: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env | Out-String | Invoke-Expression
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
$($__out__ = $(fnm install v18.20.0 --reinstall-packages-from=v18.20.0 | Select-String 'Skipping package reinstallation'); if ($__out__ -eq $null) { exit 1 } else { $__out__ })"
`;

exports[`PowerShell source has no global packages: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env | Out-String | Invoke-Expression
fnm install v18.20.0
$($__out__ = $(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 | Select-String 'No global packages found in'); if ($__out__ -eq $null) { exit 1 } else { $__out__ })"
`;

exports[`Zsh errors when source version is not installed: Zsh 1`] = `
"set -e
eval "$(fnm env --log-level=error)"
(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1) | grep 'Version v18.20.0 is not installed' || (echo "Expected output to contain 'Version v18.20.0 is not installed'" && exit 1)"
`;

exports[`Zsh reinstall packages from another version: Zsh 1`] = `
"set -e
eval "$(fnm env)"
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
fnm use v18.20.0
npm install -g is-odd
(npm list -g --depth=0) | grep 'is-odd' || (echo "Expected output to contain 'is-odd'" && exit 1)
__out__="$(fnm install v20.11.0 --reinstall-packages-from=v18.20.0 2>&1)"
echo "$__out__" | grep 'is-odd@' || (echo "Expected output to contain 'is-odd@'" && exit 1)
if echo "$__out__" | grep -q ' - npm@'; then
echo "Expected output to not contain 'npm@'"
exit 1
fi
if echo "$__out__" | grep -q ' - corepack@'; then
echo "Expected output to not contain 'corepack@'"
exit 1
fi
echo "$__out__" | grep 'Successfully reinstalled' || (echo "Expected output to contain 'Successfully reinstalled'" && exit 1)

fnm use v20.11.0
(npm list -g --depth=0) | grep 'is-odd' || (echo "Expected output to contain 'is-odd'" && exit 1)"
`;

exports[`Zsh skips reinstall when source and target are the same version: Zsh 1`] = `
"set -e
eval "$(fnm env)"
npm config set prefix ./npm-global --location=user
fnm install v18.20.0
(fnm install v18.20.0 --reinstall-packages-from=v18.20.0) | grep 'Skipping package reinstallation' || (echo "Expected output to contain 'Skipping package reinstallation'" && exit 1)"
`;

exports[`Zsh source has no global packages: Zsh 1`] = `
"set -e
eval "$(fnm env)"
fnm install v18.20.0
(fnm install v20.11.0 --reinstall-packages-from=v18.20.0) | grep 'No global packages found in' || (echo "Expected output to contain 'No global packages found in'" && exit 1)"
`;
Loading
Loading