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
5 changes: 5 additions & 0 deletions .changeset/upset-chefs-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fnm": patch
---

Only enable Corepack on Node.js versions that bundle it
6 changes: 6 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ error: Can't find version in dotfiles. Please provide a version manually to the

Runs [`corepack enable`](https://nodejs.org/api/corepack.html#enabling-the-feature) when a new version of Node.js is installed. Experimental due to the fact Corepack itself is experimental.

> [!NOTE]
> Corepack is only bundled with Node.js v14.19.0+, v16.9.0+ and up to, but not including v25.0.0+, i.e. `^14.19.0 || 16.9.0 - 24.x.x`.
>
> When installing Node.js versions outside the range,
> you will see a hint that you need to manually install and enable Corepack via `npm install -g corepack && corepack enable`.

### `--resolve-engines`

**🧪 Experimental**
Expand Down
23 changes: 23 additions & 0 deletions e2e/__snapshots__/corepack.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,45 @@ fnm install 18
fnm exec --using=18 node test-pnpm-corepack.js"
`;

exports[`Bash skips enabling Corepack if it's not bundled with Node.js: Bash 1`] = `
"set -e
eval "$(fnm env --corepack-enabled)"
(fnm install 14.18.0) | grep "npm install -g corepack" || (echo "Expected output to contain "npm install -g corepack"" && exit 1)"
`;

exports[`Fish installs corepack: Fish 1`] = `
"fnm env --corepack-enabled | source
fnm install 18
fnm exec --using=18 node test-pnpm-corepack.js"
`;

exports[`Fish skips enabling Corepack if it's not bundled with Node.js: Fish 1`] = `
"fnm env --corepack-enabled | source
begin; fnm install 14.18.0; end | grep "npm install -g corepack"; or echo "Expected output to contain "npm install -g corepack"" && exit 1"
`;

exports[`PowerShell installs corepack: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env --corepack-enabled | Out-String | Invoke-Expression
fnm install 18
fnm exec --using=18 node test-pnpm-corepack.js"
`;

exports[`PowerShell skips enabling Corepack if it's not bundled with Node.js: PowerShell 1`] = `
"$ErrorActionPreference = "Stop"
fnm env --corepack-enabled | Out-String | Invoke-Expression
$($__out__ = $(fnm install 14.18.0 | Select-String "npm install -g corepack"); if ($__out__ -eq $null) { exit 1 } else { $__out__ })"
`;

exports[`Zsh installs corepack: Zsh 1`] = `
"set -e
eval "$(fnm env --corepack-enabled)"
fnm install 18
fnm exec --using=18 node test-pnpm-corepack.js"
`;

exports[`Zsh skips enabling Corepack if it's not bundled with Node.js: Zsh 1`] = `
"set -e
eval "$(fnm env --corepack-enabled)"
(fnm install 14.18.0) | grep "npm install -g corepack" || (echo "Expected output to contain "npm install -g corepack"" && exit 1)"
`;
13 changes: 13 additions & 0 deletions e2e/corepack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,18 @@ for (const shell of [Bash, Fish, PowerShell, Zsh]) {
// .addExtraEnvVar("RUST_LOG", "fnm=debug")
.execute(shell)
})

test(`skips enabling Corepack if it's not bundled with Node.js`, async () => {
await script(shell)
.then(shell.env({ corepackEnabled: true }))
.then(
shell.scriptOutputContains(
shell.call("fnm", ["install", "14.18.0"]),
`"npm install -g corepack"`,
)
)
.takeSnapshot(shell)
.execute(shell)
})
})
}
17 changes: 17 additions & 0 deletions src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ fn tag_alias(config: &FnmConfig, matched_version: &Version, alias: &Version) ->
}

fn enable_corepack(version: &Version, config: &FnmConfig) -> Result<(), Error> {
let Version::Semver(nodejs_version) = version else {
return Ok(());
};

let corepack_range: node_semver::Range = "^14.19.0 || 16.9.0 - 24.x.x".parse().unwrap();

if !nodejs_version.satisfies(&corepack_range) {
let message = format!(
"Note: Corepack is not bundled with Node.js {nodejs_version}, \
so you have to manually install and enable it by running:\
\nnpm install -g corepack && corepack enable"
);
outln!(config, Info, "{}", message.yellow());

return Ok(());
}

let corepack_path = version.installation_path(config);
let corepack_path = if cfg!(windows) {
corepack_path.join("corepack.cmd")
Expand Down