Files
orca/src/shared/setup-runner-command.ts
T
2026-06-28 13:50:00 -07:00

88 lines
2.4 KiB
TypeScript

import { isWindowsAbsolutePathLike } from './cross-platform-path'
export type SetupRunnerCommandPlatform = 'windows' | 'posix'
export type SetupRunnerCommandShell = 'posix' | 'windows'
export type SetupRunnerCommandResolution = {
command: string
runnerScriptPathForShell: string
shell: SetupRunnerCommandShell
}
export function buildSetupRunnerCommand(
runnerScriptPath: string,
platform: SetupRunnerCommandPlatform
): string {
return resolveSetupRunnerCommand(runnerScriptPath, platform).command
}
export function getSetupRunnerCommandPlatformForPath(
runnerScriptPath: string,
fallbackPlatform: SetupRunnerCommandPlatform
): SetupRunnerCommandPlatform {
if (isWindowsAbsolutePathLike(runnerScriptPath)) {
return 'windows'
}
if (runnerScriptPath.startsWith('/')) {
return 'posix'
}
return fallbackPlatform
}
export function resolveSetupRunnerCommand(
runnerScriptPath: string,
platform: SetupRunnerCommandPlatform
): SetupRunnerCommandResolution {
if (platform === 'windows') {
if (isWslUncPath(runnerScriptPath)) {
const linuxPath = wslUncToLinuxPath(runnerScriptPath)
return {
command: `bash ${quotePosixArg(linuxPath)}`,
runnerScriptPathForShell: linuxPath,
shell: 'posix'
}
}
if (runnerScriptPath.startsWith('/') && !isWindowsAbsolutePathLike(runnerScriptPath)) {
return {
command: `bash ${quotePosixArg(runnerScriptPath)}`,
runnerScriptPathForShell: runnerScriptPath,
shell: 'posix'
}
}
return {
command: `cmd.exe /c ${quoteWindowsArg(runnerScriptPath)}`,
runnerScriptPathForShell: runnerScriptPath,
shell: 'windows'
}
}
return {
command: `bash ${quotePosixArg(runnerScriptPath)}`,
runnerScriptPathForShell: runnerScriptPath,
shell: 'posix'
}
}
export function isWslUncPath(path: string): boolean {
const normalized = path.replace(/\\/g, '/')
return /^\/\/(wsl\.localhost|wsl\$)\//i.test(normalized)
}
export function wslUncToLinuxPath(windowsPath: string): string {
const normalized = windowsPath.replace(/\\/g, '/')
const match = normalized.match(/^\/\/(wsl\.localhost|wsl\$)\/[^/]+(\/.*)?$/i)
return match?.[2] || '/'
}
function quotePosixArg(value: string): string {
if (/^[A-Za-z0-9_./:-]+$/.test(value)) {
return value
}
return `'${value.replace(/'/g, `'\\''`)}'`
}
function quoteWindowsArg(value: string): string {
return `"${value.replace(/"/g, '""')}"`
}