1 | #!/usr/bin/env node
|
2 | const fs = require('fs');
|
3 | const yargs = require('yargs');
|
4 | const defaults = require('../src/defaults');
|
5 | const concurrently = require('../index');
|
6 |
|
7 | const args = yargs
|
8 | .usage('$0 [options] <command ...>')
|
9 | .help('h')
|
10 | .alias('h', 'help')
|
11 | .version('v', require('../package.json').version)
|
12 | .alias('v', 'V')
|
13 | .alias('v', 'version')
|
14 | .options({
|
15 |
|
16 | 'm': {
|
17 | alias: 'max-processes',
|
18 | describe:
|
19 | 'How many processes should run at once.\n' +
|
20 | 'New processes only spawn after all restart tries of a process.',
|
21 | type: 'number'
|
22 | },
|
23 | 'n': {
|
24 | alias: 'names',
|
25 | describe:
|
26 | 'List of custom names to be used in prefix template.\n' +
|
27 | 'Example names: "main,browser,server"',
|
28 | type: 'string'
|
29 | },
|
30 | 'name-separator': {
|
31 | describe:
|
32 | 'The character to split <names> on. Example usage:\n' +
|
33 | 'concurrently -n "styles|scripts|server" --name-separator "|"',
|
34 | default: defaults.nameSeparator,
|
35 | },
|
36 | 's': {
|
37 | alias: 'success',
|
38 | describe:
|
39 | 'Return exit code of zero or one based on the success or failure ' +
|
40 | 'of the "first" child to terminate, the "last child", or succeed ' +
|
41 | 'only if "all" child processes succeed.',
|
42 | choices: ['first', 'last', 'all'],
|
43 | default: defaults.success
|
44 | },
|
45 | 'r': {
|
46 | alias: 'raw',
|
47 | describe:
|
48 | 'Output only raw output of processes, disables prettifying ' +
|
49 | 'and concurrently coloring.',
|
50 | type: 'boolean'
|
51 | },
|
52 |
|
53 |
|
54 | 'no-color': {
|
55 | describe: 'Disables colors from logging',
|
56 | type: 'boolean'
|
57 | },
|
58 |
|
59 |
|
60 | 'k': {
|
61 | alias: 'kill-others',
|
62 | describe: 'kill other processes if one exits or dies',
|
63 | type: 'boolean'
|
64 | },
|
65 | 'kill-others-on-fail': {
|
66 | describe: 'kill other processes if one exits with non zero status code',
|
67 | type: 'boolean'
|
68 | },
|
69 |
|
70 |
|
71 | 'p': {
|
72 | alias: 'prefix',
|
73 | describe:
|
74 | 'Prefix used in logging for each process.\n' +
|
75 | 'Possible values: index, pid, time, command, name, none, or a template. ' +
|
76 | 'Example template: "{time}-{pid}"',
|
77 | defaultDescription: 'index or name (when --names is set)',
|
78 | type: 'string'
|
79 | },
|
80 | 'c': {
|
81 | alias: 'prefix-colors',
|
82 | describe:
|
83 | 'Comma-separated list of chalk colors to use on prefixes. ' +
|
84 | 'If there are more commands than colors, the last color will be repeated.\n' +
|
85 | '- Available modifiers: reset, bold, dim, italic, underline, inverse, hidden, strikethrough\n' +
|
86 | '- Available colors: black, red, green, yellow, blue, magenta, cyan, white, gray \n' +
|
87 | 'or any hex values for colors, eg #23de43\n' +
|
88 | '- Available background colors: bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite\n' +
|
89 | 'See https://www.npmjs.com/package/chalk for more information.',
|
90 | default: defaults.prefixColors,
|
91 | type: 'string'
|
92 | },
|
93 | 'l': {
|
94 | alias: 'prefix-length',
|
95 | describe:
|
96 | 'Limit how many characters of the command is displayed in prefix. ' +
|
97 | 'The option can be used to shorten the prefix when it is set to "command"',
|
98 | default: defaults.prefixLength,
|
99 | type: 'number'
|
100 | },
|
101 | 't': {
|
102 | alias: 'timestamp-format',
|
103 | describe: 'Specify the timestamp in moment/date-fns format.',
|
104 | default: defaults.timestampFormat,
|
105 | type: 'string'
|
106 | },
|
107 |
|
108 |
|
109 | 'restart-tries': {
|
110 | describe: 'How many times a process that died should restart.',
|
111 | default: defaults.restartTries,
|
112 | type: 'number'
|
113 | },
|
114 | 'restart-after': {
|
115 | describe: 'Delay time to respawn the process, in milliseconds.',
|
116 | default: defaults.restartDelay,
|
117 | type: 'number'
|
118 | },
|
119 |
|
120 |
|
121 | 'i': {
|
122 | alias: 'handle-input',
|
123 | describe:
|
124 | 'Whether input should be forwarded to the child processes. ' +
|
125 | 'See examples for more information.',
|
126 | type: 'boolean'
|
127 | },
|
128 | 'default-input-target': {
|
129 | default: defaults.defaultInputTarget,
|
130 | describe:
|
131 | 'Identifier for child process to which input on stdin ' +
|
132 | 'should be sent if not specified at start of input.\n' +
|
133 | 'Can be either the index or the name of the process.'
|
134 | }
|
135 | })
|
136 | .group(['m', 'n', 'name-separator', 'raw', 's', 'no-color'], 'General')
|
137 | .group(['p', 'c', 'l', 't'], 'Prefix styling')
|
138 | .group(['i', 'default-input-target'], 'Input handling')
|
139 | .group(['k', 'kill-others-on-fail'], 'Killing other processes')
|
140 | .group(['restart-tries', 'restart-after'], 'Restarting')
|
141 |
|
142 | .epilogue(fs.readFileSync(__dirname + '/epilogue.txt', { encoding: 'utf8' }))
|
143 | .argv;
|
144 |
|
145 | const prefixColors = args.prefixColors.split(',');
|
146 | const names = (args.names || '').split(args.nameSeparator);
|
147 |
|
148 | let lastColor;
|
149 | concurrently(args._.map((command, index) => {
|
150 |
|
151 | lastColor = prefixColors[index] || lastColor;
|
152 | return {
|
153 | command,
|
154 | prefixColor: lastColor,
|
155 | name: names[index]
|
156 | };
|
157 | }), {
|
158 | inputStream: args.handleInput && process.stdin,
|
159 | defaultInputTarget: args.defaultInputTarget,
|
160 | killOthers: args.killOthers
|
161 | ? ['success', 'failure']
|
162 | : (args.killOthersOnFail ? ['failure'] : []),
|
163 | maxProcesses: args.maxProcesses,
|
164 | raw: args.raw,
|
165 | prefix: args.prefix,
|
166 | prefixLength: args.prefixLength,
|
167 | restartDelay: args.restartAfter,
|
168 | restartTries: args.restartTries,
|
169 | successCondition: args.success,
|
170 | timestampFormat: args.timestampFormat
|
171 | }).then(
|
172 | () => process.exit(0),
|
173 | () => process.exit(1)
|
174 | );
|