source: frontend/node_modules/execa/index.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[9af201e]1'use strict';
2const path = require('path');
3const childProcess = require('child_process');
4const crossSpawn = require('cross-spawn');
5const stripFinalNewline = require('strip-final-newline');
6const npmRunPath = require('npm-run-path');
7const onetime = require('onetime');
8const makeError = require('./lib/error');
9const normalizeStdio = require('./lib/stdio');
10const {spawnedKill, spawnedCancel, setupTimeout, validateTimeout, setExitHandler} = require('./lib/kill');
11const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = require('./lib/stream');
12const {mergePromise, getSpawnedPromise} = require('./lib/promise');
13const {joinCommand, parseCommand, getEscapedCommand} = require('./lib/command');
14
15const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100;
16
17const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => {
18 const env = extendEnv ? {...process.env, ...envOption} : envOption;
19
20 if (preferLocal) {
21 return npmRunPath.env({env, cwd: localDir, execPath});
22 }
23
24 return env;
25};
26
27const handleArguments = (file, args, options = {}) => {
28 const parsed = crossSpawn._parse(file, args, options);
29 file = parsed.command;
30 args = parsed.args;
31 options = parsed.options;
32
33 options = {
34 maxBuffer: DEFAULT_MAX_BUFFER,
35 buffer: true,
36 stripFinalNewline: true,
37 extendEnv: true,
38 preferLocal: false,
39 localDir: options.cwd || process.cwd(),
40 execPath: process.execPath,
41 encoding: 'utf8',
42 reject: true,
43 cleanup: true,
44 all: false,
45 windowsHide: true,
46 ...options
47 };
48
49 options.env = getEnv(options);
50
51 options.stdio = normalizeStdio(options);
52
53 if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') {
54 // #116
55 args.unshift('/q');
56 }
57
58 return {file, args, options, parsed};
59};
60
61const handleOutput = (options, value, error) => {
62 if (typeof value !== 'string' && !Buffer.isBuffer(value)) {
63 // When `execa.sync()` errors, we normalize it to '' to mimic `execa()`
64 return error === undefined ? undefined : '';
65 }
66
67 if (options.stripFinalNewline) {
68 return stripFinalNewline(value);
69 }
70
71 return value;
72};
73
74const execa = (file, args, options) => {
75 const parsed = handleArguments(file, args, options);
76 const command = joinCommand(file, args);
77 const escapedCommand = getEscapedCommand(file, args);
78
79 validateTimeout(parsed.options);
80
81 let spawned;
82 try {
83 spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options);
84 } catch (error) {
85 // Ensure the returned error is always both a promise and a child process
86 const dummySpawned = new childProcess.ChildProcess();
87 const errorPromise = Promise.reject(makeError({
88 error,
89 stdout: '',
90 stderr: '',
91 all: '',
92 command,
93 escapedCommand,
94 parsed,
95 timedOut: false,
96 isCanceled: false,
97 killed: false
98 }));
99 return mergePromise(dummySpawned, errorPromise);
100 }
101
102 const spawnedPromise = getSpawnedPromise(spawned);
103 const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise);
104 const processDone = setExitHandler(spawned, parsed.options, timedPromise);
105
106 const context = {isCanceled: false};
107
108 spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned));
109 spawned.cancel = spawnedCancel.bind(null, spawned, context);
110
111 const handlePromise = async () => {
112 const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone);
113 const stdout = handleOutput(parsed.options, stdoutResult);
114 const stderr = handleOutput(parsed.options, stderrResult);
115 const all = handleOutput(parsed.options, allResult);
116
117 if (error || exitCode !== 0 || signal !== null) {
118 const returnedError = makeError({
119 error,
120 exitCode,
121 signal,
122 stdout,
123 stderr,
124 all,
125 command,
126 escapedCommand,
127 parsed,
128 timedOut,
129 isCanceled: context.isCanceled,
130 killed: spawned.killed
131 });
132
133 if (!parsed.options.reject) {
134 return returnedError;
135 }
136
137 throw returnedError;
138 }
139
140 return {
141 command,
142 escapedCommand,
143 exitCode: 0,
144 stdout,
145 stderr,
146 all,
147 failed: false,
148 timedOut: false,
149 isCanceled: false,
150 killed: false
151 };
152 };
153
154 const handlePromiseOnce = onetime(handlePromise);
155
156 handleInput(spawned, parsed.options.input);
157
158 spawned.all = makeAllStream(spawned, parsed.options);
159
160 return mergePromise(spawned, handlePromiseOnce);
161};
162
163module.exports = execa;
164
165module.exports.sync = (file, args, options) => {
166 const parsed = handleArguments(file, args, options);
167 const command = joinCommand(file, args);
168 const escapedCommand = getEscapedCommand(file, args);
169
170 validateInputSync(parsed.options);
171
172 let result;
173 try {
174 result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options);
175 } catch (error) {
176 throw makeError({
177 error,
178 stdout: '',
179 stderr: '',
180 all: '',
181 command,
182 escapedCommand,
183 parsed,
184 timedOut: false,
185 isCanceled: false,
186 killed: false
187 });
188 }
189
190 const stdout = handleOutput(parsed.options, result.stdout, result.error);
191 const stderr = handleOutput(parsed.options, result.stderr, result.error);
192
193 if (result.error || result.status !== 0 || result.signal !== null) {
194 const error = makeError({
195 stdout,
196 stderr,
197 error: result.error,
198 signal: result.signal,
199 exitCode: result.status,
200 command,
201 escapedCommand,
202 parsed,
203 timedOut: result.error && result.error.code === 'ETIMEDOUT',
204 isCanceled: false,
205 killed: result.signal !== null
206 });
207
208 if (!parsed.options.reject) {
209 return error;
210 }
211
212 throw error;
213 }
214
215 return {
216 command,
217 escapedCommand,
218 exitCode: 0,
219 stdout,
220 stderr,
221 failed: false,
222 timedOut: false,
223 isCanceled: false,
224 killed: false
225 };
226};
227
228module.exports.command = (command, options) => {
229 const [file, ...args] = parseCommand(command);
230 return execa(file, args, options);
231};
232
233module.exports.commandSync = (command, options) => {
234 const [file, ...args] = parseCommand(command);
235 return execa.sync(file, args, options);
236};
237
238module.exports.node = (scriptPath, args, options = {}) => {
239 if (args && !Array.isArray(args) && typeof args === 'object') {
240 options = args;
241 args = [];
242 }
243
244 const stdio = normalizeStdio.node(options);
245 const defaultExecArgv = process.execArgv.filter(arg => !arg.startsWith('--inspect'));
246
247 const {
248 nodePath = process.execPath,
249 nodeOptions = defaultExecArgv
250 } = options;
251
252 return execa(
253 nodePath,
254 [
255 ...nodeOptions,
256 scriptPath,
257 ...(Array.isArray(args) ? args : [])
258 ],
259 {
260 ...options,
261 stdin: undefined,
262 stdout: undefined,
263 stderr: undefined,
264 stdio,
265 shell: false
266 }
267 );
268};
Note: See TracBrowser for help on using the repository browser.