123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import {spawnSync} from 'node:child_process';
- import {handleCommand} from '../arguments/command.js';
- import {normalizeOptions} from '../arguments/options.js';
- import {makeError, makeEarlyError, makeSuccessResult} from '../return/result.js';
- import {handleResult} from '../return/reject.js';
- import {handleStdioSync} from '../stdio/handle-sync.js';
- import {stripNewline} from '../io/strip-newline.js';
- import {addInputOptionsSync} from '../io/input-sync.js';
- import {transformOutputSync} from '../io/output-sync.js';
- import {getMaxBufferSync} from '../io/max-buffer.js';
- import {getAllSync} from '../resolve/all-sync.js';
- import {getExitResultSync} from '../resolve/exit-sync.js';
- // Main shared logic for all sync methods: `execaSync()`, `$.sync()`
- export const execaCoreSync = (rawFile, rawArguments, rawOptions) => {
- const {file, commandArguments, command, escapedCommand, startTime, verboseInfo, options, fileDescriptors} = handleSyncArguments(rawFile, rawArguments, rawOptions);
- const result = spawnSubprocessSync({
- file,
- commandArguments,
- options,
- command,
- escapedCommand,
- verboseInfo,
- fileDescriptors,
- startTime,
- });
- return handleResult(result, verboseInfo, options);
- };
- // Compute arguments to pass to `child_process.spawnSync()`
- const handleSyncArguments = (rawFile, rawArguments, rawOptions) => {
- const {command, escapedCommand, startTime, verboseInfo} = handleCommand(rawFile, rawArguments, rawOptions);
- const syncOptions = normalizeSyncOptions(rawOptions);
- const {file, commandArguments, options} = normalizeOptions(rawFile, rawArguments, syncOptions);
- validateSyncOptions(options);
- const fileDescriptors = handleStdioSync(options, verboseInfo);
- return {
- file,
- commandArguments,
- command,
- escapedCommand,
- startTime,
- verboseInfo,
- options,
- fileDescriptors,
- };
- };
- // Options normalization logic specific to sync methods
- const normalizeSyncOptions = options => options.node && !options.ipc ? {...options, ipc: false} : options;
- // Options validation logic specific to sync methods
- const validateSyncOptions = ({ipc, ipcInput, detached, cancelSignal}) => {
- if (ipcInput) {
- throwInvalidSyncOption('ipcInput');
- }
- if (ipc) {
- throwInvalidSyncOption('ipc: true');
- }
- if (detached) {
- throwInvalidSyncOption('detached: true');
- }
- if (cancelSignal) {
- throwInvalidSyncOption('cancelSignal');
- }
- };
- const throwInvalidSyncOption = value => {
- throw new TypeError(`The "${value}" option cannot be used with synchronous methods.`);
- };
- const spawnSubprocessSync = ({file, commandArguments, options, command, escapedCommand, verboseInfo, fileDescriptors, startTime}) => {
- const syncResult = runSubprocessSync({
- file,
- commandArguments,
- options,
- command,
- escapedCommand,
- fileDescriptors,
- startTime,
- });
- if (syncResult.failed) {
- return syncResult;
- }
- const {resultError, exitCode, signal, timedOut, isMaxBuffer} = getExitResultSync(syncResult, options);
- const {output, error = resultError} = transformOutputSync({
- fileDescriptors,
- syncResult,
- options,
- isMaxBuffer,
- verboseInfo,
- });
- const stdio = output.map((stdioOutput, fdNumber) => stripNewline(stdioOutput, options, fdNumber));
- const all = stripNewline(getAllSync(output, options), options, 'all');
- return getSyncResult({
- error,
- exitCode,
- signal,
- timedOut,
- isMaxBuffer,
- stdio,
- all,
- options,
- command,
- escapedCommand,
- startTime,
- });
- };
- const runSubprocessSync = ({file, commandArguments, options, command, escapedCommand, fileDescriptors, startTime}) => {
- try {
- addInputOptionsSync(fileDescriptors, options);
- const normalizedOptions = normalizeSpawnSyncOptions(options);
- return spawnSync(file, commandArguments, normalizedOptions);
- } catch (error) {
- return makeEarlyError({
- error,
- command,
- escapedCommand,
- fileDescriptors,
- options,
- startTime,
- isSync: true,
- });
- }
- };
- // The `encoding` option is handled by Execa, not by `child_process.spawnSync()`
- const normalizeSpawnSyncOptions = ({encoding, maxBuffer, ...options}) => ({...options, encoding: 'buffer', maxBuffer: getMaxBufferSync(maxBuffer)});
- const getSyncResult = ({error, exitCode, signal, timedOut, isMaxBuffer, stdio, all, options, command, escapedCommand, startTime}) => error === undefined
- ? makeSuccessResult({
- command,
- escapedCommand,
- stdio,
- all,
- ipcOutput: [],
- options,
- startTime,
- })
- : makeError({
- error,
- command,
- escapedCommand,
- timedOut,
- isCanceled: false,
- isGracefullyCanceled: false,
- isMaxBuffer,
- isForcefullyTerminated: false,
- exitCode,
- signal,
- stdio,
- all,
- ipcOutput: [],
- options,
- startTime,
- isSync: true,
- });
|