90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { type Options as ExecaOptions, execaSync } from 'execa'
|
|
import { getCwd } from '../utils/cwd.js'
|
|
import { slowLogging } from './slowOperations.js'
|
|
|
|
const MS_IN_SECOND = 1000
|
|
const SECONDS_IN_MINUTE = 60
|
|
|
|
type ExecSyncOptions = {
|
|
abortSignal?: AbortSignal
|
|
timeout?: number
|
|
input?: string
|
|
stdio?: ExecaOptions['stdio']
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use `execa` directly with `{ shell: true, reject: false }` for non-blocking execution.
|
|
* Sync exec calls block the event loop and cause performance issues.
|
|
*/
|
|
export function execSyncWithDefaults_DEPRECATED(command: string): string | null
|
|
/**
|
|
* @deprecated Use `execa` directly with `{ shell: true, reject: false }` for non-blocking execution.
|
|
* Sync exec calls block the event loop and cause performance issues.
|
|
*/
|
|
export function execSyncWithDefaults_DEPRECATED(
|
|
command: string,
|
|
options: ExecSyncOptions,
|
|
): string | null
|
|
/**
|
|
* @deprecated Use `execa` directly with `{ shell: true, reject: false }` for non-blocking execution.
|
|
* Sync exec calls block the event loop and cause performance issues.
|
|
*/
|
|
export function execSyncWithDefaults_DEPRECATED(
|
|
command: string,
|
|
abortSignal: AbortSignal,
|
|
timeout?: number,
|
|
): string | null
|
|
/**
|
|
* @deprecated Use `execa` directly with `{ shell: true, reject: false }` for non-blocking execution.
|
|
* Sync exec calls block the event loop and cause performance issues.
|
|
*/
|
|
export function execSyncWithDefaults_DEPRECATED(
|
|
command: string,
|
|
optionsOrAbortSignal?: ExecSyncOptions | AbortSignal,
|
|
timeout = 10 * SECONDS_IN_MINUTE * MS_IN_SECOND,
|
|
): string | null {
|
|
let options: ExecSyncOptions
|
|
|
|
if (optionsOrAbortSignal === undefined) {
|
|
// No second argument - use defaults
|
|
options = {}
|
|
} else if (optionsOrAbortSignal instanceof AbortSignal) {
|
|
// Old signature - second argument is AbortSignal
|
|
options = {
|
|
abortSignal: optionsOrAbortSignal,
|
|
timeout,
|
|
}
|
|
} else {
|
|
// New signature - second argument is options object
|
|
options = optionsOrAbortSignal
|
|
}
|
|
|
|
const {
|
|
abortSignal,
|
|
timeout: finalTimeout = 10 * SECONDS_IN_MINUTE * MS_IN_SECOND,
|
|
input,
|
|
stdio = ['ignore', 'pipe', 'pipe'],
|
|
} = options
|
|
|
|
abortSignal?.throwIfAborted()
|
|
using _ = slowLogging`exec: ${command.slice(0, 200)}`
|
|
try {
|
|
const result = execaSync(command, {
|
|
env: process.env,
|
|
maxBuffer: 1_000_000,
|
|
timeout: finalTimeout,
|
|
cwd: getCwd(),
|
|
stdio,
|
|
shell: true, // execSync typically runs shell commands
|
|
reject: false, // Don't throw on non-zero exit codes
|
|
input,
|
|
})
|
|
if (!result.stdout) {
|
|
return null
|
|
}
|
|
return result.stdout.trim() || null
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|