Skip to content

Commit 842e8c4

Browse files
authored
fix(pnpm): fallback from pnpm.cmd to pnpm on Windows for non-standard installs (#1606)
1 parent d8c983b commit 842e8c4

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

src/package-managers/pnpm.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,37 @@ const npmConfigFromPnpmWorkspace = memoize(async (options: Options): Promise<Npm
5151
return config
5252
})
5353

54+
/**
55+
* Spawn pnpm. On Windows, prefer `pnpm.cmd` but fall back to `pnpm` when the
56+
* `.cmd` shim is not available (e.g. mise, scoop).
57+
*/
58+
async function spawnPnpmCommand(
59+
args: string[],
60+
spawnPleaseOptions?: SpawnPleaseOptions,
61+
spawnOptions?: SpawnOptions,
62+
) {
63+
if (process.platform !== 'win32') {
64+
return spawn('pnpm', args, spawnPleaseOptions, spawnOptions)
65+
}
66+
67+
try {
68+
return await spawn('pnpm.cmd', args, spawnPleaseOptions, spawnOptions)
69+
} catch (e) {
70+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
71+
return spawn('pnpm', args, spawnPleaseOptions, spawnOptions)
72+
}
73+
74+
throw e
75+
}
76+
}
77+
5478
/** Fetches the list of all installed packages. */
5579
export const list = async (options: Options = {}): Promise<Index<string | undefined>> => {
5680
// use npm for local ls for completeness
5781
// this should never happen since list is only called in runGlobal -> getInstalledPackages
5882
if (!options.global) return npm.list(options)
5983

60-
const cmd = process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm'
61-
const { stdout } = await spawn(cmd, ['ls', '-g', '--json'])
84+
const { stdout } = await spawnPnpmCommand(['ls', '-g', '--json'])
6285
const result = JSON.parse(stdout) as PnpmList
6386
const list = keyValueBy(result[0].dependencies || {}, (name, { version }) => ({
6487
[name]: version,
@@ -94,15 +117,13 @@ async function spawnPnpm(
94117
spawnOptions?: SpawnOptions,
95118
spawnPleaseOptions?: SpawnPleaseOptions,
96119
): Promise<string> {
97-
const cmd = process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm'
98-
99120
const fullArgs = [
100121
...(npmOptions.global ? 'global' : []),
101122
...(Array.isArray(args) ? args : [args]),
102123
...(npmOptions.prefix ? `--prefix=${npmOptions.prefix}` : []),
103124
]
104125

105-
const { stdout } = await spawn(cmd, fullArgs, spawnPleaseOptions, spawnOptions)
126+
const { stdout } = await spawnPnpmCommand(fullArgs, spawnPleaseOptions, spawnOptions)
106127

107128
return stdout
108129
}

0 commit comments

Comments
 (0)