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.
Files changed (52) hide show
  1. package/.travis.yml +3 -4
  2. package/.vscode/settings.json +5 -0
  3. package/CONTRIBUTING.md +1 -4
  4. package/README.md +131 -94
  5. package/appveyor.yml +1 -1
  6. package/bin/concurrently.js +164 -0
  7. package/bin/concurrently.spec.js +340 -0
  8. package/bin/epilogue.txt +46 -0
  9. package/{test/support → bin/fixtures}/read-echo.js +0 -2
  10. package/index.js +56 -0
  11. package/package.json +28 -31
  12. package/src/command-parser/expand-npm-shortcut.js +13 -0
  13. package/src/command-parser/expand-npm-shortcut.spec.js +36 -0
  14. package/src/command-parser/expand-npm-wildcard.js +34 -0
  15. package/src/command-parser/expand-npm-wildcard.spec.js +58 -0
  16. package/src/command-parser/strip-quotes.js +12 -0
  17. package/src/command-parser/strip-quotes.spec.js +14 -0
  18. package/src/command.js +50 -0
  19. package/src/command.spec.js +142 -0
  20. package/src/completion-listener.js +35 -0
  21. package/src/completion-listener.spec.js +88 -0
  22. package/src/concurrently.js +69 -0
  23. package/src/concurrently.spec.js +77 -0
  24. package/src/defaults.js +27 -0
  25. package/src/flow-control/fixtures/fake-command.js +16 -0
  26. package/src/flow-control/input-handler.js +39 -0
  27. package/src/flow-control/input-handler.spec.js +79 -0
  28. package/src/flow-control/kill-on-signal.js +29 -0
  29. package/src/flow-control/kill-on-signal.spec.js +70 -0
  30. package/src/flow-control/kill-others.js +35 -0
  31. package/src/flow-control/kill-others.spec.js +66 -0
  32. package/src/flow-control/log-error.js +20 -0
  33. package/src/flow-control/log-error.spec.js +40 -0
  34. package/src/flow-control/log-exit.js +13 -0
  35. package/src/flow-control/log-exit.spec.js +36 -0
  36. package/src/flow-control/log-output.js +14 -0
  37. package/src/flow-control/log-output.spec.js +41 -0
  38. package/src/flow-control/restart-process.js +51 -0
  39. package/src/flow-control/restart-process.spec.js +129 -0
  40. package/src/get-spawn-opts.js +12 -0
  41. package/src/get-spawn-opts.spec.js +18 -0
  42. package/src/logger.js +109 -0
  43. package/src/logger.spec.js +178 -0
  44. package/src/findChild.js +0 -11
  45. package/src/main.js +0 -563
  46. package/src/parseCmds.js +0 -65
  47. package/src/pkgInfo.js +0 -17
  48. package/test/support/signal.js +0 -13
  49. package/test/test-findChild.js +0 -39
  50. package/test/test-functional.js +0 -396
  51. package/test/test-parseCmds.js +0 -204
  52. package/test/utils.js +0 -68
package/src/main.js DELETED
@@ -1,563 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const Rx = require('rx');
5
- const path = require('path');
6
- const formatDate = require('date-fns/format');
7
- const program = require('commander');
8
- const _ = require('lodash');
9
- const treeKill = require('tree-kill');
10
- const chalk = require('chalk');
11
- const spawn = require('spawn-command');
12
- const supportsColor = require('supports-color');
13
- const IS_WINDOWS = /^win/.test(process.platform);
14
-
15
- const findChild = require('./findChild.js');
16
- const parseCmds = require('./parseCmds');
17
-
18
- let config = {
19
- // Kill other processes if one dies
20
- killOthers: false,
21
-
22
- // Kill other processes if one exits with non zero status code
23
- killOthersOnFail: false,
24
-
25
- // Return success or failure of the 'first' child to terminate, the 'last' child,
26
- // or succeed only if 'all' children succeed
27
- success: 'all',
28
-
29
- // Prefix logging with pid
30
- // Possible values: 'pid', 'none', 'time', 'command', 'index', 'name'
31
- prefix: '',
32
-
33
- // List of custom names to be used in prefix template
34
- names: '',
35
-
36
- // What to split the list of custom names on
37
- nameSeparator: ',',
38
-
39
- // Comma-separated list of chalk color paths to use on prefixes.
40
- prefixColors: 'gray.dim',
41
-
42
- // moment/date-fns format
43
- timestampFormat: 'YYYY-MM-DD HH:mm:ss.SSS',
44
-
45
- // How many characters to display from start of command in prefix if
46
- // command is defined. Note that also '..' will be added in the middle
47
- prefixLength: 10,
48
-
49
- // By default, color output
50
- color: true,
51
-
52
- // If true, the output will only be raw output of processes, nothing more
53
- raw: false,
54
-
55
- // If true, the process restart when it exited with status code non-zero
56
- allowRestart: false,
57
-
58
- // By default, restart instantly
59
- restartAfter: 0,
60
-
61
- // By default, restart once
62
- restartTries: 1,
63
-
64
- // Default identifier for child to which input on stdin should be sent.
65
- defaultInputTarget: '0'
66
- };
67
-
68
- function main() {
69
- const firstBase = path.basename(process.argv[0]);
70
- const secondBase = path.basename(process.argv[1]);
71
- if (firstBase === 'concurrent' || secondBase === 'concurrent') {
72
- console.error('Warning: "concurrent" command is deprecated, use "concurrently" instead.\n');
73
- }
74
-
75
- parseArgs();
76
- config = mergeDefaultsWithArgs(config);
77
-
78
- const cmds = parseCmds(program.args, config);
79
- run(cmds);
80
- }
81
-
82
- function parseArgs() {
83
- program
84
- .version(require('../package.json').version)
85
- .usage('[options] <command ...>')
86
- .option(
87
- '-k, --kill-others',
88
- 'kill other processes if one exits or dies'
89
- )
90
- .option(
91
- '--kill-others-on-fail',
92
- 'kill other processes if one exits with non zero status code'
93
- )
94
- .option(
95
- '--no-color',
96
- 'disable colors from logging'
97
- )
98
- .option(
99
- '-p, --prefix <prefix>',
100
- 'prefix used in logging for each process.\n' +
101
- 'Possible values: index, pid, time, command, name, none, or a template. Default: ' +
102
- 'index or name (when --names is set). Example template: "{time}-{pid}"\n'
103
- )
104
- .option(
105
- '-n, --names <names>',
106
- 'List of custom names to be used in prefix template.\n' +
107
- 'Example names: "main,browser,server"\n'
108
- )
109
- .option(
110
- '--name-separator <char>',
111
- 'The character to split <names> on.\n' +
112
- 'Default: "' + config.nameSeparator + '". Example usage: ' +
113
- 'concurrently -n "styles,scripts|server" --name-separator "|" <command ...>\n'
114
- )
115
- .option(
116
- '-c, --prefix-colors <colors>',
117
- 'Comma-separated list of chalk colors to use on prefixes. If there are more commands than colors, the last color will be repeated.\n' +
118
- 'Available modifiers: reset, bold, dim, italic, underline, inverse, hidden, strikethrough\n' +
119
- 'Available colors: black, red, green, yellow, blue, magenta, cyan, white, gray\n' +
120
- 'Available background colors: bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite\n' +
121
- 'See https://www.npmjs.com/package/chalk for more information.\n' +
122
- 'Default: "' + config.prefixColors + '". Example: "black.bgWhite,cyan,gray.dim"\n'
123
- )
124
- .option(
125
- '-t, --timestamp-format <format>',
126
- 'specify the timestamp in moment/date-fns format. Default: ' +
127
- config.timestampFormat + '\n'
128
- )
129
- .option(
130
- '-r, --raw',
131
- 'output only raw output of processes,' +
132
- ' disables prettifying and concurrently coloring'
133
- )
134
- .option(
135
- '-s, --success <first|last|all>',
136
- 'Return exit code of zero or one based on the success or failure ' +
137
- 'of the "first" child to terminate, the "last" child, or succeed ' +
138
- ' only if "all" child processes succeed. Default: ' +
139
- config.success + '\n'
140
- )
141
- .option(
142
- '-l, --prefix-length <length>',
143
- 'limit how many characters of the command is displayed in prefix.\n' +
144
- 'The option can be used to shorten long commands.\n' +
145
- 'Works only if prefix is set to "command". Default: ' +
146
- config.prefixLength + '\n'
147
- )
148
- .option(
149
- '--allow-restart',
150
- 'Restart a process which died. Default: ' +
151
- config.allowRestart + '\n'
152
- )
153
- .option(
154
- '--restart-after <miliseconds>',
155
- 'delay time to respawn the process. Default: ' +
156
- config.restartAfter + '\n'
157
- )
158
- .option(
159
- '--restart-tries <times>',
160
- 'limit the number of respawn tries. Default: ' +
161
- config.restartTries + '\n'
162
-
163
- )
164
- .option(
165
- '--default-input-target <identifier>',
166
- 'identifier for child process to which input on ' +
167
- 'stdin should be sent if not specified at start ' +
168
- 'of input. Can be either the index or the name ' +
169
- 'of the process. Default: ' + config.defaultInputTarget + '\n'
170
- );
171
-
172
- program.on('--help', function() {
173
- const help = [
174
- ' Input:',
175
- '',
176
- ' Input can be sent to any of the child processes using either the name or',
177
- ' index of the command followed by a colon. If no child identifier is',
178
- ' specified then the input will be sent to the child specified by the',
179
- ' `--default-input-target` option, which defaults to index 0.',
180
- '',
181
- ' Examples:',
182
- '',
183
- ' - Kill other processes if one exits or dies',
184
- '',
185
- ' $ concurrently --kill-others "grunt watch" "http-server"',
186
- '',
187
- ' - Kill other processes if one exits with non zero status code',
188
- '',
189
- ' $ concurrently --kill-others-on-fail "npm run build:client" "npm run build:server"',
190
- '',
191
- ' - Output nothing more than stdout+stderr of child processes',
192
- '',
193
- ' $ concurrently --raw "npm run watch-less" "npm run watch-js"',
194
- '',
195
- ' - Normal output but without colors e.g. when logging to file',
196
- '',
197
- ' $ concurrently --no-color "grunt watch" "http-server" > log',
198
- '',
199
- ' - Custom prefix',
200
- '',
201
- ' $ concurrently --prefix "{time}-{pid}" "npm run watch" "http-server"',
202
- '',
203
- ' - Custom names and colored prefixes',
204
- '',
205
- ' $ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold" "http-server" "npm run watch"',
206
- '',
207
- ' - Send input to default',
208
- '',
209
- ' $ concurrently "nodemon" "npm run watch-js"',
210
- ' rs # Sends rs command to nodemon process',
211
- '',
212
- ' - Specify a default-input-target',
213
- '',
214
- ' $ concurrently --default-input-target 1 "npm run watch-js" nodemon',
215
- ' rs',
216
- '',
217
- ' - Send input to specific child identified by index',
218
- '',
219
- ' $ concurrently "npm run watch-js" nodemon',
220
- ' 1:rs',
221
- '',
222
- ' - Send input to specific child identified by name',
223
- '',
224
- ' $ concurrently -n js,srv "npm run watch-js" nodemon',
225
- ' srv:rs',
226
- '',
227
- ' - Shortened NPM run commands',
228
- '',
229
- ' $ concurrently npm:watch-node npm:watch-js npm:watch-css',
230
- '',
231
- ' - Shortened NPM run command with wildcard',
232
- '',
233
- ' $ concurrently npm:watch-*',
234
- ''
235
- ];
236
- console.log(help.join('\n'));
237
-
238
- const url = 'https://github.com/kimmobrunfeldt/concurrently';
239
- console.log(' For more details, visit ' + url);
240
- console.log('');
241
- });
242
-
243
- program.parse(process.argv);
244
- }
245
-
246
- function mergeDefaultsWithArgs(config) {
247
- // This will pollute config object with other attributes from program too
248
- return _.merge(config, program);
249
- }
250
-
251
- function run(commands) {
252
- const childrenInfo = {};
253
- let lastPrefixColor = _.get(chalk, chalk.gray.dim);
254
- const children = _.map(commands, function(cmdInfo, index) {
255
-
256
- const spawnOpts = config.raw ? {stdio: 'inherit'} : {};
257
- if (IS_WINDOWS) {
258
- spawnOpts.detached = false;
259
- }
260
- if (supportsColor) {
261
- spawnOpts.env = Object.assign({FORCE_COLOR: supportsColor.level}, process.env);
262
- }
263
-
264
- const child = spawnChild(cmdInfo.cmd, spawnOpts);
265
-
266
- if (cmdInfo.color) {
267
- const prefixColorPath = cmdInfo.color;
268
- lastPrefixColor = _.get(chalk, prefixColorPath, chalk.gray.dim);
269
- }
270
-
271
- childrenInfo[child.pid] = {
272
- command: cmdInfo.cmd,
273
- index: index,
274
- name: cmdInfo.name,
275
- options: spawnOpts,
276
- restartTries: config.restartTries,
277
- prefixColor: lastPrefixColor
278
- };
279
- return child;
280
- });
281
-
282
- const streams = toStreams(children);
283
-
284
- handleChildEvents(streams, children, childrenInfo);
285
-
286
- ['SIGINT', 'SIGTERM'].forEach(function(signal) {
287
- process.on(signal, function() {
288
- children.forEach(function(child) {
289
- treeKill(child.pid, signal);
290
- });
291
- });
292
- });
293
-
294
- process.stdin.on('data', (chunk) => {
295
- let line = chunk.toString();
296
-
297
- let targetId = config.defaultInputTarget;
298
- if (line.indexOf(':') >= 0) {
299
- const parts = line.split(':');
300
- targetId = parts[0];
301
- line = parts[1];
302
- }
303
-
304
- const target = findChild(targetId, children, childrenInfo);
305
- if (target) {
306
- target.stdin.write(line);
307
- } else {
308
- logError('', chalk.gray.dim, `Unable to find command [${targetId}]\n`);
309
- }
310
- });
311
- }
312
-
313
- function spawnChild(cmd, options) {
314
- let child;
315
- try {
316
- child = spawn(cmd, options);
317
- } catch (e) {
318
- logError('', chalk.gray.dim, 'Error occured when executing command: ' + cmd);
319
- logError('', chalk.gray.dim, e.stack);
320
- process.exit(1);
321
- }
322
- return child;
323
- }
324
-
325
- function toStreams(children) {
326
- // Transform all process events to rx streams
327
- return _.map(children, function(child) {
328
- const childStreams = {
329
- error: Rx.Node.fromEvent(child, 'error'),
330
- close: Rx.Node.fromEvent(child, 'close')
331
- };
332
- if (!config.raw) {
333
- childStreams.stdout = Rx.Node.fromReadableStream(child.stdout);
334
- childStreams.stderr = Rx.Node.fromReadableStream(child.stderr);
335
- }
336
-
337
- return _.reduce(childStreams, function(memo, stream, key) {
338
- memo[key] = stream.map(function(data) {
339
- return {child: child, data: data};
340
- });
341
-
342
- return memo;
343
- }, {});
344
- });
345
- }
346
-
347
- function handleChildEvents(streams, children, childrenInfo) {
348
- handleClose(streams, children, childrenInfo);
349
- handleError(streams, childrenInfo);
350
- if (!config.raw) {
351
- handleOutput(streams, childrenInfo, 'stdout');
352
- handleOutput(streams, childrenInfo, 'stderr');
353
- }
354
- }
355
-
356
- function handleOutput(streams, childrenInfo, source) {
357
- const sourceStreams = _.map(streams, source);
358
- const combinedSourceStream = Rx.Observable.merge.apply(this, sourceStreams);
359
-
360
- combinedSourceStream.subscribe(function(event) {
361
- const prefix = getPrefix(childrenInfo, event.child);
362
- const prefixColor = childrenInfo[event.child.pid].prefixColor;
363
- log(prefix, prefixColor, event.data.toString());
364
- });
365
- }
366
-
367
- function handleClose(streams, children, childrenInfo) {
368
- let aliveChildren = _.clone(children);
369
- const exitCodes = [];
370
- const closeStreams = _.map(streams, 'close');
371
- const closeStream = Rx.Observable.merge.apply(this, closeStreams);
372
- let othersKilled = false;
373
-
374
- // TODO: Is it possible that amount of close events !== count of spawned?
375
- closeStream.subscribe(function(event) {
376
- const exitCode = event.data;
377
- const nonSuccess = exitCode !== 0;
378
- exitCodes.push(exitCode);
379
-
380
- const prefix = getPrefix(childrenInfo, event.child);
381
- const childInfo = childrenInfo[event.child.pid];
382
- const prefixColor = childInfo.prefixColor;
383
- const command = childInfo.command;
384
- logEvent(prefix, prefixColor, command + ' exited with code ' + exitCode);
385
-
386
- aliveChildren = _.filter(aliveChildren, function(child) {
387
- return child.pid !== event.child.pid;
388
- });
389
-
390
- if (nonSuccess && config.allowRestart && childInfo.restartTries--) {
391
- respawnChild(event, childrenInfo);
392
- return;
393
- }
394
-
395
- if (aliveChildren.length === 0) {
396
- exit(exitCodes);
397
- }
398
- if (!othersKilled) {
399
- if (config.killOthers) {
400
- killOtherProcesses(aliveChildren);
401
- othersKilled = true;
402
- } else if (config.killOthersOnFail && nonSuccess) {
403
- killOtherProcesses(aliveChildren);
404
- othersKilled = true;
405
- }
406
- }
407
- });
408
- }
409
-
410
- function respawnChild(event, childrenInfo) {
411
- setTimeout(function() {
412
- const childInfo = childrenInfo[event.child.pid];
413
- const prefix = getPrefix(childrenInfo, event.child);
414
- const prefixColor = childInfo.prefixColor;
415
- logEvent(prefix, prefixColor, childInfo.command + ' restarted');
416
- const newChild = spawnChild(childInfo.command, childInfo.options);
417
-
418
- childrenInfo[newChild.pid] = childrenInfo[event.child.pid];
419
- delete childrenInfo[event.child.pid];
420
-
421
- const children = [newChild];
422
- const streams = toStreams(children);
423
- handleChildEvents(streams, children, childrenInfo);
424
- }, config.restartAfter);
425
- }
426
-
427
- function killOtherProcesses(processes) {
428
- logEvent('--> ', chalk.gray.dim, 'Sending SIGTERM to other processes..');
429
-
430
- // Send SIGTERM to alive children
431
- _.each(processes, function(child) {
432
- treeKill(child.pid, 'SIGTERM');
433
- });
434
- }
435
-
436
- function exit(childExitCodes) {
437
- let success;
438
- switch (config.success) {
439
- case 'first':
440
- success = _.first(childExitCodes) === 0;
441
- break;
442
- case 'last':
443
- success = _.last(childExitCodes) === 0;
444
- break;
445
- default:
446
- success = _.every(childExitCodes, function(code) {
447
- return code === 0;
448
- });
449
- }
450
- process.exit(success ? 0 : 1);
451
- }
452
-
453
- function handleError(streams, childrenInfo) {
454
- // Output emitted errors from child process
455
- const errorStreams = _.map(streams, 'error');
456
- const processErrorStream = Rx.Observable.merge.apply(this, errorStreams);
457
-
458
- processErrorStream.subscribe(function(event) {
459
- const command = childrenInfo[event.child.pid].command;
460
- logError('', chalk.gray.dim, 'Error occured when executing command: ' + command);
461
- logError('', chalk.gray.dim, event.data.stack);
462
- });
463
- }
464
-
465
- function colorText(text, color) {
466
- if (!config.color) {
467
- return text;
468
- } else {
469
- return color(text);
470
- }
471
- }
472
-
473
- function getPrefix(childrenInfo, child) {
474
- const prefixes = getPrefixes(childrenInfo, child);
475
- const prefixType = config.prefix || prefixes.name ? 'name' : 'index';
476
- if (_.includes(_.keys(prefixes), prefixType)) {
477
- return '[' + prefixes[prefixType] + '] ';
478
- }
479
-
480
- return _.reduce(prefixes, function(memo, val, key) {
481
- const re = new RegExp('{' + key + '}', 'g');
482
- return memo.replace(re, val);
483
- }, config.prefix) + ' ';
484
- }
485
-
486
- function getPrefixes(childrenInfo, child) {
487
- const prefixes = {};
488
-
489
- prefixes.none = '';
490
- prefixes.pid = child.pid;
491
- prefixes.index = childrenInfo[child.pid].index;
492
- prefixes.name = childrenInfo[child.pid].name;
493
- prefixes.time = formatDate(Date.now(), config.timestampFormat);
494
-
495
- const command = childrenInfo[child.pid].command;
496
- prefixes.command = shortenText(command, config.prefixLength);
497
- return prefixes;
498
- }
499
-
500
- function shortenText(text, length, cut) {
501
- if (text.length <= length) {
502
- return text;
503
- }
504
- cut = _.isString(cut) ? cut : '..';
505
-
506
- const endLength = Math.floor(length / 2);
507
- const startLength = length - endLength;
508
-
509
- const first = text.substring(0, startLength);
510
- const last = text.substring(text.length - endLength, text.length);
511
- return first + cut + last;
512
- }
513
-
514
- function log(prefix, prefixColor, text) {
515
- logWithPrefix(prefix, prefixColor, text);
516
- }
517
-
518
- function logEvent(prefix, prefixColor, text) {
519
- if (config.raw) {
520
- return;
521
- }
522
-
523
- logWithPrefix(prefix, prefixColor, text + '\n', chalk.gray.dim);
524
- }
525
-
526
- function logError(prefix, prefixColor, text) {
527
- // This is for now same as log, there might be separate colors for stderr
528
- // and stdout
529
- logWithPrefix(prefix, prefixColor, text, chalk.red.bold);
530
- }
531
-
532
- let lastChar;
533
-
534
- function logWithPrefix(prefix, prefixColor, text, color) {
535
-
536
- if (config.raw) {
537
- process.stdout.write(text);
538
- return;
539
- }
540
-
541
- text = text.replace(/\u2026/g,'...'); // Ellipsis
542
-
543
- const lines = text.split('\n');
544
- // Do not bgColor trailing space
545
- const coloredPrefix = colorText(prefix.replace(/ $/, ''), prefixColor) + ' ';
546
- const paddedLines = _.map(lines, function(line, index) {
547
- let coloredLine = color ? colorText(line, color) : line;
548
- if (index !== 0 && index !== (lines.length - 1)) {
549
- coloredLine = coloredPrefix + coloredLine;
550
- }
551
- return coloredLine;
552
- });
553
-
554
- if (!lastChar || lastChar === '\n' ) {
555
- process.stdout.write(coloredPrefix);
556
- }
557
-
558
- lastChar = text[text.length - 1];
559
-
560
- process.stdout.write(paddedLines.join('\n'));
561
- }
562
-
563
- main();
package/src/parseCmds.js DELETED
@@ -1,65 +0,0 @@
1
- 'use strict';
2
- const _ = require('lodash');
3
-
4
- const pkgInfo = require('./pkgInfo');
5
-
6
- module.exports = function(cmds, config) {
7
- config = config || {};
8
-
9
- const names = (config.names || '').split(config.nameSeparator || ',');
10
- const prefixColors = config.prefixColors ? config.prefixColors.split(',') : [];
11
-
12
- cmds = cmds.map(stripCmdQuotes);
13
-
14
- cmds = cmds.map((cmd, idx) => ({
15
- cmd: cmd,
16
- name: names[idx] || ''
17
- }));
18
-
19
- cmds = _.flatMap(cmds, expandCmdShortcuts);
20
-
21
- return cmds.map((cmd, idx) => Object.assign(cmd, {
22
- color: prefixColors[idx]
23
- }));
24
- };
25
-
26
- function stripCmdQuotes(cmd) {
27
- // Removes the quotes surrounding a command.
28
- if (cmd[0] === '"' || cmd[0] === '\'') {
29
- return cmd.substr(1, cmd.length - 2);
30
- } else {
31
- return cmd;
32
- }
33
- }
34
-
35
- function expandCmdShortcuts(cmd) {
36
- const shortcut = cmd.cmd.match(/^npm:(\S+)(.*)/);
37
- if (shortcut) {
38
- const cmdName = shortcut[1];
39
- const args = shortcut[2];
40
-
41
- const wildcard = cmdName.indexOf('*');
42
- if (wildcard >= 0) {
43
- return expandNpmWildcard(cmd, cmdName, wildcard, args);
44
- }
45
-
46
- if (!cmd.name) {
47
- cmd.name = cmdName;
48
- }
49
- cmd.cmd = `npm run ${cmdName}${args}`;
50
- }
51
- return [ cmd ];
52
- }
53
-
54
- function expandNpmWildcard(cmd, cmdName, wildcardPos, args) {
55
- const rePre = _.escapeRegExp(cmdName.substr(0, wildcardPos));
56
- const reSuf = _.escapeRegExp(cmdName.substr(wildcardPos + 1));
57
- const wildcardRe = new RegExp(`^${rePre}(.*?)${reSuf}$`);
58
-
59
- return pkgInfo.getScripts()
60
- .filter(script => script.match(wildcardRe))
61
- .map(script => Object.assign({}, cmd, {
62
- cmd: `npm run ${script}${args}`,
63
- name: cmd.name + script.match(wildcardRe)[1]
64
- }));
65
- }
package/src/pkgInfo.js DELETED
@@ -1,17 +0,0 @@
1
- 'use strict';
2
-
3
- const readPkg = require('read-pkg');
4
-
5
- let pkg;
6
-
7
- function getPkg() {
8
- if (!pkg) {
9
- pkg = readPkg.sync();
10
- }
11
- return pkg;
12
- }
13
-
14
- exports.getScripts = function() {
15
- const pkg = getPkg();
16
- return Object.keys(pkg.scripts || {});
17
- };
@@ -1,13 +0,0 @@
1
- ['SIGINT', 'SIGTERM'].forEach(function(signal) {
2
- process.on(signal, function() {
3
- console.log(signal);
4
- process.exit(1);
5
- });
6
- });
7
-
8
- function doNothing() {
9
- setTimeout(doNothing, 1000);
10
- }
11
-
12
- doNothing();
13
- console.log('STARTED');
@@ -1,39 +0,0 @@
1
- 'use strict';
2
-
3
- const assert = require('assert');
4
-
5
- const findChild = require('../src/findChild');
6
-
7
- describe('findChild', () => {
8
-
9
- const aChild = { pid: '111' };
10
- const bChild = { pid: '222' };
11
-
12
- const children = [ aChild, bChild ];
13
-
14
- const childrenInfo = {
15
- 111: {
16
- index: 0,
17
- name: 'a child'
18
- },
19
- 222: {
20
- index: 1,
21
- name: 'b child'
22
- }
23
- };
24
-
25
- it('finds child by index', () => {
26
- const child = findChild('1', children, childrenInfo);
27
- assert.strictEqual(child, bChild);
28
- });
29
-
30
- it('finds child by name', () => {
31
- const child = findChild('a child', children, childrenInfo);
32
- assert.strictEqual(child, aChild);
33
- });
34
-
35
- it('returns undefined when no matching child found', () => {
36
- const child = findChild('no child', children, childrenInfo);
37
- assert.strictEqual(child, undefined);
38
- });
39
- });