Skip to content

Commit

Permalink
allow to automatically enable corepack (#960)
Browse files Browse the repository at this point in the history
* allow to automatically enable corepack

* update command docs

* add changeset

* fix clippy

* don't show the value of corepack

* fix test

* test against more shells

* Make exec handle errors more nicely

* nicer i think

* set corepack as debug

* fix windows-style paths in Bash #390

* fix clippy

* run cygpath on `use` validation too

* trim whitespace

* fix test?

* fix test

* add changeset
  • Loading branch information
Schniz authored Jun 29, 2023
1 parent 9940513 commit c29f315
Show file tree
Hide file tree
Showing 21 changed files with 331 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-rocks-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fnm": minor
---

Add --corepack-enabled flag for automatically enabling corepack on fnm install
5 changes: 5 additions & 0 deletions .changeset/rare-otters-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fnm": patch
---

use cygwinpath to make the path posix-like on Windows Bash usage
91 changes: 91 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -101,6 +108,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -151,6 +165,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -204,6 +225,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -260,6 +288,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -317,6 +352,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -387,6 +429,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -450,6 +499,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -506,6 +562,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -556,6 +619,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -610,6 +680,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -667,6 +744,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down Expand Up @@ -721,6 +805,13 @@ OPTIONS:
[env: FNM_ARCH]
--corepack-enabled
Enable corepack support for each new installation. This will make fnm call `corepack
enable` on every Node.js installation. For more information about corepack see
https://nodejs.org/api/corepack.html
[env: FNM_COREPACK_ENABLED]
--fnm-dir <BASE_DIR>
The root directory of fnm installations
Expand Down
28 changes: 28 additions & 0 deletions e2e/__snapshots__/corepack.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

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

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

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[`Zsh installs corepack: Zsh 1`] = `
"set -e
eval "$(fnm env --corepack-enabled)"
fnm install 18
fnm exec --using=18 node test-pnpm-corepack.js"
`;
54 changes: 54 additions & 0 deletions e2e/corepack.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import fs from "fs"
import { script } from "./shellcode/script.js"
import { Bash, Fish, PowerShell, Zsh } from "./shellcode/shells.js"
import describe from "./describe.js"
import path from "path"
import testCwd from "./shellcode/test-cwd.js"
import { createRequire } from "module"

const require = createRequire(import.meta.url)
const whichPath = require.resolve("which")

const nodescript = `
const which = require(${JSON.stringify(whichPath)});
const pnpmBinary = which.sync('pnpm')
const nodeBinary = which.sync('node')
const binPath = require('path').dirname(nodeBinary);
if (!pnpmBinary.includes(binPath)) {
console.log('pnpm not found in current Node.js bin', { binPath, pnpmBinary });
process.exit(1);
}
const scriptContents = require('fs').readFileSync(pnpmBinary, 'utf8');
console.log('scriptContents', scriptContents)
if (!scriptContents.includes('corepack')) {
console.log('corepack not found in pnpm script');
process.exit(1);
}
`

for (const shell of [Bash, Fish, PowerShell, Zsh]) {
describe(shell, () => {
test(`installs corepack`, async () => {
const cwd = testCwd()
const filepath = path.join(cwd, "test-pnpm-corepack.js")
fs.writeFileSync(filepath, nodescript)

await script(shell)
.then(shell.env({ corepackEnabled: true }))
.then(shell.call("fnm", ["install", "18"]))
.then(
shell.call("fnm", [
"exec",
"--using=18",
"node",
"test-pnpm-corepack.js",
])
)
.takeSnapshot(shell)
// .addExtraEnvVar("RUST_LOG", "fnm=debug")
.execute(shell)
})
})
}
1 change: 1 addition & 0 deletions e2e/env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ for (const shell of [Bash, Zsh, Fish, PowerShell, WinCmd]) {
FNM_LOGLEVEL: "info",
FNM_MULTISHELL_PATH: expect.any(String),
FNM_NODE_DIST_MIRROR: expect.any(String),
FNM_COREPACK_ENABLED: "false",
FNM_VERSION_FILE_STRATEGY: "local",
})
}
Expand Down
20 changes: 15 additions & 5 deletions e2e/shellcode/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Script {
private readonly config: {
fnmDir: string
},
private readonly lines: ScriptLine[]
private readonly lines: ScriptLine[],
private readonly extraEnvVars: Record<string, string> = {}
) {}
then(line: ScriptLine): Script {
return new Script(this.config, [...this.lines, line])
Expand All @@ -28,6 +29,14 @@ class Script {
return this
}

addExtraEnvVar(name: string, value: string): this {
return new Script(
this.config,
this.lines,
Object.assign({}, this.extraEnvVars, { [name]: value })
) as this
}

async execute(
shell: Pick<
Shell,
Expand All @@ -54,6 +63,7 @@ class Script {
cwd: testCwd(),
env: (() => {
const newProcessEnv: Record<string, string> = {
...this.extraEnvVars,
...removeAllFnmEnvVars(process.env),
PATH: [testBinDir(), fnmTargetDir(), process.env.PATH]
.filter(Boolean)
Expand Down Expand Up @@ -119,8 +129,8 @@ function streamOutputsAndBuffer(child: ExecaChildProcess) {

if (child.stdout) {
child.stdout.on("data", (data) => {
const line = data.toString().trim()
if (line) {
const lines = data.toString().trim().split(/\r?\n/)
for (const line of lines) {
process.stdout.write(`${stdoutPrefix}${line}\n`)
}
stdout.push(data.toString())
Expand All @@ -129,8 +139,8 @@ function streamOutputsAndBuffer(child: ExecaChildProcess) {

if (child.stderr) {
child.stderr.on("data", (data) => {
const line = data.toString().trim()
if (line) {
const lines = data.toString().trim().split(/\r?\n/)
for (const line of lines) {
process.stdout.write(`${stderrPrefix}${line}\n`)
}
stderr.push(data.toString())
Expand Down
9 changes: 7 additions & 2 deletions e2e/shellcode/shells/cmdEnv.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { ScriptLine, define } from "./types.js"

type EnvConfig = { useOnCd: boolean; logLevel: string }
type EnvConfig = {
useOnCd: boolean
logLevel: string
corepackEnabled: boolean
}
export type HasEnv = { env(cfg: Partial<EnvConfig>): ScriptLine }

function stringify(envConfig: Partial<EnvConfig> = {}) {
const { useOnCd, logLevel } = envConfig
const { useOnCd, logLevel, corepackEnabled } = envConfig
return [
`fnm env`,
useOnCd && "--use-on-cd",
logLevel && `--log-level=${logLevel}`,
corepackEnabled && "--corepack-enabled",
]
.filter(Boolean)
.join(" ")
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"ts-dedent": "^2.2.0",
"ts-jest": "^29.0.3",
"typescript": "^4.8.4",
"which": "^3.0.1",
"zod": "^3.19.1"
},
"prettier": {
Expand Down
Loading

1 comment on commit c29f315

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linux Benchmarks

benchmark current value last value diff trend
fnm_basic/median 20.86ms 20.81ms +0.05ms

fnm_basic/max 28.07ms 22.75ms +5.33ms

fnm_basic/mean 21.05ms 20.96ms +0.09ms

fnm_basic/min 20.31ms 20.29ms +0.02ms

fnm_basic/stddev 0.93ms 0.53ms +0.4ms

binary size 6804kb 6772kb +32kb

Please sign in to comment.