Skip to content

Commit facd1f2

Browse files
committed
Fix Windows spawn issues by enabling shell for .cmd files
1 parent ef6c9a9 commit facd1f2

File tree

4 files changed

+14
-6
lines changed

4 files changed

+14
-6
lines changed

src/agent.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import { CI } from '#env/ci'
2727

28+
import { WIN32 } from '#constants/platform'
2829
import { execBin } from './bin'
2930
import { isDebug } from './debug'
3031
import { findUpSync } from './fs'
@@ -128,6 +129,8 @@ export function execNpm(args: string[], options?: SpawnOptions | undefined) {
128129
],
129130
{
130131
__proto__: null,
132+
// On Windows, npm is a .cmd file that requires shell to execute.
133+
shell: WIN32,
131134
...options,
132135
} as SpawnOptions,
133136
)

src/bin.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { HOME } from '#env/home'
88
import { LOCALAPPDATA } from '#env/localappdata'
99
import { XDG_DATA_HOME } from '#env/xdg-data-home'
1010

11+
import { WIN32 } from '#constants/platform'
1112
import { readJsonSync } from './fs'
1213
import { getOwn } from './objects'
1314
import { isPath, normalizePath } from './path'
@@ -79,7 +80,11 @@ export async function execBin(
7980
const binCommand = Array.isArray(resolvedPath)
8081
? resolvedPath[0]!
8182
: resolvedPath
82-
return await spawn(binCommand, args ?? [], options)
83+
// On Windows, binaries are often .cmd files that require shell to execute.
84+
return await spawn(binCommand, args ?? [], {
85+
shell: WIN32,
86+
...options,
87+
})
8388
}
8489

8590
/**
@@ -248,7 +253,6 @@ export function findRealNpm(): string {
248253
* Find the real pnpm executable, bypassing any aliases and shadow bins.
249254
*/
250255
export function findRealPnpm(): string {
251-
const WIN32 = require('../constants/platform').WIN32
252256
const path = getPath()
253257

254258
// Try common pnpm locations.
@@ -381,7 +385,6 @@ export function resolveBinPathSync(binPath: string): string {
381385
return voltaBinPath
382386
}
383387
}
384-
const WIN32 = require('../constants/platform').WIN32
385388
if (WIN32) {
386389
const hasKnownExt =
387390
extLowered === '' ||

src/git.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'node:path'
22

3+
import { WIN32 } from '#constants/platform'
34
import { getGlobMatcher } from './globs'
45
import { normalizePath } from './path'
56
import { spawn, spawnSync } from './spawn'
@@ -231,7 +232,7 @@ function getGitDiffSpawnArgs(cwd?: string | undefined): GitDiffSpawnArgs {
231232
['status', '--porcelain'],
232233
{
233234
cwd: resolvedCwd,
234-
shell: process.platform === 'win32',
235+
shell: WIN32,
235236
},
236237
],
237238
unstaged: [
@@ -246,7 +247,7 @@ function getGitDiffSpawnArgs(cwd?: string | undefined): GitDiffSpawnArgs {
246247
['diff', '--cached', '--name-only'],
247248
{
248249
cwd: resolvedCwd,
249-
shell: process.platform === 'win32',
250+
shell: WIN32,
250251
},
251252
],
252253
}

src/temporary-executor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Identifies and handles temporary execution contexts such as npx, pnpm dlx, and yarn dlx.
44
*/
55

6+
import { WIN32 } from '#constants/platform'
67
import { normalizePath } from './path'
78

89
/**
@@ -46,7 +47,7 @@ export function isRunningInTemporaryExecutor(cwd = process.cwd()): boolean {
4647
]
4748

4849
// Yarn on Windows uses AppData/Local/Temp/xfs- pattern.
49-
if (process.platform === 'win32') {
50+
if (WIN32) {
5051
tempPatterns.push('AppData/Local/Temp/xfs-')
5152
}
5253

0 commit comments

Comments
 (0)