concurrently 3.6.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +3 -4
- package/.vscode/settings.json +5 -0
- package/CONTRIBUTING.md +1 -4
- package/README.md +131 -94
- package/appveyor.yml +1 -1
- package/bin/concurrently.js +164 -0
- package/bin/concurrently.spec.js +340 -0
- package/bin/epilogue.txt +46 -0
- package/{test/support → bin/fixtures}/read-echo.js +0 -2
- package/index.js +56 -0
- package/package.json +28 -31
- package/src/command-parser/expand-npm-shortcut.js +13 -0
- package/src/command-parser/expand-npm-shortcut.spec.js +36 -0
- package/src/command-parser/expand-npm-wildcard.js +34 -0
- package/src/command-parser/expand-npm-wildcard.spec.js +58 -0
- package/src/command-parser/strip-quotes.js +12 -0
- package/src/command-parser/strip-quotes.spec.js +14 -0
- package/src/command.js +50 -0
- package/src/command.spec.js +142 -0
- package/src/completion-listener.js +35 -0
- package/src/completion-listener.spec.js +88 -0
- package/src/concurrently.js +69 -0
- package/src/concurrently.spec.js +77 -0
- package/src/defaults.js +27 -0
- package/src/flow-control/fixtures/fake-command.js +16 -0
- package/src/flow-control/input-handler.js +39 -0
- package/src/flow-control/input-handler.spec.js +79 -0
- package/src/flow-control/kill-on-signal.js +29 -0
- package/src/flow-control/kill-on-signal.spec.js +70 -0
- package/src/flow-control/kill-others.js +35 -0
- package/src/flow-control/kill-others.spec.js +66 -0
- package/src/flow-control/log-error.js +20 -0
- package/src/flow-control/log-error.spec.js +40 -0
- package/src/flow-control/log-exit.js +13 -0
- package/src/flow-control/log-exit.spec.js +36 -0
- package/src/flow-control/log-output.js +14 -0
- package/src/flow-control/log-output.spec.js +41 -0
- package/src/flow-control/restart-process.js +51 -0
- package/src/flow-control/restart-process.spec.js +129 -0
- package/src/get-spawn-opts.js +12 -0
- package/src/get-spawn-opts.spec.js +18 -0
- package/src/logger.js +109 -0
- package/src/logger.spec.js +178 -0
- package/src/findChild.js +0 -11
- package/src/main.js +0 -563
- package/src/parseCmds.js +0 -65
- package/src/pkgInfo.js +0 -17
- package/test/support/signal.js +0 -13
- package/test/test-findChild.js +0 -39
- package/test/test-functional.js +0 -396
- package/test/test-parseCmds.js +0 -204
- package/test/utils.js +0 -68
package/test/test-functional.js
DELETED
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
// Test basic usage of cli
|
|
3
|
-
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const assert = require('assert');
|
|
6
|
-
const run = require('./utils').run;
|
|
7
|
-
const IS_WINDOWS = /^win/.test(process.platform);
|
|
8
|
-
|
|
9
|
-
// Note: Set the DEBUG_TESTS environment variable to `true` to see output of test commands.
|
|
10
|
-
|
|
11
|
-
const TEST_DIR = 'dir/';
|
|
12
|
-
|
|
13
|
-
// Abs path to test directory
|
|
14
|
-
const testDir = path.resolve(__dirname);
|
|
15
|
-
process.chdir(path.join(testDir, '..'));
|
|
16
|
-
|
|
17
|
-
describe('concurrently', function() {
|
|
18
|
-
this.timeout(5000);
|
|
19
|
-
|
|
20
|
-
it('help should be successful', () => {
|
|
21
|
-
return run('node ./src/main.js --help')
|
|
22
|
-
.then(function(exitCode) {
|
|
23
|
-
// exit code 0 means success
|
|
24
|
-
assert.strictEqual(exitCode, 0);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('version should be successful', () => {
|
|
29
|
-
return run('node ./src/main.js -V')
|
|
30
|
-
.then(function(exitCode) {
|
|
31
|
-
assert.strictEqual(exitCode, 0);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('two successful commands should exit 0', () => {
|
|
36
|
-
return run('node ./src/main.js "echo test" "echo test"')
|
|
37
|
-
.then(function(exitCode) {
|
|
38
|
-
assert.strictEqual(exitCode, 0);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('at least one unsuccessful commands should exit non-zero', () => {
|
|
43
|
-
return run('node ./src/main.js "echo test" "nosuchcmd" "echo test"')
|
|
44
|
-
.then(function(exitCode) {
|
|
45
|
-
assert.notStrictEqual(exitCode, 0);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('--kill-others should kill other commands if one dies', () => {
|
|
50
|
-
return run('node ./src/main.js --kill-others "sleep 1" "echo test" "sleep 0.1 && nosuchcmd"')
|
|
51
|
-
.then(function(exitCode) {
|
|
52
|
-
assert.notStrictEqual(exitCode, 0);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('--kill-others-on-fail should kill other commands if one exits with non-zero status code', () => {
|
|
57
|
-
return run('node ./src/main.js --kill-others-on-fail "sleep 1" "exit 1" "sleep 1"')
|
|
58
|
-
.then(function(exitCode) {
|
|
59
|
-
assert.notStrictEqual(exitCode, 0);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('--kill-others-on-fail should NOT kill other commands if none of them exits with non-zero status code', (done) => {
|
|
64
|
-
const readline = require('readline');
|
|
65
|
-
let exits = 0;
|
|
66
|
-
let sigtermInOutput = false;
|
|
67
|
-
|
|
68
|
-
run('node ./src/main.js --kill-others-on-fail "echo killTest1" "echo killTest2" "echo killTest3"', {
|
|
69
|
-
onOutputLine: function(line) {
|
|
70
|
-
if (/SIGTERM/.test(line)) {
|
|
71
|
-
sigtermInOutput = true;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// waiting for exits
|
|
75
|
-
if (/killTest\d$/.test(line)) {
|
|
76
|
-
exits++;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}).then(function() {
|
|
80
|
-
if (sigtermInOutput) {
|
|
81
|
-
done(new Error('There was a "SIGTERM" in console output'));
|
|
82
|
-
} else if (exits !== 3) {
|
|
83
|
-
done(new Error('There was wrong number of echoes(' + exits + ') from executed commands'));
|
|
84
|
-
} else {
|
|
85
|
-
done();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('--success=first should return first exit code', () => {
|
|
91
|
-
return run('node ./src/main.js -k --success first "echo test" "sleep 0.1 && nosuchcmd"')
|
|
92
|
-
// When killed, sleep returns null exit code
|
|
93
|
-
.then(function(exitCode) {
|
|
94
|
-
assert.strictEqual(exitCode, 0);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('--success=last should return last exit code', () => {
|
|
99
|
-
// When killed, sleep returns null exit code
|
|
100
|
-
return run('node ./src/main.js -k --success last "echo test" "sleep 0.1 && nosuchcmd"')
|
|
101
|
-
.then(function(exitCode) {
|
|
102
|
-
assert.notStrictEqual(exitCode, 0);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('&& nosuchcmd should return non-zero exit code', () => {
|
|
107
|
-
return run('node ./src/main.js "echo 1 && nosuchcmd" "echo 1 && nosuchcmd" ')
|
|
108
|
-
.then(function(exitCode) {
|
|
109
|
-
assert.strictEqual(exitCode, 1);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('--prefix-colors should handle non-existent colors without failing', () => {
|
|
114
|
-
return run('node ./src/main.js -c "not.a.color" "echo colors"')
|
|
115
|
-
.then(function(exitCode) {
|
|
116
|
-
assert.strictEqual(exitCode, 0);
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('--prefix should default to "index"', () => {
|
|
121
|
-
const collectedLines = [];
|
|
122
|
-
|
|
123
|
-
return run('node ./src/main.js "echo one" "echo two"', {
|
|
124
|
-
onOutputLine: (line) => {
|
|
125
|
-
if (/(one|two)$/.exec(line)) {
|
|
126
|
-
collectedLines.push(line);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
})
|
|
130
|
-
.then(function(exitCode) {
|
|
131
|
-
assert.strictEqual(exitCode, 0);
|
|
132
|
-
|
|
133
|
-
collectedLines.sort();
|
|
134
|
-
assert.deepEqual(collectedLines, [
|
|
135
|
-
'[0] one',
|
|
136
|
-
'[1] two'
|
|
137
|
-
]);
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('--names should set a different default prefix', () => {
|
|
142
|
-
const collectedLines = [];
|
|
143
|
-
|
|
144
|
-
return run('node ./src/main.js -n aa,bb "echo one" "echo two"', {
|
|
145
|
-
onOutputLine: (line) => {
|
|
146
|
-
if (/(one|two)$/.exec(line)) {
|
|
147
|
-
collectedLines.push(line);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
})
|
|
151
|
-
.then(function(exitCode) {
|
|
152
|
-
assert.strictEqual(exitCode, 0);
|
|
153
|
-
|
|
154
|
-
collectedLines.sort();
|
|
155
|
-
assert.deepEqual(collectedLines, [
|
|
156
|
-
'[aa] one',
|
|
157
|
-
'[bb] two'
|
|
158
|
-
]);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('--allow-restart should restart a proccess with non-zero exit code', (done) => {
|
|
163
|
-
const readline = require('readline');
|
|
164
|
-
let exitedWithOne = false;
|
|
165
|
-
let restarted = false;
|
|
166
|
-
|
|
167
|
-
run('node ./src/main.js --allow-restart "sleep 0.1 && exit 1" "sleep 1"', {
|
|
168
|
-
pipe: false,
|
|
169
|
-
onOutputLine: (line) => {
|
|
170
|
-
const re = /exited with code (.+)/.exec(line);
|
|
171
|
-
if (re && re[1] === '1') {
|
|
172
|
-
exitedWithOne = true;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (/restarted/.test(line)) {
|
|
176
|
-
restarted = true;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}).then(function() {
|
|
180
|
-
if (exitedWithOne && restarted) {
|
|
181
|
-
done();
|
|
182
|
-
} else {
|
|
183
|
-
done(new Error('No restarted process exited with code 1'));
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('--restart-after=n should restart a proccess after n miliseconds', (done) => {
|
|
189
|
-
const readline = require('readline');
|
|
190
|
-
let start, end;
|
|
191
|
-
|
|
192
|
-
run('node ./src/main.js --allow-restart --restart-after 300 "exit 1" "sleep 1"', {
|
|
193
|
-
pipe: false,
|
|
194
|
-
onOutputLine: (line) => {
|
|
195
|
-
if (!start && /exited with code (.+)/.test(line)) {
|
|
196
|
-
start = new Date().getTime();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!end && /restarted/.test(line)) {
|
|
200
|
-
end = new Date().getTime();
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}).then(function() {
|
|
204
|
-
// we accept 100 miliseconds of error
|
|
205
|
-
if (end - start >= 300 && end - start < 400) {
|
|
206
|
-
done();
|
|
207
|
-
} else {
|
|
208
|
-
done(new Error('No restarted process after 300 miliseconds'));
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
it('--restart-tries=n should restart a proccess at most n times', (done) => {
|
|
213
|
-
const readline = require('readline');
|
|
214
|
-
let restartedTimes = 0;
|
|
215
|
-
|
|
216
|
-
run('node ./src/main.js --allow-restart --restart-tries 2 "exit 1" "sleep 1"', {
|
|
217
|
-
pipe: false,
|
|
218
|
-
onOutputLine: (line) => {
|
|
219
|
-
if (/restarted/.test(line)) {
|
|
220
|
-
restartedTimes++;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}).then(function() {
|
|
224
|
-
if (restartedTimes === 2) {
|
|
225
|
-
done();
|
|
226
|
-
} else {
|
|
227
|
-
done(new Error('No restarted process twice'));
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
['SIGINT', 'SIGTERM'].forEach((signal) => {
|
|
233
|
-
if (IS_WINDOWS) {
|
|
234
|
-
console.log('IS_WINDOWS=true');
|
|
235
|
-
console.log('Skipping SIGINT/SIGTERM propagation tests ..');
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
it('killing it with ' + signal + ' should propagate the signal to the children', function(done) {
|
|
240
|
-
const readline = require('readline');
|
|
241
|
-
let waitingStart = 2;
|
|
242
|
-
let waitingSignal = 2;
|
|
243
|
-
|
|
244
|
-
function waitForSignal(cb) {
|
|
245
|
-
if (waitingSignal) {
|
|
246
|
-
setTimeout(waitForSignal, 100);
|
|
247
|
-
} else {
|
|
248
|
-
cb();
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
run('node ./src/main.js "node ./test/support/signal.js" "node ./test/support/signal.js"', {
|
|
253
|
-
onOutputLine: function(line, child) {
|
|
254
|
-
// waiting for startup
|
|
255
|
-
if (/STARTED/.test(line)) {
|
|
256
|
-
waitingStart--;
|
|
257
|
-
}
|
|
258
|
-
if (!waitingStart) {
|
|
259
|
-
// both processes are started
|
|
260
|
-
child.kill(signal);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// waiting for signal
|
|
264
|
-
if (new RegExp(signal).test(line)) {
|
|
265
|
-
waitingSignal--;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}).then(function() {
|
|
269
|
-
waitForSignal(done);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it('sends input to default stdin target process', (done) => {
|
|
275
|
-
let echoed = false;
|
|
276
|
-
run('node ./src/main.js "node ./test/support/read-echo.js"', {
|
|
277
|
-
onOutputLine: (line, child) => {
|
|
278
|
-
if (/READING/.test(line)) {
|
|
279
|
-
child.stdin.write('stop\n');
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (/\[\d+\] stop/.test(line)) {
|
|
283
|
-
echoed = true;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
})
|
|
287
|
-
.then(() => {
|
|
288
|
-
assert(echoed);
|
|
289
|
-
})
|
|
290
|
-
.then(done, done);
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it('sends input to specified default stdin target process', (done) => {
|
|
294
|
-
let echoed = false;
|
|
295
|
-
run('node ./src/main.js --default-input-target 1 "echo test" "node ./test/support/read-echo.js"', {
|
|
296
|
-
onOutputLine: (line, child) => {
|
|
297
|
-
if (/READING/.test(line)) {
|
|
298
|
-
child.stdin.write('stop\n');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (/\[1\] stop/.test(line)) {
|
|
302
|
-
echoed = true;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
})
|
|
306
|
-
.then(() => {
|
|
307
|
-
assert(echoed);
|
|
308
|
-
})
|
|
309
|
-
.then(done, done);
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it('sends input to child specified by index', (done) => {
|
|
313
|
-
let echoed = false;
|
|
314
|
-
run('node ./src/main.js "echo test" "node ./test/support/read-echo.js"', {
|
|
315
|
-
onOutputLine: (line, child) => {
|
|
316
|
-
if (/READING/.test(line)) {
|
|
317
|
-
child.stdin.write('1:stop\n');
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (/\[1\] stop/.test(line)) {
|
|
321
|
-
echoed = true;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
})
|
|
325
|
-
.then(() => {
|
|
326
|
-
assert(echoed);
|
|
327
|
-
})
|
|
328
|
-
.then(done, done);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it('emits error when specified read stream is not found', (done) => {
|
|
332
|
-
let errorEmitted = false;
|
|
333
|
-
run('node ./src/main.js "echo test" "node ./test/support/read-echo.js"', {
|
|
334
|
-
onOutputLine: (line, child) => {
|
|
335
|
-
if (/READING/.test(line)) {
|
|
336
|
-
child.stdin.write('2:stop\n');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if ('Unable to find command [2]' === line.trim()) {
|
|
340
|
-
errorEmitted = true;
|
|
341
|
-
|
|
342
|
-
// Stop read process to continue the test
|
|
343
|
-
child.stdin.write('1:stop\n');
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
})
|
|
347
|
-
.then(() => {
|
|
348
|
-
assert(errorEmitted);
|
|
349
|
-
})
|
|
350
|
-
.then(done, done);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should expand npm: command shortcuts', (done) => {
|
|
354
|
-
let echo1 = false;
|
|
355
|
-
let echo2 = false;
|
|
356
|
-
run('node ./src/main.js "npm:echo-test" "npm:echo -- testarg"', {
|
|
357
|
-
onOutputLine: function(line, child) {
|
|
358
|
-
if (line === '[echo-test] test') {
|
|
359
|
-
echo1 = true;
|
|
360
|
-
} else if (line === '[echo] testarg') {
|
|
361
|
-
echo2 = true;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
})
|
|
365
|
-
.then((exitCode) => {
|
|
366
|
-
assert.strictEqual(exitCode, 0);
|
|
367
|
-
assert.ok(echo1);
|
|
368
|
-
assert.ok(echo2);
|
|
369
|
-
})
|
|
370
|
-
.then(done, done);
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('expands npm run shortcut wildcards', (done) => {
|
|
374
|
-
let echoBeep = false;
|
|
375
|
-
let echoBoop = false;
|
|
376
|
-
run('node ./src/main.js "npm:echo-sound-*"', {
|
|
377
|
-
onOutputLine: (line, child) => {
|
|
378
|
-
if (line === '[beep] beep') {
|
|
379
|
-
echoBeep = true;
|
|
380
|
-
} else if (line === '[boop] boop') {
|
|
381
|
-
echoBoop = true;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
})
|
|
385
|
-
.then((exitCode) => {
|
|
386
|
-
assert.strictEqual(exitCode, 0);
|
|
387
|
-
assert.ok(echoBeep);
|
|
388
|
-
assert.ok(echoBoop);
|
|
389
|
-
})
|
|
390
|
-
.then(done, done);
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
function resolve(relativePath) {
|
|
395
|
-
return path.join(testDir, relativePath);
|
|
396
|
-
}
|
package/test/test-parseCmds.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const assert = require('assert');
|
|
3
|
-
const sinon = require('sinon');
|
|
4
|
-
|
|
5
|
-
const parseCmds = require('../src/parseCmds');
|
|
6
|
-
|
|
7
|
-
const sandbox = sinon.createSandbox();
|
|
8
|
-
|
|
9
|
-
describe('parseCmds', () => {
|
|
10
|
-
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
sandbox.restore();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('returns a list of command objects', () => {
|
|
16
|
-
const cmds = parseCmds([ 'echo test' ]);
|
|
17
|
-
|
|
18
|
-
assert.deepStrictEqual(cmds, [
|
|
19
|
-
{
|
|
20
|
-
cmd: 'echo test',
|
|
21
|
-
name: '',
|
|
22
|
-
color: undefined
|
|
23
|
-
}
|
|
24
|
-
]);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('strips quotes', () => {
|
|
28
|
-
const cmds = parseCmds([ '"echo test"' ]);
|
|
29
|
-
|
|
30
|
-
assert.deepStrictEqual(cmds, [
|
|
31
|
-
{
|
|
32
|
-
cmd: 'echo test',
|
|
33
|
-
name: '',
|
|
34
|
-
color: undefined
|
|
35
|
-
}
|
|
36
|
-
]);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('assigns names', () => {
|
|
40
|
-
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
41
|
-
names: 'echo-test,echo-test2'
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
assert.deepStrictEqual(cmds, [
|
|
45
|
-
{
|
|
46
|
-
cmd: 'echo test',
|
|
47
|
-
name: 'echo-test',
|
|
48
|
-
color: undefined
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
cmd: 'echo test2',
|
|
52
|
-
name: 'echo-test2',
|
|
53
|
-
color: undefined
|
|
54
|
-
}
|
|
55
|
-
]);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('assigns names with custom separator', () => {
|
|
59
|
-
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
60
|
-
names: 'echo-test|echo-test2',
|
|
61
|
-
nameSeparator: '|'
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
assert.deepStrictEqual(cmds, [
|
|
65
|
-
{
|
|
66
|
-
cmd: 'echo test',
|
|
67
|
-
name: 'echo-test',
|
|
68
|
-
color: undefined
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
cmd: 'echo test2',
|
|
72
|
-
name: 'echo-test2',
|
|
73
|
-
color: undefined
|
|
74
|
-
}
|
|
75
|
-
]);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('assigns colours', () => {
|
|
79
|
-
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
80
|
-
prefixColors: 'blue'
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
assert.deepStrictEqual(cmds, [
|
|
84
|
-
{
|
|
85
|
-
cmd: 'echo test',
|
|
86
|
-
name: '',
|
|
87
|
-
color: 'blue'
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
cmd: 'echo test2',
|
|
91
|
-
name: '',
|
|
92
|
-
color: undefined
|
|
93
|
-
}
|
|
94
|
-
]);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('expands npm: shortcut', () => {
|
|
98
|
-
const cmds = parseCmds([ 'npm:watch:js' ]);
|
|
99
|
-
|
|
100
|
-
assert.deepStrictEqual(cmds, [
|
|
101
|
-
{
|
|
102
|
-
cmd: 'npm run watch:js',
|
|
103
|
-
name: 'watch:js',
|
|
104
|
-
color: undefined
|
|
105
|
-
}
|
|
106
|
-
]);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('expands npm: shortcut with assigned name', () => {
|
|
110
|
-
const cmds = parseCmds([ 'npm:watch:js' ], {
|
|
111
|
-
names: 'js'
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
assert.deepStrictEqual(cmds, [
|
|
115
|
-
{
|
|
116
|
-
cmd: 'npm run watch:js',
|
|
117
|
-
name: 'js',
|
|
118
|
-
color: undefined
|
|
119
|
-
}
|
|
120
|
-
]);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('expands npm: shortcut with wildcard', () => {
|
|
124
|
-
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
125
|
-
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
126
|
-
]);
|
|
127
|
-
|
|
128
|
-
const cmds = parseCmds([ 'npm:watch:*' ]);
|
|
129
|
-
|
|
130
|
-
assert.deepStrictEqual(cmds, [
|
|
131
|
-
{
|
|
132
|
-
cmd: 'npm run watch:js',
|
|
133
|
-
name: 'js',
|
|
134
|
-
color: undefined
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
cmd: 'npm run watch:css',
|
|
138
|
-
name: 'css',
|
|
139
|
-
color: undefined
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
cmd: 'npm run watch:node',
|
|
143
|
-
name: 'node',
|
|
144
|
-
color: undefined
|
|
145
|
-
}
|
|
146
|
-
]);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('expands npm: shortcut with wildcard and name prefix', () => {
|
|
150
|
-
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
151
|
-
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
152
|
-
]);
|
|
153
|
-
|
|
154
|
-
const cmds = parseCmds([ 'npm:watch:*' ], {
|
|
155
|
-
names: 'w:'
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
assert.deepStrictEqual(cmds, [
|
|
159
|
-
{
|
|
160
|
-
cmd: 'npm run watch:js',
|
|
161
|
-
name: 'w:js',
|
|
162
|
-
color: undefined
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
cmd: 'npm run watch:css',
|
|
166
|
-
name: 'w:css',
|
|
167
|
-
color: undefined
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
cmd: 'npm run watch:node',
|
|
171
|
-
name: 'w:node',
|
|
172
|
-
color: undefined
|
|
173
|
-
}
|
|
174
|
-
]);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('applies prefix colors to expanded commands', () => {
|
|
178
|
-
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
179
|
-
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
180
|
-
]);
|
|
181
|
-
|
|
182
|
-
const cmds = parseCmds([ 'npm:watch:*' ], {
|
|
183
|
-
prefixColors: 'blue,magenta,cyan'
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
assert.deepStrictEqual(cmds, [
|
|
187
|
-
{
|
|
188
|
-
cmd: 'npm run watch:js',
|
|
189
|
-
name: 'js',
|
|
190
|
-
color: 'blue'
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
cmd: 'npm run watch:css',
|
|
194
|
-
name: 'css',
|
|
195
|
-
color: 'magenta'
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
cmd: 'npm run watch:node',
|
|
199
|
-
name: 'node',
|
|
200
|
-
color: 'cyan'
|
|
201
|
-
}
|
|
202
|
-
]);
|
|
203
|
-
});
|
|
204
|
-
});
|
package/test/utils.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const childProcess = require('child_process');
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const readline = require('readline');
|
|
5
|
-
const shellQuote = require('shell-quote');
|
|
6
|
-
|
|
7
|
-
// If true, output of commands are shown
|
|
8
|
-
const DEBUG_TESTS = process.env.DEBUG_TESTS === 'true';
|
|
9
|
-
|
|
10
|
-
function run(cmd, opts) {
|
|
11
|
-
opts = _.merge({
|
|
12
|
-
// If set to a function, it will be called for each line
|
|
13
|
-
// written to the child process's stdout as (line, child)
|
|
14
|
-
onOutputLine: undefined,
|
|
15
|
-
onErrorLine: undefined
|
|
16
|
-
}, opts);
|
|
17
|
-
|
|
18
|
-
let child;
|
|
19
|
-
const parts = shellQuote.parse(cmd);
|
|
20
|
-
try {
|
|
21
|
-
child = childProcess.spawn(_.head(parts), _.tail(parts), {
|
|
22
|
-
stdio: DEBUG_TESTS && !opts.onOutputLine ? 'inherit': null,
|
|
23
|
-
});
|
|
24
|
-
} catch (e) {
|
|
25
|
-
return Promise.reject(e);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (opts.onOutputLine) {
|
|
29
|
-
readLines(child, opts.onOutputLine);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (opts.onErrorLine) {
|
|
33
|
-
readLines(child, opts.onErrorLine, 'stderr');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
readLines(child, (l) => { console.log(l); }, 'stderr');
|
|
37
|
-
|
|
38
|
-
return new Promise(function(resolve, reject) {
|
|
39
|
-
child.on('error', function(err) {
|
|
40
|
-
reject(err);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
child.on('close', function(exitCode) {
|
|
44
|
-
resolve(exitCode);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function readLines(child, callback, src) {
|
|
50
|
-
src = src || 'stdout';
|
|
51
|
-
|
|
52
|
-
const rl = readline.createInterface({
|
|
53
|
-
input: child[src],
|
|
54
|
-
output: null
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
rl.on('line', function(line) {
|
|
58
|
-
if (DEBUG_TESTS) {
|
|
59
|
-
console.log(line);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
callback(line, child);
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
module.exports = {
|
|
67
|
-
run: run
|
|
68
|
-
};
|