concurrently 7.2.1 → 7.4.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 +87 -69
- package/dist/bin/concurrently.js +16 -10
- package/dist/bin/epilogue.js +16 -15
- package/dist/src/command-parser/expand-arguments.d.ts +5 -1
- package/dist/src/command-parser/expand-arguments.js +3 -5
- package/dist/src/command-parser/expand-npm-shortcut.js +3 -3
- package/dist/src/command-parser/expand-npm-wildcard.js +12 -28
- package/dist/src/command-parser/strip-quotes.d.ts +5 -1
- package/dist/src/command-parser/strip-quotes.js +2 -3
- package/dist/src/command.d.ts +5 -2
- package/dist/src/command.js +8 -5
- package/dist/src/completion-listener.d.ts +2 -2
- package/dist/src/completion-listener.js +14 -15
- package/dist/src/concurrently.js +14 -11
- package/dist/src/flow-control/input-handler.d.ts +1 -1
- package/dist/src/flow-control/input-handler.js +10 -7
- package/dist/src/flow-control/kill-on-signal.js +5 -6
- package/dist/src/flow-control/kill-others.d.ts +1 -1
- package/dist/src/flow-control/kill-others.js +6 -8
- package/dist/src/flow-control/log-error.js +2 -3
- package/dist/src/flow-control/log-exit.js +1 -2
- package/dist/src/flow-control/log-output.js +3 -4
- package/dist/src/flow-control/log-timings.d.ts +3 -3
- package/dist/src/flow-control/log-timings.js +13 -13
- package/dist/src/flow-control/restart-process.d.ts +1 -1
- package/dist/src/flow-control/restart-process.js +11 -6
- package/dist/src/get-spawn-opts.d.ts +4 -1
- package/dist/src/get-spawn-opts.js +9 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/logger.d.ts +2 -2
- package/dist/src/logger.js +16 -13
- package/dist/src/output-writer.d.ts +1 -1
- package/dist/src/output-writer.js +8 -6
- package/index.js +5 -3
- package/index.mjs +5 -4
- package/package.json +44 -33
- package/dist/.DS_Store +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -24,9 +28,9 @@ const Rx = __importStar(require("rxjs"));
|
|
|
24
28
|
const operators_1 = require("rxjs/operators");
|
|
25
29
|
/**
|
|
26
30
|
* Provides logic to determine whether lists of commands ran successfully.
|
|
27
|
-
*/
|
|
31
|
+
*/
|
|
28
32
|
class CompletionListener {
|
|
29
|
-
constructor({ successCondition = 'all', scheduler }) {
|
|
33
|
+
constructor({ successCondition = 'all', scheduler, }) {
|
|
30
34
|
this.successCondition = successCondition;
|
|
31
35
|
this.scheduler = scheduler;
|
|
32
36
|
}
|
|
@@ -46,16 +50,14 @@ class CompletionListener {
|
|
|
46
50
|
// Note that a command's `name` is not necessarily unique,
|
|
47
51
|
// in which case all of them must meet the success condition.
|
|
48
52
|
const nameOrIndex = commandSyntaxMatch[1];
|
|
49
|
-
const targetCommandsEvents = events.filter(({ command, index }) =>
|
|
50
|
-
|| index === Number(nameOrIndex)));
|
|
53
|
+
const targetCommandsEvents = events.filter(({ command, index }) => command.name === nameOrIndex || index === Number(nameOrIndex));
|
|
51
54
|
if (this.successCondition.startsWith('!')) {
|
|
52
55
|
// All commands except the specified ones must exit succesfully
|
|
53
|
-
return events.every((event) =>
|
|
54
|
-
|| event.exitCode === 0));
|
|
56
|
+
return events.every((event) => targetCommandsEvents.includes(event) || event.exitCode === 0);
|
|
55
57
|
}
|
|
56
58
|
// Only the specified commands must exit succesfully
|
|
57
|
-
return targetCommandsEvents.length > 0
|
|
58
|
-
|
|
59
|
+
return (targetCommandsEvents.length > 0 &&
|
|
60
|
+
targetCommandsEvents.every((event) => event.exitCode === 0));
|
|
59
61
|
}
|
|
60
62
|
/**
|
|
61
63
|
* Given a list of commands, wait for all of them to exit and then evaluate their exit codes.
|
|
@@ -63,13 +65,10 @@ class CompletionListener {
|
|
|
63
65
|
* @returns A Promise that resolves if the success condition is met, or rejects otherwise.
|
|
64
66
|
*/
|
|
65
67
|
listen(commands) {
|
|
66
|
-
const closeStreams = commands.map(command => command.close);
|
|
67
|
-
return Rx.merge(...closeStreams)
|
|
68
|
-
.pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.switchMap)(exitInfos => this.isSuccess(exitInfos)
|
|
68
|
+
const closeStreams = commands.map((command) => command.close);
|
|
69
|
+
return Rx.lastValueFrom(Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.switchMap)((exitInfos) => this.isSuccess(exitInfos)
|
|
69
70
|
? Rx.of(exitInfos, this.scheduler)
|
|
70
|
-
: Rx.throwError(exitInfos, this.scheduler)), (0, operators_1.take)(1))
|
|
71
|
-
.toPromise();
|
|
71
|
+
: Rx.throwError(exitInfos, this.scheduler)), (0, operators_1.take)(1)));
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
exports.CompletionListener = CompletionListener;
|
|
75
|
-
;
|
package/dist/src/concurrently.js
CHANGED
|
@@ -44,14 +44,15 @@ function concurrently(baseCommands, baseOptions) {
|
|
|
44
44
|
let lastColor = '';
|
|
45
45
|
let commands = (0, lodash_1.default)(baseCommands)
|
|
46
46
|
.map(mapToCommandInfo)
|
|
47
|
-
.flatMap(command => parseCommand(command, commandParsers))
|
|
47
|
+
.flatMap((command) => parseCommand(command, commandParsers))
|
|
48
48
|
.map((command, index) => {
|
|
49
49
|
// Use documented behaviour of repeating last color when specifying more commands than colors
|
|
50
|
-
lastColor = options.prefixColors && options.prefixColors[index] || lastColor;
|
|
51
|
-
return new command_1.Command(
|
|
50
|
+
lastColor = (options.prefixColors && options.prefixColors[index]) || lastColor;
|
|
51
|
+
return new command_1.Command({
|
|
52
52
|
index,
|
|
53
53
|
prefixColor: lastColor,
|
|
54
|
-
|
|
54
|
+
...command,
|
|
55
|
+
}, (0, get_spawn_opts_1.getSpawnOpts)({
|
|
55
56
|
raw: options.raw,
|
|
56
57
|
env: command.env,
|
|
57
58
|
cwd: command.cwd || options.cwd,
|
|
@@ -66,7 +67,7 @@ function concurrently(baseCommands, baseOptions) {
|
|
|
66
67
|
};
|
|
67
68
|
}, { commands, onFinishCallbacks: [] });
|
|
68
69
|
commands = handleResult.commands;
|
|
69
|
-
if (options.logger) {
|
|
70
|
+
if (options.logger && options.outputStream) {
|
|
70
71
|
const outputWriter = new output_writer_1.OutputWriter({
|
|
71
72
|
outputStream: options.outputStream,
|
|
72
73
|
group: options.group,
|
|
@@ -90,7 +91,6 @@ function concurrently(baseCommands, baseOptions) {
|
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
93
|
exports.concurrently = concurrently;
|
|
93
|
-
;
|
|
94
94
|
function mapToCommandInfo(command) {
|
|
95
95
|
if (typeof command === 'string') {
|
|
96
96
|
return {
|
|
@@ -100,17 +100,20 @@ function mapToCommandInfo(command) {
|
|
|
100
100
|
cwd: '',
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
return
|
|
103
|
+
return {
|
|
104
104
|
command: command.command,
|
|
105
105
|
name: command.name || '',
|
|
106
106
|
env: command.env || {},
|
|
107
107
|
cwd: command.cwd || '',
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
...(command.prefixColor
|
|
109
|
+
? {
|
|
110
|
+
prefixColor: command.prefixColor,
|
|
111
|
+
}
|
|
112
|
+
: {}),
|
|
113
|
+
};
|
|
111
114
|
}
|
|
112
115
|
function parseCommand(command, parsers) {
|
|
113
|
-
return parsers.reduce((commands, parser) => lodash_1.default.flatMap(commands, command => parser.parse(command)), lodash_1.default.castArray(command));
|
|
116
|
+
return parsers.reduce((commands, parser) => lodash_1.default.flatMap(commands, (command) => parser.parse(command)), lodash_1.default.castArray(command));
|
|
114
117
|
}
|
|
115
118
|
function maybeRunMore(commandsLeft) {
|
|
116
119
|
const command = commandsLeft.shift();
|
|
@@ -17,7 +17,7 @@ export declare class InputHandler implements FlowController {
|
|
|
17
17
|
private readonly defaultInputTarget;
|
|
18
18
|
private readonly inputStream;
|
|
19
19
|
private readonly pauseInputStreamOnFinish;
|
|
20
|
-
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }: {
|
|
20
|
+
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }: {
|
|
21
21
|
inputStream: Readable;
|
|
22
22
|
logger: Logger;
|
|
23
23
|
defaultInputTarget?: CommandIdentifier;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -33,7 +37,7 @@ const defaults = __importStar(require("../defaults"));
|
|
|
33
37
|
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
|
34
38
|
*/
|
|
35
39
|
class InputHandler {
|
|
36
|
-
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }) {
|
|
40
|
+
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger, }) {
|
|
37
41
|
this.logger = logger;
|
|
38
42
|
this.defaultInputTarget = defaultInputTarget || defaults.defaultInputTarget;
|
|
39
43
|
this.inputStream = inputStream;
|
|
@@ -44,13 +48,13 @@ class InputHandler {
|
|
|
44
48
|
return { commands };
|
|
45
49
|
}
|
|
46
50
|
Rx.fromEvent(this.inputStream, 'data')
|
|
47
|
-
.pipe((0, operators_1.map)(data => data.toString()))
|
|
48
|
-
.subscribe(data => {
|
|
51
|
+
.pipe((0, operators_1.map)((data) => data.toString()))
|
|
52
|
+
.subscribe((data) => {
|
|
49
53
|
const dataParts = data.split(/:(.+)/);
|
|
50
54
|
const targetId = dataParts.length > 1 ? dataParts[0] : this.defaultInputTarget;
|
|
51
55
|
const input = dataParts[1] || data;
|
|
52
|
-
const command = commands.find(command =>
|
|
53
|
-
command.index.toString() === targetId.toString())
|
|
56
|
+
const command = commands.find((command) => command.name === targetId ||
|
|
57
|
+
command.index.toString() === targetId.toString());
|
|
54
58
|
if (command && command.stdin) {
|
|
55
59
|
command.stdin.write(input);
|
|
56
60
|
}
|
|
@@ -70,4 +74,3 @@ class InputHandler {
|
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
exports.InputHandler = InputHandler;
|
|
73
|
-
;
|
|
@@ -12,17 +12,17 @@ class KillOnSignal {
|
|
|
12
12
|
}
|
|
13
13
|
handle(commands) {
|
|
14
14
|
let caughtSignal;
|
|
15
|
-
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(signal => {
|
|
15
|
+
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach((signal) => {
|
|
16
16
|
this.process.on(signal, () => {
|
|
17
17
|
caughtSignal = signal;
|
|
18
|
-
commands.forEach(command => command.kill(signal));
|
|
18
|
+
commands.forEach((command) => command.kill(signal));
|
|
19
19
|
});
|
|
20
20
|
});
|
|
21
21
|
return {
|
|
22
|
-
commands: commands.map(command => {
|
|
23
|
-
const closeStream = command.close.pipe((0, operators_1.map)(exitInfo => {
|
|
22
|
+
commands: commands.map((command) => {
|
|
23
|
+
const closeStream = command.close.pipe((0, operators_1.map)((exitInfo) => {
|
|
24
24
|
const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
|
|
25
|
-
return
|
|
25
|
+
return { ...exitInfo, exitCode };
|
|
26
26
|
}));
|
|
27
27
|
return new Proxy(command, {
|
|
28
28
|
get(target, prop) {
|
|
@@ -34,4 +34,3 @@ class KillOnSignal {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
exports.KillOnSignal = KillOnSignal;
|
|
37
|
-
;
|
|
@@ -8,7 +8,7 @@ export declare type ProcessCloseCondition = 'failure' | 'success';
|
|
|
8
8
|
export declare class KillOthers implements FlowController {
|
|
9
9
|
private readonly logger;
|
|
10
10
|
private readonly conditions;
|
|
11
|
-
constructor({ logger, conditions }: {
|
|
11
|
+
constructor({ logger, conditions, }: {
|
|
12
12
|
logger: Logger;
|
|
13
13
|
conditions: ProcessCloseCondition | ProcessCloseCondition[];
|
|
14
14
|
});
|
|
@@ -10,26 +10,24 @@ const operators_1 = require("rxjs/operators");
|
|
|
10
10
|
* Sends a SIGTERM signal to all commands when one of the exits with a matching condition.
|
|
11
11
|
*/
|
|
12
12
|
class KillOthers {
|
|
13
|
-
constructor({ logger, conditions }) {
|
|
13
|
+
constructor({ logger, conditions, }) {
|
|
14
14
|
this.logger = logger;
|
|
15
15
|
this.conditions = lodash_1.default.castArray(conditions);
|
|
16
16
|
}
|
|
17
17
|
handle(commands) {
|
|
18
|
-
const conditions = this.conditions.filter(condition =>
|
|
19
|
-
condition === 'success'));
|
|
18
|
+
const conditions = this.conditions.filter((condition) => condition === 'failure' || condition === 'success');
|
|
20
19
|
if (!conditions.length) {
|
|
21
20
|
return { commands };
|
|
22
21
|
}
|
|
23
|
-
const closeStates = commands.map(command => command.close.pipe((0, operators_1.map)(({ exitCode }) => exitCode === 0 ? 'success' : 'failure'), (0, operators_1.filter)(state => conditions.includes(state))));
|
|
24
|
-
closeStates.forEach(closeState => closeState.subscribe(() => {
|
|
25
|
-
const killableCommands = commands.filter(command => command.killable);
|
|
22
|
+
const closeStates = commands.map((command) => command.close.pipe((0, operators_1.map)(({ exitCode }) => exitCode === 0 ? 'success' : 'failure'), (0, operators_1.filter)((state) => conditions.includes(state))));
|
|
23
|
+
closeStates.forEach((closeState) => closeState.subscribe(() => {
|
|
24
|
+
const killableCommands = commands.filter((command) => command.killable);
|
|
26
25
|
if (killableCommands.length) {
|
|
27
26
|
this.logger.logGlobalEvent('Sending SIGTERM to other processes..');
|
|
28
|
-
killableCommands.forEach(command => command.kill());
|
|
27
|
+
killableCommands.forEach((command) => command.kill());
|
|
29
28
|
}
|
|
30
29
|
}));
|
|
31
30
|
return { commands };
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
exports.KillOthers = KillOthers;
|
|
35
|
-
;
|
|
@@ -9,13 +9,12 @@ class LogError {
|
|
|
9
9
|
this.logger = logger;
|
|
10
10
|
}
|
|
11
11
|
handle(commands) {
|
|
12
|
-
commands.forEach(command => command.error.subscribe(event => {
|
|
12
|
+
commands.forEach((command) => command.error.subscribe((event) => {
|
|
13
13
|
this.logger.logCommandEvent(`Error occurred when executing command: ${command.command}`, command);
|
|
14
|
-
const errorText = String(event instanceof Error ?
|
|
14
|
+
const errorText = String(event instanceof Error ? event.stack || event : event);
|
|
15
15
|
this.logger.logCommandEvent(errorText, command);
|
|
16
16
|
}));
|
|
17
17
|
return { commands };
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
exports.LogError = LogError;
|
|
21
|
-
;
|
|
@@ -9,11 +9,10 @@ class LogExit {
|
|
|
9
9
|
this.logger = logger;
|
|
10
10
|
}
|
|
11
11
|
handle(commands) {
|
|
12
|
-
commands.forEach(command => command.close.subscribe(({ exitCode }) => {
|
|
12
|
+
commands.forEach((command) => command.close.subscribe(({ exitCode }) => {
|
|
13
13
|
this.logger.logCommandEvent(`${command.command} exited with code ${exitCode}`, command);
|
|
14
14
|
}));
|
|
15
15
|
return { commands };
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
exports.LogExit = LogExit;
|
|
19
|
-
;
|
|
@@ -9,12 +9,11 @@ class LogOutput {
|
|
|
9
9
|
this.logger = logger;
|
|
10
10
|
}
|
|
11
11
|
handle(commands) {
|
|
12
|
-
commands.forEach(command => {
|
|
13
|
-
command.stdout.subscribe(text => this.logger.logCommandText(text.toString(), command));
|
|
14
|
-
command.stderr.subscribe(text => this.logger.logCommandText(text.toString(), command));
|
|
12
|
+
commands.forEach((command) => {
|
|
13
|
+
command.stdout.subscribe((text) => this.logger.logCommandText(text.toString(), command));
|
|
14
|
+
command.stderr.subscribe((text) => this.logger.logCommandText(text.toString(), command));
|
|
15
15
|
});
|
|
16
16
|
return { commands };
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
exports.LogOutput = LogOutput;
|
|
20
|
-
;
|
|
@@ -12,14 +12,14 @@ interface TimingInfo {
|
|
|
12
12
|
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
|
13
13
|
*/
|
|
14
14
|
export declare class LogTimings implements FlowController {
|
|
15
|
-
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode }: CloseEvent): TimingInfo;
|
|
15
|
+
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }: CloseEvent): TimingInfo;
|
|
16
16
|
private readonly logger?;
|
|
17
17
|
private readonly timestampFormat;
|
|
18
|
-
constructor({ logger, timestampFormat }: {
|
|
18
|
+
constructor({ logger, timestampFormat, }: {
|
|
19
19
|
logger?: Logger;
|
|
20
20
|
timestampFormat?: string;
|
|
21
21
|
});
|
|
22
|
-
printExitInfoTimingTable
|
|
22
|
+
private printExitInfoTimingTable;
|
|
23
23
|
handle(commands: Command[]): {
|
|
24
24
|
commands: Command[];
|
|
25
25
|
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -32,11 +36,11 @@ const defaults = __importStar(require("../defaults"));
|
|
|
32
36
|
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
|
33
37
|
*/
|
|
34
38
|
class LogTimings {
|
|
35
|
-
constructor({ logger, timestampFormat = defaults.timestampFormat }) {
|
|
39
|
+
constructor({ logger, timestampFormat = defaults.timestampFormat, }) {
|
|
36
40
|
this.logger = logger;
|
|
37
41
|
this.timestampFormat = timestampFormat;
|
|
38
42
|
}
|
|
39
|
-
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode }) {
|
|
43
|
+
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }) {
|
|
40
44
|
const readableDurationMs = (timings.endDate.getTime() - timings.startDate.getTime()).toLocaleString();
|
|
41
45
|
return {
|
|
42
46
|
name: command.name,
|
|
@@ -47,42 +51,38 @@ class LogTimings {
|
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
53
|
printExitInfoTimingTable(exitInfos) {
|
|
50
|
-
var _a, _b;
|
|
51
54
|
const exitInfoTable = (0, lodash_1.default)(exitInfos)
|
|
52
55
|
.sortBy(({ timings }) => timings.durationSeconds)
|
|
53
56
|
.reverse()
|
|
54
57
|
.map(LogTimings.mapCloseEventToTimingInfo)
|
|
55
58
|
.value();
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
this.logger.logGlobalEvent('Timings:');
|
|
60
|
+
this.logger.logTable(exitInfoTable);
|
|
58
61
|
return exitInfos;
|
|
59
62
|
}
|
|
60
|
-
;
|
|
61
63
|
handle(commands) {
|
|
62
64
|
if (!this.logger) {
|
|
63
65
|
return { commands };
|
|
64
66
|
}
|
|
65
67
|
// individual process timings
|
|
66
|
-
commands.forEach(command => {
|
|
68
|
+
commands.forEach((command) => {
|
|
67
69
|
command.timer.subscribe(({ startDate, endDate }) => {
|
|
68
|
-
var _a, _b;
|
|
69
70
|
if (!endDate) {
|
|
70
71
|
const formattedStartDate = (0, format_1.default)(startDate, this.timestampFormat);
|
|
71
|
-
|
|
72
|
+
this.logger.logCommandEvent(`${command.command} started at ${formattedStartDate}`, command);
|
|
72
73
|
}
|
|
73
74
|
else {
|
|
74
75
|
const durationMs = endDate.getTime() - startDate.getTime();
|
|
75
76
|
const formattedEndDate = (0, format_1.default)(endDate, this.timestampFormat);
|
|
76
|
-
|
|
77
|
+
this.logger.logCommandEvent(`${command.command} stopped at ${formattedEndDate} after ${durationMs.toLocaleString()}ms`, command);
|
|
77
78
|
}
|
|
78
79
|
});
|
|
79
80
|
});
|
|
80
81
|
// overall summary timings
|
|
81
|
-
const closeStreams = commands.map(command => command.close);
|
|
82
|
+
const closeStreams = commands.map((command) => command.close);
|
|
82
83
|
const allProcessesClosed = Rx.merge(...closeStreams).pipe((0, operators_1.bufferCount)(closeStreams.length), (0, operators_1.take)(1));
|
|
83
84
|
allProcessesClosed.subscribe((exitInfos) => this.printExitInfoTimingTable(exitInfos));
|
|
84
85
|
return { commands };
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
exports.LogTimings = LogTimings;
|
|
88
|
-
;
|
|
@@ -10,7 +10,7 @@ export declare class RestartProcess implements FlowController {
|
|
|
10
10
|
private readonly scheduler?;
|
|
11
11
|
readonly delay: number;
|
|
12
12
|
readonly tries: number;
|
|
13
|
-
constructor({ delay, tries, logger, scheduler }: {
|
|
13
|
+
constructor({ delay, tries, logger, scheduler, }: {
|
|
14
14
|
delay?: number;
|
|
15
15
|
tries?: number;
|
|
16
16
|
logger: Logger;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -27,7 +31,7 @@ const defaults = __importStar(require("../defaults"));
|
|
|
27
31
|
* Restarts commands that fail up to a defined number of times.
|
|
28
32
|
*/
|
|
29
33
|
class RestartProcess {
|
|
30
|
-
constructor({ delay, tries, logger, scheduler }) {
|
|
34
|
+
constructor({ delay, tries, logger, scheduler, }) {
|
|
31
35
|
this.logger = logger;
|
|
32
36
|
this.delay = delay != null ? +delay : defaults.restartDelay;
|
|
33
37
|
this.tries = tries != null ? +tries : defaults.restartTries;
|
|
@@ -38,14 +42,16 @@ class RestartProcess {
|
|
|
38
42
|
if (this.tries === 0) {
|
|
39
43
|
return { commands };
|
|
40
44
|
}
|
|
41
|
-
commands
|
|
45
|
+
commands
|
|
46
|
+
.map((command) => command.close.pipe((0, operators_1.take)(this.tries), (0, operators_1.takeWhile)(({ exitCode }) => exitCode !== 0)))
|
|
47
|
+
.map((failure, index) => Rx.merge(
|
|
42
48
|
// Delay the emission (so that the restarts happen on time),
|
|
43
49
|
// explicitly telling the subscriber that a restart is needed
|
|
44
50
|
failure.pipe((0, operators_1.delay)(this.delay, this.scheduler), (0, operators_1.mapTo)(true)),
|
|
45
51
|
// Skip the first N emissions (as these would be duplicates of the above),
|
|
46
52
|
// meaning it will be empty because of success, or failed all N times,
|
|
47
53
|
// and no more restarts should be attempted.
|
|
48
|
-
failure.pipe((0, operators_1.skip)(this.tries), (0, operators_1.mapTo)(false), (0, operators_1.defaultIfEmpty)(false))).subscribe(restart => {
|
|
54
|
+
failure.pipe((0, operators_1.skip)(this.tries), (0, operators_1.mapTo)(false), (0, operators_1.defaultIfEmpty)(false))).subscribe((restart) => {
|
|
49
55
|
const command = commands[index];
|
|
50
56
|
if (restart) {
|
|
51
57
|
this.logger.logCommandEvent(`${command.command} restarted`, command);
|
|
@@ -53,7 +59,7 @@ class RestartProcess {
|
|
|
53
59
|
}
|
|
54
60
|
}));
|
|
55
61
|
return {
|
|
56
|
-
commands: commands.map(command => {
|
|
62
|
+
commands: commands.map((command) => {
|
|
57
63
|
const closeStream = command.close.pipe((0, operators_1.filter)(({ exitCode }, emission) => {
|
|
58
64
|
// We let all success codes pass, and failures only after restarting won't happen again
|
|
59
65
|
return exitCode === 0 || emission >= this.tries;
|
|
@@ -68,4 +74,3 @@ class RestartProcess {
|
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
exports.RestartProcess = RestartProcess;
|
|
71
|
-
;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
/// <reference types="node" />
|
|
2
5
|
import { SpawnOptions } from 'child_process';
|
|
3
6
|
import supportsColor from 'supports-color';
|
|
4
7
|
export declare const getSpawnOpts: ({ colorSupport, cwd, process, raw, env, }: {
|
|
@@ -26,5 +29,5 @@ export declare const getSpawnOpts: ({ colorSupport, cwd, process, raw, env, }: {
|
|
|
26
29
|
/**
|
|
27
30
|
* Map of custom environment variables to include in the spawn options.
|
|
28
31
|
*/
|
|
29
|
-
env?: Record<string,
|
|
32
|
+
env?: Record<string, unknown>;
|
|
30
33
|
}) => SpawnOptions;
|
|
@@ -5,7 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getSpawnOpts = void 0;
|
|
7
7
|
const supports_color_1 = __importDefault(require("supports-color"));
|
|
8
|
-
const getSpawnOpts = ({ colorSupport = supports_color_1.default.stdout, cwd, process = global.process, raw = false, env = {}, }) =>
|
|
8
|
+
const getSpawnOpts = ({ colorSupport = supports_color_1.default.stdout, cwd, process = global.process, raw = false, env = {}, }) => ({
|
|
9
9
|
cwd: cwd || process.cwd(),
|
|
10
|
-
|
|
10
|
+
...(raw && { stdio: 'inherit' }),
|
|
11
|
+
...(/^win/.test(process.platform) && { detached: false }),
|
|
12
|
+
env: {
|
|
13
|
+
...(colorSupport ? { FORCE_COLOR: colorSupport.level.toString() } : {}),
|
|
14
|
+
...process.env,
|
|
15
|
+
...env,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
11
18
|
exports.getSpawnOpts = getSpawnOpts;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -71,4 +71,4 @@ export declare type ConcurrentlyOptions = BaseConcurrentlyOptions & {
|
|
|
71
71
|
};
|
|
72
72
|
declare const _default: (commands: ConcurrentlyCommandInput[], options?: Partial<ConcurrentlyOptions>) => ConcurrentlyResult;
|
|
73
73
|
export default _default;
|
|
74
|
-
export {
|
|
74
|
+
export { CloseEvent, Command, CommandIdentifier, concurrently, ConcurrentlyCommandInput, ConcurrentlyResult, FlowController, InputHandler, KillOnSignal, KillOthers, LogError, LogExit, Logger, LogOutput, LogTimings, RestartProcess, TimerEvent, };
|
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RestartProcess = exports.LogTimings = exports.LogOutput = exports.LogExit = exports.LogError = exports.KillOthers = exports.KillOnSignal = exports.InputHandler = exports.
|
|
3
|
+
exports.RestartProcess = exports.LogTimings = exports.LogOutput = exports.Logger = exports.LogExit = exports.LogError = exports.KillOthers = exports.KillOnSignal = exports.InputHandler = exports.concurrently = exports.Command = void 0;
|
|
4
4
|
const command_1 = require("./command");
|
|
5
5
|
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
|
|
6
6
|
const concurrently_1 = require("./concurrently");
|
package/dist/src/logger.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare class Logger {
|
|
|
19
19
|
command: Command | undefined;
|
|
20
20
|
text: string;
|
|
21
21
|
}>;
|
|
22
|
-
constructor({ hide, prefixFormat, prefixLength, raw, timestampFormat }: {
|
|
22
|
+
constructor({ hide, prefixFormat, prefixLength, raw, timestampFormat, }: {
|
|
23
23
|
/**
|
|
24
24
|
* Which command(s) should have their output hidden.
|
|
25
25
|
*/
|
|
@@ -66,7 +66,7 @@ export declare class Logger {
|
|
|
66
66
|
*
|
|
67
67
|
* Each row is a single input item, and they are presented in the input order.
|
|
68
68
|
*/
|
|
69
|
-
logTable(tableContents:
|
|
69
|
+
logTable(tableContents: unknown[]): void;
|
|
70
70
|
log(prefix: string, text: string, command?: Command): void;
|
|
71
71
|
emit(command: Command | undefined, text: string): void;
|
|
72
72
|
}
|
package/dist/src/logger.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -24,12 +28,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
24
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
29
|
exports.Logger = void 0;
|
|
26
30
|
const chalk_1 = __importDefault(require("chalk"));
|
|
27
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
28
31
|
const format_1 = __importDefault(require("date-fns/format"));
|
|
32
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
29
33
|
const Rx = __importStar(require("rxjs"));
|
|
30
34
|
const defaults = __importStar(require("./defaults"));
|
|
31
35
|
class Logger {
|
|
32
|
-
constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat }) {
|
|
36
|
+
constructor({ hide, prefixFormat, prefixLength, raw = false, timestampFormat, }) {
|
|
33
37
|
/**
|
|
34
38
|
* Observable that emits when there's been output logged.
|
|
35
39
|
* If `command` is is `undefined`, then the log is for a global event.
|
|
@@ -38,7 +42,9 @@ class Logger {
|
|
|
38
42
|
// To avoid empty strings from hiding the output of commands that don't have a name,
|
|
39
43
|
// keep in the list of commands to hide only strings with some length.
|
|
40
44
|
// This might happen through the CLI when no `--hide` argument is specified, for example.
|
|
41
|
-
this.hide = lodash_1.default.castArray(hide)
|
|
45
|
+
this.hide = lodash_1.default.castArray(hide)
|
|
46
|
+
.filter((name) => name || name === 0)
|
|
47
|
+
.map(String);
|
|
42
48
|
this.raw = raw;
|
|
43
49
|
this.prefixFormat = prefixFormat;
|
|
44
50
|
this.prefixLength = prefixLength || defaults.prefixLength;
|
|
@@ -52,8 +58,8 @@ class Logger {
|
|
|
52
58
|
const prefixLength = this.prefixLength - ellipsis.length;
|
|
53
59
|
const endLength = Math.floor(prefixLength / 2);
|
|
54
60
|
const beginningLength = prefixLength - endLength;
|
|
55
|
-
const beginnning = text.
|
|
56
|
-
const end = text.
|
|
61
|
+
const beginnning = text.slice(0, beginningLength);
|
|
62
|
+
const end = text.slice(text.length - endLength, text.length);
|
|
57
63
|
return beginnning + ellipsis + end;
|
|
58
64
|
}
|
|
59
65
|
getPrefixesFor(command) {
|
|
@@ -131,7 +137,7 @@ class Logger {
|
|
|
131
137
|
}
|
|
132
138
|
let nextColIndex = 0;
|
|
133
139
|
const headers = {};
|
|
134
|
-
const contentRows = tableContents.map(row => {
|
|
140
|
+
const contentRows = tableContents.map((row) => {
|
|
135
141
|
const rowContents = [];
|
|
136
142
|
Object.keys(row).forEach((col) => {
|
|
137
143
|
if (!headers[col]) {
|
|
@@ -149,18 +155,16 @@ class Logger {
|
|
|
149
155
|
});
|
|
150
156
|
return rowContents;
|
|
151
157
|
});
|
|
152
|
-
const headersFormatted = Object
|
|
153
|
-
.keys(headers)
|
|
154
|
-
.map(header => header.padEnd(headers[header].length, ' '));
|
|
158
|
+
const headersFormatted = Object.keys(headers).map((header) => header.padEnd(headers[header].length, ' '));
|
|
155
159
|
if (!headersFormatted.length) {
|
|
156
160
|
// No columns exist.
|
|
157
161
|
return;
|
|
158
162
|
}
|
|
159
|
-
const borderRowFormatted = headersFormatted.map(header => '─'.padEnd(header.length, '─'));
|
|
163
|
+
const borderRowFormatted = headersFormatted.map((header) => '─'.padEnd(header.length, '─'));
|
|
160
164
|
this.logGlobalEvent(`┌─${borderRowFormatted.join('─┬─')}─┐`);
|
|
161
165
|
this.logGlobalEvent(`│ ${headersFormatted.join(' │ ')} │`);
|
|
162
166
|
this.logGlobalEvent(`├─${borderRowFormatted.join('─┼─')}─┤`);
|
|
163
|
-
contentRows.forEach(contentRow => {
|
|
167
|
+
contentRows.forEach((contentRow) => {
|
|
164
168
|
const contentRowFormatted = headersFormatted.map((header, colIndex) => {
|
|
165
169
|
// If the table was expanded after this row was processed, it won't have this column.
|
|
166
170
|
// Use an empty string in this case.
|
|
@@ -196,4 +200,3 @@ class Logger {
|
|
|
196
200
|
}
|
|
197
201
|
}
|
|
198
202
|
exports.Logger = Logger;
|
|
199
|
-
;
|
|
@@ -9,7 +9,7 @@ export declare class OutputWriter {
|
|
|
9
9
|
private readonly group;
|
|
10
10
|
readonly buffers: string[][];
|
|
11
11
|
activeCommandIndex: number;
|
|
12
|
-
constructor({ outputStream, group, commands }: {
|
|
12
|
+
constructor({ outputStream, group, commands, }: {
|
|
13
13
|
outputStream: Writable;
|
|
14
14
|
group: boolean;
|
|
15
15
|
commands: Command[];
|