-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
98 lines (78 loc) · 2.58 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'use strict';
const crossSpawn = require('cross-spawn');
const spawn = require('child_process').spawn;
function execute(command, args, options) {
let cp;
options = Object.assign({ crossSpawn: true }, options);
const promise = new Promise((resolve, reject) => {
let stderr = new Buffer('');
let stdout = new Buffer('');
// Buffer output, reporting progress
// Use cross or node's spawn according to options.crossSpawn
cp = options.crossSpawn ? crossSpawn(command, args, options) : spawn(command, args, options);
delete options.crossSpawn;
if (cp.stdout) {
cp.stdout.on('data', (data) => {
stdout = Buffer.concat([stdout, data]);
});
}
if (cp.stderr) {
cp.stderr.on('data', (data) => {
stderr = Buffer.concat([stderr, data]);
});
}
// If there is an error spawning the command, reject the promise
cp.on('error', reject);
// Listen to the close event instead of exit
// They are similar but close ensures that streams are flushed
cp.on('close', (code) => {
stdout = stdout.toString();
stderr = stderr.toString();
if (!code) {
return resolve({ stdout, stderr });
}
// Generate the full command to be presented in the error message
args = args || [];
const fullCommand = command + (args.length ? ` ${args.join(' ')}` : '');
// Build the error instance
reject(Object.assign(new Error(`Failed to execute "${fullCommand}", exit code of #${code}`), 'ECMDERR', {
code: 'ECMDERR',
stderr,
stdout,
details: stderr,
status: code,
}));
});
});
promise.cp = cp;
return promise;
}
function buffered(command, args, options, callback) {
if (typeof options === 'function') {
callback = options;
options = null;
}
if (typeof args === 'function') {
callback = args;
args = options = null;
}
if (args && !Array.isArray(args)) {
options = args;
args = null;
}
const promise = execute(command, args, options);
if (!callback) {
return promise;
}
promise
.then((output) => {
callback(null, output.stdout, output.stderr);
}, callback)
.then(null, (err) => {
setTimeout(() => {
throw err;
}, 1);
});
return promise.cp;
}
module.exports = buffered;