fix(scripts): quote Windows shell invocations
This commit is contained in:
parent
58a0eb603d
commit
636beb5e42
11 changed files with 99 additions and 57 deletions
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { spawn } from 'node:child_process';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
import { spawnWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
const standalonePort = process.env.STANDALONE_PORT?.trim() || '3456';
|
const standalonePort = process.env.STANDALONE_PORT?.trim() || '3456';
|
||||||
|
|
@ -13,22 +14,11 @@ const corsOrigin =
|
||||||
process.env.CORS_ORIGIN?.trim() ||
|
process.env.CORS_ORIGIN?.trim() ||
|
||||||
`http://127.0.0.1:${webPort},http://localhost:${webPort}`;
|
`http://127.0.0.1:${webPort},http://localhost:${webPort}`;
|
||||||
|
|
||||||
const WINDOWS_SHELL_COMMANDS = new Set(['pnpm', 'npm', 'npx', 'yarn', 'yarnpkg', 'corepack']);
|
|
||||||
|
|
||||||
function shouldUseWindowsShell(cmd) {
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WINDOWS_SHELL_COMMANDS.has(path.basename(cmd).toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
function spawnProcess(cmd, args, env) {
|
function spawnProcess(cmd, args, env) {
|
||||||
return spawn(cmd, args, {
|
return spawnWithWindowsShell(cmd, args, {
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env: { ...process.env, ...env },
|
env: { ...process.env, ...env },
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: shouldUseWindowsShell(cmd),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ import fs from 'node:fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import { once } from 'node:events';
|
import { once } from 'node:events';
|
||||||
import readline from 'node:readline';
|
import readline from 'node:readline';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const uiRepoRoot = path.resolve(scriptDir, '..');
|
const uiRepoRoot = path.resolve(scriptDir, '..');
|
||||||
const runtimeRepoRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim() ?? '';
|
const runtimeRepoRoot = process.env.CLAUDE_DEV_RUNTIME_ROOT?.trim() ?? '';
|
||||||
|
|
@ -22,26 +23,10 @@ const scriptArgs = process.argv.slice(2);
|
||||||
const shouldPrintRuntimePath = scriptArgs.includes('--print-runtime-path');
|
const shouldPrintRuntimePath = scriptArgs.includes('--print-runtime-path');
|
||||||
const electronViteArgs = scriptArgs.filter((arg) => arg !== '--print-runtime-path' && arg !== '--');
|
const electronViteArgs = scriptArgs.filter((arg) => arg !== '--print-runtime-path' && arg !== '--');
|
||||||
const runtimeDisplayName = 'teams orchestrator';
|
const runtimeDisplayName = 'teams orchestrator';
|
||||||
const WINDOWS_SHELL_COMMANDS = new Set(['pnpm', 'npm', 'npx', 'yarn', 'yarnpkg', 'corepack']);
|
|
||||||
|
|
||||||
function shouldUseWindowsShell(cmd) {
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const extension = path.extname(cmd).toLowerCase();
|
|
||||||
if (extension === '.cmd' || extension === '.bat') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const commandName = path.basename(cmd).toLowerCase();
|
|
||||||
return WINDOWS_SHELL_COMMANDS.has(commandName);
|
|
||||||
}
|
|
||||||
|
|
||||||
function runOrExit(cmd, args, options = {}) {
|
function runOrExit(cmd, args, options = {}) {
|
||||||
const result = spawnSync(cmd, args, {
|
const result = spawnSyncWithWindowsShell(cmd, args, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: shouldUseWindowsShell(cmd),
|
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -56,9 +41,8 @@ function runOrExit(cmd, args, options = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function runAndCapture(cmd, args, options = {}) {
|
function runAndCapture(cmd, args, options = {}) {
|
||||||
const result = spawnSync(cmd, args, {
|
const result = spawnSyncWithWindowsShell(cmd, args, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
shell: shouldUseWindowsShell(cmd),
|
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
59
scripts/lib/windows-shell-spawn.mjs
Normal file
59
scripts/lib/windows-shell-spawn.mjs
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { spawn, spawnSync } from 'node:child_process';
|
||||||
|
import path from 'node:path';
|
||||||
|
import process from 'node:process';
|
||||||
|
|
||||||
|
const WINDOWS_SHELL_COMMANDS = new Set(['pnpm', 'npm', 'npx', 'yarn', 'yarnpkg', 'corepack']);
|
||||||
|
|
||||||
|
export function quoteWindowsCmdArg(value) {
|
||||||
|
const text = String(value);
|
||||||
|
if (text.length === 0) {
|
||||||
|
return '""';
|
||||||
|
}
|
||||||
|
if (!/[ \t\r\n"&|<>^()%!]/.test(text)) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return `"${text.replace(/%/g, '%%').replace(/(["^&|<>])/g, '^$1')}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldUseWindowsShell(command) {
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extension = path.extname(command).toLowerCase();
|
||||||
|
if (extension === '.cmd' || extension === '.bat') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINDOWS_SHELL_COMMANDS.has(path.basename(command).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
function toWindowsShellCommand(command, args) {
|
||||||
|
return [command, ...args].map(quoteWindowsCmdArg).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function spawnWithWindowsShell(command, args, options = {}) {
|
||||||
|
if (!shouldUseWindowsShell(command)) {
|
||||||
|
return spawn(command, args, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
const safeOptions = { ...options };
|
||||||
|
delete safeOptions.shell;
|
||||||
|
return spawn(toWindowsShellCommand(command, args), {
|
||||||
|
...safeOptions,
|
||||||
|
shell: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function spawnSyncWithWindowsShell(command, args, options = {}) {
|
||||||
|
if (!shouldUseWindowsShell(command)) {
|
||||||
|
return spawnSync(command, args, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
const safeOptions = { ...options };
|
||||||
|
delete safeOptions.shell;
|
||||||
|
return spawnSync(toWindowsShellCommand(command, args), {
|
||||||
|
...safeOptions,
|
||||||
|
shell: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -26,7 +26,7 @@ if (!env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH?.trim()) {
|
||||||
console.log('Running agent CLI launch live smoke');
|
console.log('Running agent CLI launch live smoke');
|
||||||
console.log(`Claude runtime: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`);
|
console.log(`Claude runtime: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -42,7 +42,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
@ -10,6 +9,7 @@ import {
|
||||||
exitForSkippedPreflight,
|
exitForSkippedPreflight,
|
||||||
preflightOpenCodeLiveEnvironment,
|
preflightOpenCodeLiveEnvironment,
|
||||||
} from './lib/opencode-live-preflight.mjs';
|
} from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -40,7 +40,7 @@ console.log(`Multi-lane: ${env.OPENCODE_E2E_MIXED_RECOVERY_MULTI === '1' ? 'enab
|
||||||
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
||||||
exitForSkippedPreflight(preflight);
|
exitForSkippedPreflight(preflight);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -56,7 +56,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
@ -10,6 +9,7 @@ import {
|
||||||
exitForSkippedPreflight,
|
exitForSkippedPreflight,
|
||||||
preflightOpenCodeLiveEnvironment,
|
preflightOpenCodeLiveEnvironment,
|
||||||
} from './lib/opencode-live-preflight.mjs';
|
} from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -46,7 +46,7 @@ console.log(`Orchestrator CLI: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`)
|
||||||
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
||||||
exitForSkippedPreflight(preflight);
|
exitForSkippedPreflight(preflight);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -62,7 +62,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
@ -10,6 +9,7 @@ import {
|
||||||
exitForSkippedPreflight,
|
exitForSkippedPreflight,
|
||||||
preflightOpenCodeLiveEnvironment,
|
preflightOpenCodeLiveEnvironment,
|
||||||
} from './lib/opencode-live-preflight.mjs';
|
} from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -38,7 +38,7 @@ console.log(`Orchestrator CLI: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`)
|
||||||
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
||||||
exitForSkippedPreflight(preflight);
|
exitForSkippedPreflight(preflight);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -54,7 +54,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
@ -10,6 +9,7 @@ import {
|
||||||
exitForSkippedPreflight,
|
exitForSkippedPreflight,
|
||||||
preflightOpenCodeLiveEnvironment,
|
preflightOpenCodeLiveEnvironment,
|
||||||
} from './lib/opencode-live-preflight.mjs';
|
} from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -36,7 +36,7 @@ console.log(`Orchestrator CLI: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`)
|
||||||
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
||||||
exitForSkippedPreflight(preflight);
|
exitForSkippedPreflight(preflight);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -52,7 +52,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { spawnSync } from 'node:child_process';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
@ -10,6 +9,7 @@ import {
|
||||||
exitForSkippedPreflight,
|
exitForSkippedPreflight,
|
||||||
preflightOpenCodeLiveEnvironment,
|
preflightOpenCodeLiveEnvironment,
|
||||||
} from './lib/opencode-live-preflight.mjs';
|
} from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -38,7 +38,7 @@ console.log(`Orchestrator CLI: ${env.CLAUDE_AGENT_TEAMS_ORCHESTRATOR_CLI_PATH}`)
|
||||||
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
const preflight = await preflightOpenCodeLiveEnvironment({ repoRoot });
|
||||||
exitForSkippedPreflight(preflight);
|
exitForSkippedPreflight(preflight);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -54,7 +54,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
import { resolveLiveSmokeOrchestratorCliPath } from './lib/live-smoke-runtime.mjs';
|
||||||
import { preflightOpenCodeLiveEnvironment } from './lib/opencode-live-preflight.mjs';
|
import { preflightOpenCodeLiveEnvironment } from './lib/opencode-live-preflight.mjs';
|
||||||
|
import { spawnSyncWithWindowsShell } from './lib/windows-shell-spawn.mjs';
|
||||||
|
|
||||||
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const repoRoot = path.resolve(scriptDir, '..');
|
const repoRoot = path.resolve(scriptDir, '..');
|
||||||
|
|
@ -69,7 +70,7 @@ if (preflight.skipped.length > 0 && process.env.PROVIDER_LAUNCH_STRESS_STRICT ==
|
||||||
env.PROVIDER_LAUNCH_STRESS_ORDER = preflight.order.join(',');
|
env.PROVIDER_LAUNCH_STRESS_ORDER = preflight.order.join(',');
|
||||||
console.log(`Runnable order: ${env.PROVIDER_LAUNCH_STRESS_ORDER}`);
|
console.log(`Runnable order: ${env.PROVIDER_LAUNCH_STRESS_ORDER}`);
|
||||||
|
|
||||||
const result = spawnSync(
|
const result = spawnSyncWithWindowsShell(
|
||||||
'pnpm',
|
'pnpm',
|
||||||
[
|
[
|
||||||
'exec',
|
'exec',
|
||||||
|
|
@ -85,7 +86,6 @@ const result = spawnSync(
|
||||||
cwd: repoRoot,
|
cwd: repoRoot,
|
||||||
env,
|
env,
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: process.platform === 'win32',
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -312,10 +312,25 @@ function spawnRealCli(
|
||||||
) {
|
) {
|
||||||
const spawnOptions = options ?? {};
|
const spawnOptions = options ?? {};
|
||||||
const needsWindowsCommandShell = process.platform === 'win32' && /\.(bat|cmd)$/i.test(command);
|
const needsWindowsCommandShell = process.platform === 'win32' && /\.(bat|cmd)$/i.test(command);
|
||||||
return spawn(command, [...args], {
|
if (needsWindowsCommandShell) {
|
||||||
...spawnOptions,
|
const commandLine = [command, ...args].map(quoteWindowsCmdArg).join(' ');
|
||||||
...(needsWindowsCommandShell ? { shell: true } : {}),
|
return spawn(commandLine, {
|
||||||
});
|
...spawnOptions,
|
||||||
|
shell: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return spawn(command, [...args], spawnOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function quoteWindowsCmdArg(value: string) {
|
||||||
|
if (value.length === 0) {
|
||||||
|
return '""';
|
||||||
|
}
|
||||||
|
if (!/[ \t\r\n"&|<>^()%!]/.test(value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return `"${value.replace(/%/g, '%%').replace(/(["^&|<>])/g, '^$1')}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeTempRoot(dirPath: string): Promise<void> {
|
async function removeTempRoot(dirPath: string): Promise<void> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue