concurrently 5.0.2 → 6.0.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/README.md +37 -22
- package/bin/concurrently.js +11 -2
- package/index.js +4 -1
- package/package.json +12 -12
- package/src/command-parser/expand-npm-shortcut.js +1 -1
- package/src/command-parser/expand-npm-wildcard.js +1 -1
- package/src/command.js +12 -2
- package/src/completion-listener.js +26 -22
- package/src/concurrently.js +33 -10
- package/src/defaults.js +5 -1
- package/src/flow-control/kill-on-signal.js +4 -3
- package/src/flow-control/kill-others.js +1 -1
- package/src/flow-control/log-exit.js +2 -2
- package/src/flow-control/restart-process.js +3 -3
- package/src/get-spawn-opts.js +8 -4
- package/src/logger.js +7 -2
package/README.md
CHANGED
|
@@ -10,11 +10,13 @@ Like `npm run watch-js & npm run watch-less` but better.
|
|
|
10
10
|

|
|
11
11
|
|
|
12
12
|
**Table of contents**
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
13
|
+
- [Concurrently](#concurrently)
|
|
14
|
+
- [Why](#why)
|
|
15
|
+
- [Install](#install)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Programmatic Usage](#programmatic-usage)
|
|
18
|
+
- [`concurrently(commands[, options])`](#concurrentlycommands-options)
|
|
19
|
+
- [FAQ](#faq)
|
|
18
20
|
|
|
19
21
|
## Why
|
|
20
22
|
|
|
@@ -113,18 +115,21 @@ Help:
|
|
|
113
115
|
concurrently [options] <command ...>
|
|
114
116
|
|
|
115
117
|
General
|
|
116
|
-
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
-m, --max-processes How many processes should run at once.
|
|
119
|
+
New processes only spawn after all restart tries of a
|
|
120
|
+
process. [number]
|
|
121
|
+
-n, --names List of custom names to be used in prefix template.
|
|
122
|
+
Example names: "main,browser,server" [string]
|
|
123
|
+
--name-separator The character to split <names> on. Example usage:
|
|
124
|
+
concurrently -n "styles|scripts|server" --name-separator
|
|
125
|
+
"|" [default: ","]
|
|
126
|
+
-r, --raw Output only raw output of processes, disables prettifying
|
|
127
|
+
and concurrently coloring. [boolean]
|
|
128
|
+
-s, --success Return exit code of zero or one based on the success or
|
|
129
|
+
failure of the "first" child to terminate, the "last
|
|
130
|
+
child", or succeed only if "all" child processes succeed.
|
|
126
131
|
[choices: "first", "last", "all"] [default: "all"]
|
|
127
|
-
--no-color
|
|
132
|
+
--no-color Disables colors from logging [boolean]
|
|
128
133
|
|
|
129
134
|
Prefix styling
|
|
130
135
|
-p, --prefix Prefix used in logging for each process.
|
|
@@ -137,7 +142,8 @@ Prefix styling
|
|
|
137
142
|
- Available modifiers: reset, bold, dim, italic,
|
|
138
143
|
underline, inverse, hidden, strikethrough
|
|
139
144
|
- Available colors: black, red, green, yellow, blue,
|
|
140
|
-
magenta, cyan, white, gray
|
|
145
|
+
magenta, cyan, white, gray, or any hex values for
|
|
146
|
+
colors, eg #23de43
|
|
141
147
|
- Available background colors: bgBlack, bgRed,
|
|
142
148
|
bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite
|
|
143
149
|
See https://www.npmjs.com/package/chalk for more
|
|
@@ -222,14 +228,17 @@ concurrently can be used programmatically by using the API documented below:
|
|
|
222
228
|
|
|
223
229
|
### `concurrently(commands[, options])`
|
|
224
230
|
- `commands`: an array of either strings (containing the commands to run) or objects
|
|
225
|
-
with the shape `{ command, name, prefixColor }`.
|
|
231
|
+
with the shape `{ command, name, prefixColor, env, cwd }`.
|
|
226
232
|
- `options` (optional): an object containing any of the below:
|
|
233
|
+
- `cwd`: the working directory to be used by all commands. Can be overriden per command.
|
|
234
|
+
Default: `process.cwd()`.
|
|
227
235
|
- `defaultInputTarget`: the default input target when reading from `inputStream`.
|
|
228
236
|
Default: `0`.
|
|
229
237
|
- `inputStream`: a [`Readable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_readable_streams)
|
|
230
238
|
to read the input from, eg `process.stdin`.
|
|
231
239
|
- `killOthers`: an array of exitting conditions that will cause a process to kill others.
|
|
232
240
|
Can contain any of `success` or `failure`.
|
|
241
|
+
- `maxProcesses`: how many processes should run at once.
|
|
233
242
|
- `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
|
|
234
243
|
to write logs to. Default: `process.stdout`.
|
|
235
244
|
- `prefix`: the prefix type to use when logging processes output.
|
|
@@ -247,7 +256,10 @@ concurrently can be used programmatically by using the API documented below:
|
|
|
247
256
|
to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
|
|
248
257
|
|
|
249
258
|
> Returns: a `Promise` that resolves if the run was successful (according to `successCondition` option),
|
|
250
|
-
> or rejects
|
|
259
|
+
> or rejects, containing an array of objects with information for each command that has been run, in the order
|
|
260
|
+
> that the commands terminated. The objects have the shape `{ command, index, exitCode }`, where `command` is the object
|
|
261
|
+
> passed in the `commands` array and `index` its index there. Default values (empty strings or objects) are returned for
|
|
262
|
+
> the fields that were not specified.
|
|
251
263
|
|
|
252
264
|
Example:
|
|
253
265
|
|
|
@@ -255,11 +267,14 @@ Example:
|
|
|
255
267
|
const concurrently = require('concurrently');
|
|
256
268
|
concurrently([
|
|
257
269
|
'npm:watch-*',
|
|
258
|
-
{ command: 'nodemon', name: 'server' }
|
|
270
|
+
{ command: 'nodemon', name: 'server' },
|
|
271
|
+
{ command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } },
|
|
272
|
+
{ command: 'watch', name: 'watch', cwd: path.resolve(__dirname, 'scripts/watchers')}
|
|
259
273
|
], {
|
|
260
274
|
prefix: 'name',
|
|
261
275
|
killOthers: ['failure', 'success'],
|
|
262
276
|
restartTries: 3,
|
|
277
|
+
cwd: path.resolve(__dirname, 'scripts'),
|
|
263
278
|
}).then(success, failure);
|
|
264
279
|
```
|
|
265
280
|
|
|
@@ -278,6 +293,6 @@ concurrently([
|
|
|
278
293
|
So *null* means the process didn't terminate normally. This will make **concurrent**
|
|
279
294
|
to return non-zero exit code too.
|
|
280
295
|
|
|
281
|
-
* Does this work with the npm-
|
|
296
|
+
* Does this work with the npm-replacements [yarn](https://github.com/yarnpkg/yarn) or [pnpm](https://pnpm.js.org/)?
|
|
282
297
|
|
|
283
|
-
Yes! In all examples above, you may replace "`npm`" with "`yarn`".
|
|
298
|
+
Yes! In all examples above, you may replace "`npm`" with "`yarn`" or "`pnpm`".
|
package/bin/concurrently.js
CHANGED
|
@@ -13,6 +13,13 @@ const args = yargs
|
|
|
13
13
|
.alias('v', 'version')
|
|
14
14
|
.options({
|
|
15
15
|
// General
|
|
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
|
+
},
|
|
16
23
|
'n': {
|
|
17
24
|
alias: 'names',
|
|
18
25
|
describe:
|
|
@@ -76,7 +83,8 @@ const args = yargs
|
|
|
76
83
|
'Comma-separated list of chalk colors to use on prefixes. ' +
|
|
77
84
|
'If there are more commands than colors, the last color will be repeated.\n' +
|
|
78
85
|
'- Available modifiers: reset, bold, dim, italic, underline, inverse, hidden, strikethrough\n' +
|
|
79
|
-
'- Available colors: black, red, green, yellow, blue, magenta, cyan, white, gray\n' +
|
|
86
|
+
'- Available colors: black, red, green, yellow, blue, magenta, cyan, white, gray \n' +
|
|
87
|
+
'or any hex values for colors, eg #23de43\n' +
|
|
80
88
|
'- Available background colors: bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite\n' +
|
|
81
89
|
'See https://www.npmjs.com/package/chalk for more information.',
|
|
82
90
|
default: defaults.prefixColors,
|
|
@@ -125,7 +133,7 @@ const args = yargs
|
|
|
125
133
|
'Can be either the index or the name of the process.'
|
|
126
134
|
}
|
|
127
135
|
})
|
|
128
|
-
.group(['n', 'name-separator', 'raw', 's', 'no-color'], 'General')
|
|
136
|
+
.group(['m', 'n', 'name-separator', 'raw', 's', 'no-color'], 'General')
|
|
129
137
|
.group(['p', 'c', 'l', 't'], 'Prefix styling')
|
|
130
138
|
.group(['i', 'default-input-target'], 'Input handling')
|
|
131
139
|
.group(['k', 'kill-others-on-fail'], 'Killing other processes')
|
|
@@ -152,6 +160,7 @@ concurrently(args._.map((command, index) => {
|
|
|
152
160
|
killOthers: args.killOthers
|
|
153
161
|
? ['success', 'failure']
|
|
154
162
|
: (args.killOthersOnFail ? ['failure'] : []),
|
|
163
|
+
maxProcesses: args.maxProcesses,
|
|
155
164
|
raw: args.raw,
|
|
156
165
|
prefix: args.prefix,
|
|
157
166
|
prefixLength: args.prefixLength,
|
package/index.js
CHANGED
|
@@ -19,8 +19,10 @@ module.exports = (commands, options = {}) => {
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
return concurrently(commands, {
|
|
22
|
+
maxProcesses: options.maxProcesses,
|
|
22
23
|
raw: options.raw,
|
|
23
24
|
successCondition: options.successCondition,
|
|
25
|
+
cwd: options.cwd,
|
|
24
26
|
controllers: [
|
|
25
27
|
new LogError({ logger }),
|
|
26
28
|
new LogOutput({ logger }),
|
|
@@ -30,7 +32,7 @@ module.exports = (commands, options = {}) => {
|
|
|
30
32
|
defaultInputTarget: options.defaultInputTarget,
|
|
31
33
|
inputStream: options.inputStream,
|
|
32
34
|
}),
|
|
33
|
-
new KillOnSignal(),
|
|
35
|
+
new KillOnSignal({ process }),
|
|
34
36
|
new RestartProcess({
|
|
35
37
|
logger,
|
|
36
38
|
delay: options.restartDelay,
|
|
@@ -47,6 +49,7 @@ module.exports = (commands, options = {}) => {
|
|
|
47
49
|
// Export all flow controllers and the main concurrently function,
|
|
48
50
|
// so that 3rd-parties can use them however they want
|
|
49
51
|
exports.concurrently = concurrently;
|
|
52
|
+
exports.Logger = Logger;
|
|
50
53
|
exports.InputHandler = InputHandler;
|
|
51
54
|
exports.KillOnSignal = KillOnSignal;
|
|
52
55
|
exports.KillOthers = KillOthers;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "concurrently",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Run commands concurrently",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"concurrently": "./bin/concurrently.js"
|
|
8
8
|
},
|
|
9
9
|
"engines": {
|
|
10
|
-
"node": ">=
|
|
10
|
+
"node": ">=10.0.0"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"lint": "eslint . --ignore-path .gitignore",
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
"author": "Kimmo Brunfeldt",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"chalk": "^
|
|
33
|
-
"date-fns": "^2.
|
|
34
|
-
"lodash": "^4.17.
|
|
35
|
-
"read-pkg": "^
|
|
36
|
-
"rxjs": "^6.
|
|
32
|
+
"chalk": "^4.1.0",
|
|
33
|
+
"date-fns": "^2.16.1",
|
|
34
|
+
"lodash": "^4.17.20",
|
|
35
|
+
"read-pkg": "^5.2.0",
|
|
36
|
+
"rxjs": "^6.6.3",
|
|
37
37
|
"spawn-command": "^0.0.2-1",
|
|
38
|
-
"supports-color": "^
|
|
38
|
+
"supports-color": "^8.1.0",
|
|
39
39
|
"tree-kill": "^1.2.2",
|
|
40
|
-
"yargs": "^
|
|
40
|
+
"yargs": "^16.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"coveralls": "^3.0
|
|
44
|
-
"eslint": "^
|
|
45
|
-
"jest": "^
|
|
43
|
+
"coveralls": "^3.1.0",
|
|
44
|
+
"eslint": "^7.17.0",
|
|
45
|
+
"jest": "^26.6.3",
|
|
46
46
|
"jest-create-mock-instance": "^1.1.0"
|
|
47
47
|
},
|
|
48
48
|
"files": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module.exports = class ExpandNpmShortcut {
|
|
2
2
|
parse(commandInfo) {
|
|
3
|
-
const [, npmCmd, cmdName, args] = commandInfo.command.match(/^(npm|yarn):(\S+)(.*)/) || [];
|
|
3
|
+
const [, npmCmd, cmdName, args] = commandInfo.command.match(/^(npm|yarn|pnpm):(\S+)(.*)/) || [];
|
|
4
4
|
if (!cmdName) {
|
|
5
5
|
return commandInfo;
|
|
6
6
|
}
|
|
@@ -7,7 +7,7 @@ module.exports = class ExpandNpmWildcard {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
parse(commandInfo) {
|
|
10
|
-
const [, npmCmd, cmdName, args] = commandInfo.command.match(/(npm|yarn) run (\S+)([^&]*)/) || [];
|
|
10
|
+
const [, npmCmd, cmdName, args] = commandInfo.command.match(/(npm|yarn|pnpm) run (\S+)([^&]*)/) || [];
|
|
11
11
|
const wildcardPosition = (cmdName || '').indexOf('*');
|
|
12
12
|
|
|
13
13
|
// If the regex didn't match an npm script, or it has no wildcard,
|
package/src/command.js
CHANGED
|
@@ -5,11 +5,12 @@ module.exports = class Command {
|
|
|
5
5
|
return !!this.process;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
constructor({ index, name, command, prefixColor, killProcess, spawn, spawnOpts }) {
|
|
8
|
+
constructor({ index, name, command, prefixColor, env, killProcess, spawn, spawnOpts }) {
|
|
9
9
|
this.index = index;
|
|
10
10
|
this.name = name;
|
|
11
11
|
this.command = command;
|
|
12
12
|
this.prefixColor = prefixColor;
|
|
13
|
+
this.env = env;
|
|
13
14
|
this.killProcess = killProcess;
|
|
14
15
|
this.spawn = spawn;
|
|
15
16
|
this.spawnOpts = spawnOpts;
|
|
@@ -31,7 +32,16 @@ module.exports = class Command {
|
|
|
31
32
|
});
|
|
32
33
|
Rx.fromEvent(child, 'close').subscribe(([exitCode, signal]) => {
|
|
33
34
|
this.process = undefined;
|
|
34
|
-
this.close.next(
|
|
35
|
+
this.close.next({
|
|
36
|
+
command: {
|
|
37
|
+
command: this.command,
|
|
38
|
+
name: this.name,
|
|
39
|
+
prefixColor: this.prefixColor,
|
|
40
|
+
env: this.env,
|
|
41
|
+
},
|
|
42
|
+
index: this.index,
|
|
43
|
+
exitCode: exitCode === null ? signal : exitCode,
|
|
44
|
+
});
|
|
35
45
|
});
|
|
36
46
|
child.stdout && pipeTo(Rx.fromEvent(child.stdout, 'data'), this.stdout);
|
|
37
47
|
child.stderr && pipeTo(Rx.fromEvent(child.stderr, 'data'), this.stderr);
|
|
@@ -7,29 +7,33 @@ module.exports = class CompletionListener {
|
|
|
7
7
|
this.scheduler = scheduler;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
case 'first':
|
|
19
|
-
return exitCodes[0] === 0;
|
|
10
|
+
isSuccess(exitCodes) {
|
|
11
|
+
switch (this.successCondition) {
|
|
12
|
+
/* eslint-disable indent */
|
|
13
|
+
case 'first':
|
|
14
|
+
return exitCodes[0] === 0;
|
|
15
|
+
|
|
16
|
+
case 'last':
|
|
17
|
+
return exitCodes[exitCodes.length - 1] === 0;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
default:
|
|
20
|
+
return exitCodes.every(exitCode => exitCode === 0);
|
|
21
|
+
/* eslint-enable indent */
|
|
22
|
+
}
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
listen(commands) {
|
|
26
|
+
const closeStreams = commands.map(command => command.close);
|
|
27
|
+
return Rx.merge(...closeStreams)
|
|
28
|
+
.pipe(
|
|
29
|
+
bufferCount(closeStreams.length),
|
|
30
|
+
switchMap(exitInfos =>
|
|
31
|
+
this.isSuccess(exitInfos.map(({ exitCode }) => exitCode))
|
|
32
|
+
? Rx.of(exitInfos, this.scheduler)
|
|
33
|
+
: Rx.throwError(exitInfos, this.scheduler)
|
|
34
|
+
),
|
|
35
|
+
take(1)
|
|
36
|
+
)
|
|
37
|
+
.toPromise();
|
|
34
38
|
}
|
|
35
39
|
};
|
package/src/concurrently.js
CHANGED
|
@@ -16,7 +16,8 @@ const defaults = {
|
|
|
16
16
|
spawn,
|
|
17
17
|
kill: treeKill,
|
|
18
18
|
raw: false,
|
|
19
|
-
controllers: []
|
|
19
|
+
controllers: [],
|
|
20
|
+
cwd: undefined,
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
module.exports = (commands, options) => {
|
|
@@ -31,17 +32,21 @@ module.exports = (commands, options) => {
|
|
|
31
32
|
new ExpandNpmWildcard()
|
|
32
33
|
];
|
|
33
34
|
|
|
34
|
-
const spawnOpts = getSpawnOpts({ raw: options.raw });
|
|
35
|
-
|
|
36
35
|
commands = _(commands)
|
|
37
36
|
.map(mapToCommandInfo)
|
|
38
37
|
.flatMap(command => parseCommand(command, commandParsers))
|
|
39
|
-
.map((command, index) => new Command(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
.map((command, index) => new Command(
|
|
39
|
+
Object.assign({
|
|
40
|
+
index,
|
|
41
|
+
spawnOpts: getSpawnOpts({
|
|
42
|
+
raw: options.raw,
|
|
43
|
+
env: command.env,
|
|
44
|
+
cwd: command.cwd || options.cwd,
|
|
45
|
+
}),
|
|
46
|
+
killProcess: options.kill,
|
|
47
|
+
spawn: options.spawn,
|
|
48
|
+
}, command)
|
|
49
|
+
))
|
|
45
50
|
.value();
|
|
46
51
|
|
|
47
52
|
commands = options.controllers.reduce(
|
|
@@ -49,7 +54,12 @@ module.exports = (commands, options) => {
|
|
|
49
54
|
commands
|
|
50
55
|
);
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
const commandsLeft = commands.slice();
|
|
58
|
+
const maxProcesses = Math.max(1, Number(options.maxProcesses) || commandsLeft.length);
|
|
59
|
+
for (let i = 0; i < maxProcesses; i++) {
|
|
60
|
+
maybeRunMore(commandsLeft);
|
|
61
|
+
}
|
|
62
|
+
|
|
53
63
|
return new CompletionListener({ successCondition: options.successCondition }).listen(commands);
|
|
54
64
|
};
|
|
55
65
|
|
|
@@ -58,6 +68,7 @@ function mapToCommandInfo(command) {
|
|
|
58
68
|
command: command.command || command,
|
|
59
69
|
name: command.name || '',
|
|
60
70
|
prefixColor: command.prefixColor || '',
|
|
71
|
+
env: command.env || {},
|
|
61
72
|
};
|
|
62
73
|
}
|
|
63
74
|
|
|
@@ -67,3 +78,15 @@ function parseCommand(command, parsers) {
|
|
|
67
78
|
_.castArray(command)
|
|
68
79
|
);
|
|
69
80
|
}
|
|
81
|
+
|
|
82
|
+
function maybeRunMore(commandsLeft) {
|
|
83
|
+
const command = commandsLeft.shift();
|
|
84
|
+
if (!command) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
command.start();
|
|
89
|
+
command.close.subscribe(() => {
|
|
90
|
+
maybeRunMore(commandsLeft);
|
|
91
|
+
});
|
|
92
|
+
}
|
package/src/defaults.js
CHANGED
|
@@ -8,6 +8,8 @@ module.exports = {
|
|
|
8
8
|
defaultInputTarget: 0,
|
|
9
9
|
// Whether process.stdin should be forwarded to child processes
|
|
10
10
|
handleInput: false,
|
|
11
|
+
// How many processes to run at once
|
|
12
|
+
maxProcesses: 0,
|
|
11
13
|
nameSeparator: ',',
|
|
12
14
|
// Which prefix style to use when logging processes output.
|
|
13
15
|
prefix: '',
|
|
@@ -23,5 +25,7 @@ module.exports = {
|
|
|
23
25
|
// Condition of success for concurrently itself.
|
|
24
26
|
success: 'all',
|
|
25
27
|
// Refer to https://date-fns.org/v2.0.1/docs/format
|
|
26
|
-
timestampFormat: 'yyyy-MM-dd HH:mm:ss.SSS'
|
|
28
|
+
timestampFormat: 'yyyy-MM-dd HH:mm:ss.SSS',
|
|
29
|
+
// Current working dir passed as option to spawn command. Default: process.cwd()
|
|
30
|
+
cwd: undefined
|
|
27
31
|
};
|
|
@@ -2,7 +2,7 @@ const { map } = require('rxjs/operators');
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
module.exports = class KillOnSignal {
|
|
5
|
-
constructor({ process
|
|
5
|
+
constructor({ process }) {
|
|
6
6
|
this.process = process;
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -16,8 +16,9 @@ module.exports = class KillOnSignal {
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
return commands.map(command => {
|
|
19
|
-
const closeStream = command.close.pipe(map(
|
|
20
|
-
|
|
19
|
+
const closeStream = command.close.pipe(map(exitInfo => {
|
|
20
|
+
const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
|
|
21
|
+
return Object.assign({}, exitInfo, { exitCode });
|
|
21
22
|
}));
|
|
22
23
|
return new Proxy(command, {
|
|
23
24
|
get(target, prop) {
|
|
@@ -18,7 +18,7 @@ module.exports = class KillOthers {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const closeStates = commands.map(command => command.close.pipe(
|
|
21
|
-
map(exitCode => exitCode === 0 ? 'success' : 'failure'),
|
|
21
|
+
map(({ exitCode }) => exitCode === 0 ? 'success' : 'failure'),
|
|
22
22
|
filter(state => conditions.includes(state))
|
|
23
23
|
));
|
|
24
24
|
|
|
@@ -4,8 +4,8 @@ module.exports = class LogExit {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
handle(commands) {
|
|
7
|
-
commands.forEach(command => command.close.subscribe(
|
|
8
|
-
this.logger.logCommandEvent(`${command.command} exited with code ${
|
|
7
|
+
commands.forEach(command => command.close.subscribe(({ exitCode }) => {
|
|
8
|
+
this.logger.logCommandEvent(`${command.command} exited with code ${exitCode}`, command);
|
|
9
9
|
}));
|
|
10
10
|
|
|
11
11
|
return commands;
|
|
@@ -18,7 +18,7 @@ module.exports = class RestartProcess {
|
|
|
18
18
|
|
|
19
19
|
commands.map(command => command.close.pipe(
|
|
20
20
|
take(this.tries),
|
|
21
|
-
takeWhile(
|
|
21
|
+
takeWhile(({ exitCode }) => exitCode !== 0)
|
|
22
22
|
)).map((failure, index) => Rx.merge(
|
|
23
23
|
// Delay the emission (so that the restarts happen on time),
|
|
24
24
|
// explicitly telling the subscriber that a restart is needed
|
|
@@ -36,9 +36,9 @@ module.exports = class RestartProcess {
|
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
38
|
return commands.map(command => {
|
|
39
|
-
const closeStream = command.close.pipe(filter((
|
|
39
|
+
const closeStream = command.close.pipe(filter(({ exitCode }, emission) => {
|
|
40
40
|
// We let all success codes pass, and failures only after restarting won't happen again
|
|
41
|
-
return
|
|
41
|
+
return exitCode === 0 || emission >= this.tries;
|
|
42
42
|
}));
|
|
43
43
|
|
|
44
44
|
return new Proxy(command, {
|
package/src/get-spawn-opts.js
CHANGED
|
@@ -2,11 +2,15 @@ const supportsColor = require('supports-color');
|
|
|
2
2
|
|
|
3
3
|
module.exports = ({
|
|
4
4
|
colorSupport = supportsColor.stdout,
|
|
5
|
+
cwd,
|
|
5
6
|
process = global.process,
|
|
6
|
-
raw = false
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
raw = false,
|
|
8
|
+
env = {},
|
|
9
|
+
}) => Object.assign(
|
|
10
|
+
{
|
|
11
|
+
cwd: cwd || process.cwd(),
|
|
12
|
+
},
|
|
9
13
|
raw && { stdio: 'inherit' },
|
|
10
14
|
/^win/.test(process.platform) && { detached: false },
|
|
11
|
-
|
|
15
|
+
{ env: Object.assign(colorSupport ? { FORCE_COLOR: colorSupport.level } : {}, process.env, env) }
|
|
12
16
|
);
|
package/src/logger.js
CHANGED
|
@@ -53,11 +53,16 @@ module.exports = class Logger {
|
|
|
53
53
|
return _.reduce(prefixes, (prev, val, key) => {
|
|
54
54
|
const keyRegex = new RegExp(_.escapeRegExp(`{${key}}`), 'g');
|
|
55
55
|
return prev.replace(keyRegex, val);
|
|
56
|
-
}, prefix)
|
|
56
|
+
}, prefix);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
colorText(command, text) {
|
|
60
|
-
|
|
60
|
+
let color;
|
|
61
|
+
if (command.prefixColor && command.prefixColor.startsWith('#')) {
|
|
62
|
+
color = chalk.hex(command.prefixColor);
|
|
63
|
+
} else {
|
|
64
|
+
color = _.get(chalk, command.prefixColor, chalk.gray.dim);
|
|
65
|
+
}
|
|
61
66
|
return color(text);
|
|
62
67
|
}
|
|
63
68
|
|