| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 | 
							- 'use strict';
 
- const path = require('path');
 
- const childProcess = require('child_process');
 
- const crossSpawn = require('cross-spawn');
 
- const stripFinalNewline = require('strip-final-newline');
 
- const npmRunPath = require('npm-run-path');
 
- const onetime = require('onetime');
 
- const makeError = require('./lib/error');
 
- const normalizeStdio = require('./lib/stdio');
 
- const {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} = require('./lib/kill');
 
- const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = require('./lib/stream');
 
- const {mergePromise, getSpawnedPromise} = require('./lib/promise');
 
- const {joinCommand, parseCommand, getEscapedCommand} = require('./lib/command');
 
- const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100;
 
- const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => {
 
- 	const env = extendEnv ? {...process.env, ...envOption} : envOption;
 
- 	if (preferLocal) {
 
- 		return npmRunPath.env({env, cwd: localDir, execPath});
 
- 	}
 
- 	return env;
 
- };
 
- const handleArguments = (file, args, options = {}) => {
 
- 	const parsed = crossSpawn._parse(file, args, options);
 
- 	file = parsed.command;
 
- 	args = parsed.args;
 
- 	options = parsed.options;
 
- 	options = {
 
- 		maxBuffer: DEFAULT_MAX_BUFFER,
 
- 		buffer: true,
 
- 		stripFinalNewline: true,
 
- 		extendEnv: true,
 
- 		preferLocal: false,
 
- 		localDir: options.cwd || process.cwd(),
 
- 		execPath: process.execPath,
 
- 		encoding: 'utf8',
 
- 		reject: true,
 
- 		cleanup: true,
 
- 		all: false,
 
- 		windowsHide: true,
 
- 		...options
 
- 	};
 
- 	options.env = getEnv(options);
 
- 	options.stdio = normalizeStdio(options);
 
- 	if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') {
 
- 		// #116
 
- 		args.unshift('/q');
 
- 	}
 
- 	return {file, args, options, parsed};
 
- };
 
- const handleOutput = (options, value, error) => {
 
- 	if (typeof value !== 'string' && !Buffer.isBuffer(value)) {
 
- 		// When `execa.sync()` errors, we normalize it to '' to mimic `execa()`
 
- 		return error === undefined ? undefined : '';
 
- 	}
 
- 	if (options.stripFinalNewline) {
 
- 		return stripFinalNewline(value);
 
- 	}
 
- 	return value;
 
- };
 
- const execa = (file, args, options) => {
 
- 	const parsed = handleArguments(file, args, options);
 
- 	const command = joinCommand(file, args);
 
- 	const escapedCommand = getEscapedCommand(file, args);
 
- 	validateTimeout(parsed.options);
 
- 	let spawned;
 
- 	try {
 
- 		spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options);
 
- 	} catch (error) {
 
- 		// Ensure the returned error is always both a promise and a child process
 
- 		const dummySpawned = new childProcess.ChildProcess();
 
- 		const errorPromise = Promise.reject(makeError({
 
- 			error,
 
- 			stdout: '',
 
- 			stderr: '',
 
- 			all: '',
 
- 			command,
 
- 			escapedCommand,
 
- 			parsed,
 
- 			timedOut: false,
 
- 			isCanceled: false,
 
- 			killed: false
 
- 		}));
 
- 		return mergePromise(dummySpawned, errorPromise);
 
- 	}
 
- 	const spawnedPromise = getSpawnedPromise(spawned);
 
- 	const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise);
 
- 	const processDone = setExitHandler(spawned, parsed.options, timedPromise);
 
- 	const context = {isCanceled: false};
 
- 	spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned));
 
- 	spawned.cancel = spawnedCancel.bind(null, spawned, context);
 
- 	const handlePromise = async () => {
 
- 		const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone);
 
- 		const stdout = handleOutput(parsed.options, stdoutResult);
 
- 		const stderr = handleOutput(parsed.options, stderrResult);
 
- 		const all = handleOutput(parsed.options, allResult);
 
- 		if (error || exitCode !== 0 || signal !== null) {
 
- 			const returnedError = makeError({
 
- 				error,
 
- 				exitCode,
 
- 				signal,
 
- 				stdout,
 
- 				stderr,
 
- 				all,
 
- 				command,
 
- 				escapedCommand,
 
- 				parsed,
 
- 				timedOut,
 
- 				isCanceled: context.isCanceled,
 
- 				killed: spawned.killed
 
- 			});
 
- 			if (!parsed.options.reject) {
 
- 				return returnedError;
 
- 			}
 
- 			throw returnedError;
 
- 		}
 
- 		return {
 
- 			command,
 
- 			escapedCommand,
 
- 			exitCode: 0,
 
- 			stdout,
 
- 			stderr,
 
- 			all,
 
- 			failed: false,
 
- 			timedOut: false,
 
- 			isCanceled: false,
 
- 			killed: false
 
- 		};
 
- 	};
 
- 	const handlePromiseOnce = onetime(handlePromise);
 
- 	handleInput(spawned, parsed.options.input);
 
- 	spawned.all = makeAllStream(spawned, parsed.options);
 
- 	return mergePromise(spawned, handlePromiseOnce);
 
- };
 
- module.exports = execa;
 
- module.exports.sync = (file, args, options) => {
 
- 	const parsed = handleArguments(file, args, options);
 
- 	const command = joinCommand(file, args);
 
- 	const escapedCommand = getEscapedCommand(file, args);
 
- 	validateInputSync(parsed.options);
 
- 	let result;
 
- 	try {
 
- 		result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options);
 
- 	} catch (error) {
 
- 		throw makeError({
 
- 			error,
 
- 			stdout: '',
 
- 			stderr: '',
 
- 			all: '',
 
- 			command,
 
- 			escapedCommand,
 
- 			parsed,
 
- 			timedOut: false,
 
- 			isCanceled: false,
 
- 			killed: false
 
- 		});
 
- 	}
 
- 	const stdout = handleOutput(parsed.options, result.stdout, result.error);
 
- 	const stderr = handleOutput(parsed.options, result.stderr, result.error);
 
- 	if (result.error || result.status !== 0 || result.signal !== null) {
 
- 		const error = makeError({
 
- 			stdout,
 
- 			stderr,
 
- 			error: result.error,
 
- 			signal: result.signal,
 
- 			exitCode: result.status,
 
- 			command,
 
- 			escapedCommand,
 
- 			parsed,
 
- 			timedOut: result.error && result.error.code === 'ETIMEDOUT',
 
- 			isCanceled: false,
 
- 			killed: result.signal !== null
 
- 		});
 
- 		if (!parsed.options.reject) {
 
- 			return error;
 
- 		}
 
- 		throw error;
 
- 	}
 
- 	return {
 
- 		command,
 
- 		escapedCommand,
 
- 		exitCode: 0,
 
- 		stdout,
 
- 		stderr,
 
- 		failed: false,
 
- 		timedOut: false,
 
- 		isCanceled: false,
 
- 		killed: false
 
- 	};
 
- };
 
- module.exports.command = (command, options) => {
 
- 	const [file, ...args] = parseCommand(command);
 
- 	return execa(file, args, options);
 
- };
 
- module.exports.commandSync = (command, options) => {
 
- 	const [file, ...args] = parseCommand(command);
 
- 	return execa.sync(file, args, options);
 
- };
 
- module.exports.node = (scriptPath, args, options = {}) => {
 
- 	if (args && !Array.isArray(args) && typeof args === 'object') {
 
- 		options = args;
 
- 		args = [];
 
- 	}
 
- 	const stdio = normalizeStdio.node(options);
 
- 	const defaultExecArgv = process.execArgv.filter(arg => !arg.startsWith('--inspect'));
 
- 	const {
 
- 		nodePath = process.execPath,
 
- 		nodeOptions = defaultExecArgv
 
- 	} = options;
 
- 	return execa(
 
- 		nodePath,
 
- 		[
 
- 			...nodeOptions,
 
- 			scriptPath,
 
- 			...(Array.isArray(args) ? args : [])
 
- 		],
 
- 		{
 
- 			...options,
 
- 			stdin: undefined,
 
- 			stdout: undefined,
 
- 			stderr: undefined,
 
- 			stdio,
 
- 			shell: false
 
- 		}
 
- 	);
 
- };
 
 
  |