Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions .changeset/shiny-ducks-reinstall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"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.
6 changes: 6 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,12 @@ Options:
--use
Use the installed version immediately after installation

--reinstall-packages-from <version>
After installing, reinstall global npm packages from the specified
Node version. Packages are installed with their current versions.
The source version must already be installed.
Analogous to nvm's --reinstall-packages-from flag.

--arch <ARCH>
Override the architecture of the installed Node binary. Defaults to arch of fnm binary

Expand Down
67 changes: 67 additions & 0 deletions e2e/__snapshots__/reinstall-packages-from.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// 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)"
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 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[`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
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 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__ })"
`;
94 changes: 94 additions & 0 deletions e2e/reinstall-packages-from.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import getStderr from "./shellcode/get-stderr.js"
import { script } from "./shellcode/script.js"
import { Bash, PowerShell } from "./shellcode/shells.js"
import describe from "./describe.js"

const SOURCE_VERSION = "v18.20.0"
const TARGET_VERSION = "v20.11.0"

for (const shell of [Bash, PowerShell]) {
Comment thread
Schniz marked this conversation as resolved.
Outdated
describe(shell, () => {
test(`reinstall packages from another version`, async () => {
const installTargetWithReinstall =
shell === Bash
? `__out__="$(fnm install ${TARGET_VERSION} --reinstall-packages-from=${SOURCE_VERSION} 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)
`
: `$__out__ = fnm install ${TARGET_VERSION} --reinstall-packages-from=${SOURCE_VERSION} 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 }
`

await script(shell)
.then(shell.env({}))
.then(shell.call("fnm", ["install", SOURCE_VERSION]))
.then(shell.call("fnm", ["use", SOURCE_VERSION]))
.then(shell.call("npm", ["install", "-g", "is-odd"]))
.then(
shell.scriptOutputContains(
shell.call("npm", ["list", "-g", "--depth=0"]),
"'is-odd'"
)
)
.then(installTargetWithReinstall)
.then(shell.call("fnm", ["use", TARGET_VERSION]))
.then(
shell.scriptOutputContains(
shell.call("npm", ["list", "-g", "--depth=0"]),
"'is-odd'"
)
)
.takeSnapshot(shell)
.execute(shell)
})

test(`errors when source version is not installed`, async () => {
await script(shell)
.then(shell.env({ logLevel: "error" }))
.then(
shell.scriptOutputContains(
getStderr(
shell.call("fnm", [
"install",
TARGET_VERSION,
`--reinstall-packages-from=${SOURCE_VERSION}`,
])
),
"'Version v18.20.0 is not installed'",
)
)
.takeSnapshot(shell)
.execute(shell)
})

test(`source has no global packages`, async () => {
await script(shell)
.then(shell.env({}))
.then(shell.call("fnm", ["install", SOURCE_VERSION]))
.then(
shell.scriptOutputContains(
shell.call("fnm", [
"install",
TARGET_VERSION,
`--reinstall-packages-from=${SOURCE_VERSION}`,
]),
"'No global packages found in'",
)
)
.takeSnapshot(shell)
.execute(shell)
})
})
}

Loading
Loading