diff --git a/.github/local-actions/branch-manager/main.js b/.github/local-actions/branch-manager/main.js index 1fee88fad..d13356ba5 100644 --- a/.github/local-actions/branch-manager/main.js +++ b/.github/local-actions/branch-manager/main.js @@ -56702,49 +56702,6 @@ var ChildProcess = class { childProcess.on("close", (status) => status === 0 ? resolve() : reject(status)); }); } - static spawn(command, args, options = {}) { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(" ")}`; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${commandText}`); - const childProcess = _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - if (options.input !== void 0) { - childProcess.stdin.write(options.input); - childProcess.stdin.end(); - } - childProcess.stderr.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.stdout.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${commandText}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); - } static spawnSync(command, args, options = {}) { const commandText = `${command} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); @@ -56756,44 +56713,14 @@ ${logOutput}`); } throw new Error(stderr); } + static spawn(command, args, options = {}) { + const commandText = `${command} ${args.join(" ")}`; + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(commandText, options, _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" })); + } static exec(command, options = {}) { - return new Promise((resolve, reject) => { - var _a2, _b; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${command}`); - const childProcess = _exec(command, { ...options, env: env3 }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${command}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(command, options, _exec(command, { ...options, env: env3 })); } }; function statusFromExitCodeAndSignal(exitCode, signal) { @@ -56803,6 +56730,42 @@ function getEnvironmentForNonInteractiveCommand(userProvidedEnv) { const forceColorValue = supports_color_default2.stdout !== false ? supports_color_default2.stdout.level.toString() : void 0; return { FORCE_COLOR: forceColorValue, ...userProvidedEnv ?? process.env }; } +function processAsyncCmd(command, options, childProcess) { + return new Promise((resolve, reject) => { + var _a2, _b; + let logOutput = ""; + let stdout = ""; + let stderr = ""; + Log.debug(`Executing command: ${command}`); + (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { + stderr += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { + stdout += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + childProcess.on("close", (exitCode, signal) => { + const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; + const printFn = options.mode === "on-error" ? Log.error : Log.debug; + const status = statusFromExitCodeAndSignal(exitCode, signal); + printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Process output: +${logOutput}`); + if (status === 0 || options.suppressErrorOnFailingExitCode) { + resolve({ stdout, stderr, status }); + } else { + reject(options.mode === "silent" ? logOutput : void 0); + } + }); + }); +} // function determineRepoBaseDirFromCwd() { diff --git a/.github/local-actions/changelog/main.js b/.github/local-actions/changelog/main.js index e5eeaa02a..c9cee3983 100644 --- a/.github/local-actions/changelog/main.js +++ b/.github/local-actions/changelog/main.js @@ -56575,49 +56575,6 @@ var ChildProcess = class { childProcess.on("close", (status) => status === 0 ? resolve() : reject(status)); }); } - static spawn(command, args, options = {}) { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(" ")}`; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${commandText}`); - const childProcess = _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - if (options.input !== void 0) { - childProcess.stdin.write(options.input); - childProcess.stdin.end(); - } - childProcess.stderr.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.stdout.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${commandText}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); - } static spawnSync(command, args, options = {}) { const commandText = `${command} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); @@ -56629,44 +56586,14 @@ ${logOutput}`); } throw new Error(stderr); } + static spawn(command, args, options = {}) { + const commandText = `${command} ${args.join(" ")}`; + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(commandText, options, _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" })); + } static exec(command, options = {}) { - return new Promise((resolve, reject) => { - var _a2, _b; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${command}`); - const childProcess = _exec(command, { ...options, env: env3 }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${command}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(command, options, _exec(command, { ...options, env: env3 })); } }; function statusFromExitCodeAndSignal(exitCode, signal) { @@ -56676,6 +56603,42 @@ function getEnvironmentForNonInteractiveCommand(userProvidedEnv) { const forceColorValue = supports_color_default2.stdout !== false ? supports_color_default2.stdout.level.toString() : void 0; return { FORCE_COLOR: forceColorValue, ...userProvidedEnv ?? process.env }; } +function processAsyncCmd(command, options, childProcess) { + return new Promise((resolve, reject) => { + var _a2, _b; + let logOutput = ""; + let stdout = ""; + let stderr = ""; + Log.debug(`Executing command: ${command}`); + (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { + stderr += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { + stdout += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + childProcess.on("close", (exitCode, signal) => { + const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; + const printFn = options.mode === "on-error" ? Log.error : Log.debug; + const status = statusFromExitCodeAndSignal(exitCode, signal); + printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Process output: +${logOutput}`); + if (status === 0 || options.suppressErrorOnFailingExitCode) { + resolve({ stdout, stderr, status }); + } else { + reject(options.mode === "silent" ? logOutput : void 0); + } + }); + }); +} // function determineRepoBaseDirFromCwd() { diff --git a/github-actions/create-pr-for-changes/main.js b/github-actions/create-pr-for-changes/main.js index 76e99a1b3..1f3706a14 100644 --- a/github-actions/create-pr-for-changes/main.js +++ b/github-actions/create-pr-for-changes/main.js @@ -41511,49 +41511,6 @@ var ChildProcess = class { childProcess.on("close", (status) => status === 0 ? resolve() : reject(status)); }); } - static spawn(command, args, options = {}) { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(" ")}`; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${commandText}`); - const childProcess = _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - if (options.input !== void 0) { - childProcess.stdin.write(options.input); - childProcess.stdin.end(); - } - childProcess.stderr.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.stdout.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${commandText}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); - } static spawnSync(command, args, options = {}) { const commandText = `${command} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); @@ -41565,44 +41522,14 @@ ${logOutput}`); } throw new Error(stderr); } + static spawn(command, args, options = {}) { + const commandText = `${command} ${args.join(" ")}`; + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(commandText, options, _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" })); + } static exec(command, options = {}) { - return new Promise((resolve, reject) => { - var _a, _b; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${command}`); - const childProcess = _exec(command, { ...options, env: env3 }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - (_a = childProcess.stderr) == null ? void 0 : _a.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${command}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(command, options, _exec(command, { ...options, env: env3 })); } }; function statusFromExitCodeAndSignal(exitCode, signal) { @@ -41612,6 +41539,42 @@ function getEnvironmentForNonInteractiveCommand(userProvidedEnv) { const forceColorValue = supports_color_default2.stdout !== false ? supports_color_default2.stdout.level.toString() : void 0; return { FORCE_COLOR: forceColorValue, ...userProvidedEnv ?? process.env }; } +function processAsyncCmd(command, options, childProcess) { + return new Promise((resolve, reject) => { + var _a, _b; + let logOutput = ""; + let stdout = ""; + let stderr = ""; + Log.debug(`Executing command: ${command}`); + (_a = childProcess.stderr) == null ? void 0 : _a.on("data", (message) => { + stderr += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { + stdout += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + childProcess.on("close", (exitCode, signal) => { + const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; + const printFn = options.mode === "on-error" ? Log.error : Log.debug; + const status = statusFromExitCodeAndSignal(exitCode, signal); + printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Process output: +${logOutput}`); + if (status === 0 || options.suppressErrorOnFailingExitCode) { + resolve({ stdout, stderr, status }); + } else { + reject(options.mode === "silent" ? logOutput : void 0); + } + }); + }); +} // function determineRepoBaseDirFromCwd() { diff --git a/github-actions/slash-commands/main.js b/github-actions/slash-commands/main.js index e39c49cbe..c0b9d712a 100644 --- a/github-actions/slash-commands/main.js +++ b/github-actions/slash-commands/main.js @@ -53435,49 +53435,6 @@ var ChildProcess = class { childProcess.on("close", (status) => status === 0 ? resolve() : reject(status)); }); } - static spawn(command, args, options = {}) { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(" ")}`; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${commandText}`); - const childProcess = _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - if (options.input !== void 0) { - childProcess.stdin.write(options.input); - childProcess.stdin.end(); - } - childProcess.stderr.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.stdout.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${commandText}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); - } static spawnSync(command, args, options = {}) { const commandText = `${command} ${args.join(" ")}`; const env3 = getEnvironmentForNonInteractiveCommand(options.env); @@ -53489,44 +53446,14 @@ ${logOutput}`); } throw new Error(stderr); } + static spawn(command, args, options = {}) { + const commandText = `${command} ${args.join(" ")}`; + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(commandText, options, _spawn(command, args, { ...options, env: env3, shell: true, stdio: "pipe" })); + } static exec(command, options = {}) { - return new Promise((resolve, reject) => { - var _a2, _b; - const outputMode = options.mode; - const env3 = getEnvironmentForNonInteractiveCommand(options.env); - Log.debug(`Executing command: ${command}`); - const childProcess = _exec(command, { ...options, env: env3 }); - let logOutput = ""; - let stdout = ""; - let stderr = ""; - (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { - stderr += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { - stdout += message; - logOutput += message; - if (outputMode === void 0 || outputMode === "enabled") { - process.stderr.write(message); - } - }); - childProcess.on("close", (exitCode, signal) => { - const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === "on-error" ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - printFn(`Command "${command}" completed with ${exitDescription}.`); - printFn(`Process output: -${logOutput}`); - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({ stdout, stderr, status }); - } else { - reject(outputMode === "silent" ? logOutput : void 0); - } - }); - }); + const env3 = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(command, options, _exec(command, { ...options, env: env3 })); } }; function statusFromExitCodeAndSignal(exitCode, signal) { @@ -53536,6 +53463,42 @@ function getEnvironmentForNonInteractiveCommand(userProvidedEnv) { const forceColorValue = supports_color_default2.stdout !== false ? supports_color_default2.stdout.level.toString() : void 0; return { FORCE_COLOR: forceColorValue, ...userProvidedEnv ?? process.env }; } +function processAsyncCmd(command, options, childProcess) { + return new Promise((resolve, reject) => { + var _a2, _b; + let logOutput = ""; + let stdout = ""; + let stderr = ""; + Log.debug(`Executing command: ${command}`); + (_a2 = childProcess.stderr) == null ? void 0 : _a2.on("data", (message) => { + stderr += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + (_b = childProcess.stdout) == null ? void 0 : _b.on("data", (message) => { + stdout += message; + logOutput += message; + if (options.mode === void 0 || options.mode === "enabled") { + process.stderr.write(message); + } + }); + childProcess.on("close", (exitCode, signal) => { + const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; + const printFn = options.mode === "on-error" ? Log.error : Log.debug; + const status = statusFromExitCodeAndSignal(exitCode, signal); + printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Process output: +${logOutput}`); + if (status === 0 || options.suppressErrorOnFailingExitCode) { + resolve({ stdout, stderr, status }); + } else { + reject(options.mode === "silent" ? logOutput : void 0); + } + }); + }); +} // function determineRepoBaseDirFromCwd() { diff --git a/ng-dev/utils/child-process.ts b/ng-dev/utils/child-process.ts index 778a35207..2e781e30b 100644 --- a/ng-dev/utils/child-process.ts +++ b/ng-dev/utils/child-process.ts @@ -17,33 +17,30 @@ import { } from 'child_process'; import {Log} from './logging.js'; -/** Interface describing the options for spawning a process synchronously. */ -export interface SpawnSyncOptions extends Omit<_SpawnSyncOptions, 'shell' | 'stdio'> { +export interface CommonCmdOpts { + /** Console output mode. Defaults to "enabled". */ + mode?: 'enabled' | 'silent' | 'on-error'; /** Whether to prevent exit codes being treated as failures. */ suppressErrorOnFailingExitCode?: boolean; } +/** Interface describing the options for spawning a process synchronously. */ +export interface SpawnSyncOptions + extends CommonCmdOpts, + Omit<_SpawnSyncOptions, 'shell' | 'stdio'> {} + /** Interface describing the options for spawning a process. */ -export interface SpawnOptions extends Omit<_SpawnOptions, 'shell' | 'stdio'> { - /** Console output mode. Defaults to "enabled". */ - mode?: 'enabled' | 'silent' | 'on-error'; - /** Whether to prevent exit codes being treated as failures. */ - suppressErrorOnFailingExitCode?: boolean; +export interface SpawnOptions extends CommonCmdOpts, Omit<_SpawnOptions, 'shell' | 'stdio'> { // Stdin text to provide to the process. The raw text will be written to `stdin` and then // the stream is closed. This is equivalent to the `input` option from `SpawnSyncOption`. input?: string; } /** Interface describing the options for exec-ing a process. */ -export interface ExecOptions extends Omit<_ExecOptions, 'shell' | 'stdio'> { - /** Console output mode. Defaults to "enabled". */ - mode?: 'enabled' | 'silent' | 'on-error'; - /** Whether to prevent exit codes being treated as failures. */ - suppressErrorOnFailingExitCode?: boolean; -} +export interface ExecOptions extends CommonCmdOpts, Omit<_ExecOptions, 'shell' | 'stdio'> {} /** Interface describing the options for spawning an interactive process. */ -export type SpawnInteractiveCommandOptions = Omit<_SpawnOptions, 'shell' | 'stdio'>; +export interface SpawnInteractiveCommandOptions extends Omit<_SpawnOptions, 'shell' | 'stdio'> {} /** Interface describing the result of a spawned process. */ export interface SpawnResult { @@ -55,6 +52,9 @@ export interface SpawnResult { status: number | NodeJS.Signals; } +/** Interface describing the result of an exec process. */ +export type ExecResult = SpawnResult; + /** Class holding utilities for spawning child processes. */ export abstract class ChildProcess { /** @@ -79,78 +79,6 @@ export abstract class ChildProcess { }); } - /** - * Spawns a given command with the specified arguments inside a shell. All process stdout - * output is captured and returned as resolution on completion. Depending on the chosen - * output mode, stdout/stderr output is also printed to the console, or only on error. - * - * @returns a Promise resolving with captured stdout and stderr on success. The promise - * rejects on command failure. - */ - static spawn(command: string, args: string[], options: SpawnOptions = {}): Promise { - return new Promise((resolve, reject) => { - const commandText = `${command} ${args.join(' ')}`; - const outputMode = options.mode; - const env = getEnvironmentForNonInteractiveCommand(options.env); - - Log.debug(`Executing command: ${commandText}`); - - const childProcess = _spawn(command, args, {...options, env, shell: true, stdio: 'pipe'}); - let logOutput = ''; - let stdout = ''; - let stderr = ''; - - // If provided, write `input` text to the process `stdin`. - if (options.input !== undefined) { - childProcess.stdin.write(options.input); - childProcess.stdin.end(); - } - - // Capture the stdout separately so that it can be passed as resolve value. - // This is useful if commands return parsable stdout. - childProcess.stderr.on('data', (message) => { - stderr += message; - logOutput += message; - // If console output is enabled, print the message directly to the stderr. Note that - // we intentionally print all output to stderr as stdout should not be polluted. - if (outputMode === undefined || outputMode === 'enabled') { - process.stderr.write(message); - } - }); - - childProcess.stdout.on('data', (message) => { - stdout += message; - logOutput += message; - // If console output is enabled, print the message directly to the stderr. Note that - // we intentionally print all output to stderr as stdout should not be polluted. - if (outputMode === undefined || outputMode === 'enabled') { - process.stderr.write(message); - } - }); - - // The `close` event is used because the process is guaranteed to have completed writing to - // stdout and stderr, using the `exit` event can cause inconsistent information in stdout and - // stderr due to a race condition around exiting. - childProcess.on('close', (exitCode, signal) => { - const exitDescription = - exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === 'on-error' ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); - - printFn(`Command "${commandText}" completed with ${exitDescription}.`); - printFn(`Process output: \n${logOutput}`); - - // On success, resolve the promise. Otherwise reject with the captured stderr - // and stdout log output if the output mode was set to `silent`. - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({stdout, stderr, status}); - } else { - reject(outputMode === 'silent' ? logOutput : undefined); - } - }); - }); - } - /** * Spawns a given command with the specified arguments inside a shell synchronously. * @@ -179,63 +107,39 @@ export abstract class ChildProcess { throw new Error(stderr); } - static exec(command: string, options: ExecOptions = {}) { - return new Promise((resolve, reject) => { - const outputMode = options.mode; - const env = getEnvironmentForNonInteractiveCommand(options.env); - - Log.debug(`Executing command: ${command}`); - - const childProcess = _exec(command, {...options, env}); - let logOutput = ''; - let stdout = ''; - let stderr = ''; - - // Capture the stdout separately so that it can be passed as resolve value. - // This is useful if commands return parsable stdout. - childProcess.stderr?.on('data', (message) => { - stderr += message; - logOutput += message; - // If console output is enabled, print the message directly to the stderr. Note that - // we intentionally print all output to stderr as stdout should not be polluted. - if (outputMode === undefined || outputMode === 'enabled') { - process.stderr.write(message); - } - }); - - childProcess.stdout?.on('data', (message) => { - stdout += message; - logOutput += message; - // If console output is enabled, print the message directly to the stderr. Note that - // we intentionally print all output to stderr as stdout should not be polluted. - if (outputMode === undefined || outputMode === 'enabled') { - process.stderr.write(message); - } - }); - - // The `close` event is used because the process is guaranteed to have completed writing to - // stdout and stderr, using the `exit` event can cause inconsistent information in stdout and - // stderr due to a race condition around exiting. - childProcess.on('close', (exitCode, signal) => { - const exitDescription = - exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; - const printFn = outputMode === 'on-error' ? Log.error : Log.debug; - const status = statusFromExitCodeAndSignal(exitCode, signal); + /** + * Spawns a given command with the specified arguments inside a shell. All process stdout + * output is captured and returned as resolution on completion. Depending on the chosen + * output mode, stdout/stderr output is also printed to the console, or only on error. + * + * @returns a Promise resolving with captured stdout and stderr on success. The promise + * rejects on command failure. + */ + static spawn(command: string, args: string[], options: SpawnOptions = {}): Promise { + const commandText = `${command} ${args.join(' ')}`; + const env = getEnvironmentForNonInteractiveCommand(options.env); - printFn(`Command "${command}" completed with ${exitDescription}.`); - printFn(`Process output: \n${logOutput}`); + return processAsyncCmd( + commandText, + options, + _spawn(command, args, {...options, env, shell: true, stdio: 'pipe'}), + ); + } - // On success, resolve the promise. Otherwise reject with the captured stderr - // and stdout log output if the output mode was set to `silent`. - if (status === 0 || options.suppressErrorOnFailingExitCode) { - resolve({stdout, stderr, status}); - } else { - reject(outputMode === 'silent' ? logOutput : undefined); - } - }); - }); + /** + * Execs a given command with the specified arguments inside a shell. All process stdout + * output is captured and returned as resolution on completion. Depending on the chosen + * output mode, stdout/stderr output is also printed to the console, or only on error. + * + * @returns a Promise resolving with captured stdout and stderr on success. The promise + * rejects on command failure. + */ + static exec(command: string, options: ExecOptions = {}): Promise { + const env = getEnvironmentForNonInteractiveCommand(options.env); + return processAsyncCmd(command, options, _exec(command, {...options, env})); } } + /** * Convert the provided exitCode and signal to a single status code. * @@ -264,3 +168,72 @@ function getEnvironmentForNonInteractiveCommand( return {FORCE_COLOR: forceColorValue, ...(userProvidedEnv ?? process.env)}; } + +/** + * Process the ChildProcess object created by an async command. + */ +function processAsyncCmd( + cmd: string, + opts: CommonCmdOpts, + childProcess: ReturnType, +): Promise; +function processAsyncCmd( + cmd: string, + opts: CommonCmdOpts, + childProcess: ReturnType, +): Promise; +function processAsyncCmd( + command: string, + options: CommonCmdOpts, + childProcess: ReturnType, +) { + return new Promise((resolve, reject) => { + let logOutput = ''; + let stdout = ''; + let stderr = ''; + + Log.debug(`Executing command: ${command}`); + + // Capture the stdout separately so that it can be passed as resolve value. + // This is useful if commands return parsable stdout. + childProcess.stderr?.on('data', (message) => { + stderr += message; + logOutput += message; + // If console output is enabled, print the message directly to the stderr. Note that + // we intentionally print all output to stderr as stdout should not be polluted. + if (options.mode === undefined || options.mode === 'enabled') { + process.stderr.write(message); + } + }); + + childProcess.stdout?.on('data', (message) => { + stdout += message; + logOutput += message; + // If console output is enabled, print the message directly to the stderr. Note that + // we intentionally print all output to stderr as stdout should not be polluted. + if (options.mode === undefined || options.mode === 'enabled') { + process.stderr.write(message); + } + }); + + // The `close` event is used because the process is guaranteed to have completed writing to + // stdout and stderr, using the `exit` event can cause inconsistent information in stdout and + // stderr due to a race condition around exiting. + childProcess.on('close', (exitCode, signal) => { + const exitDescription = exitCode !== null ? `exit code "${exitCode}"` : `signal "${signal}"`; + const printFn = options.mode === 'on-error' ? Log.error : Log.debug; + const status = statusFromExitCodeAndSignal(exitCode, signal); + + printFn(`Command "${command}" completed with ${exitDescription}.`); + printFn(`Process output: \n${logOutput}`); + + // On success, resolve the promise. Otherwise reject with the captured stderr + // and stdout log output if the output mode was set to `silent`. + if (status === 0 || options.suppressErrorOnFailingExitCode) { + resolve({stdout, stderr, status}); + } else { + reject(options.mode === 'silent' ? logOutput : undefined); + } + }); + }); +}