concurrently 6.5.1 → 7.2.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 +133 -43
- package/dist/bin/concurrently.d.ts +2 -0
- package/dist/bin/concurrently.js +218 -0
- package/dist/bin/epilogue.d.ts +1 -0
- package/dist/bin/epilogue.js +81 -0
- package/dist/src/command-parser/command-parser.d.ts +19 -0
- package/dist/src/command-parser/command-parser.js +2 -0
- package/dist/src/command-parser/expand-arguments.d.ts +12 -0
- package/dist/src/command-parser/expand-arguments.js +40 -0
- package/dist/src/command-parser/expand-npm-shortcut.d.ts +8 -0
- package/dist/src/command-parser/expand-npm-shortcut.js +20 -0
- package/dist/src/command-parser/expand-npm-wildcard.d.ts +13 -0
- package/dist/src/command-parser/expand-npm-wildcard.js +82 -0
- package/dist/src/command-parser/strip-quotes.d.ts +10 -0
- package/dist/src/command-parser/strip-quotes.js +18 -0
- package/dist/src/command.d.ts +104 -0
- package/{src → dist/src}/command.js +54 -30
- package/dist/src/completion-listener.d.ts +39 -0
- package/dist/src/completion-listener.js +74 -0
- package/dist/src/concurrently.d.ts +90 -0
- package/dist/src/concurrently.js +124 -0
- package/dist/src/defaults.d.ts +62 -0
- package/dist/src/defaults.js +67 -0
- package/dist/src/flow-control/flow-controller.d.ts +13 -0
- package/dist/src/flow-control/flow-controller.js +2 -0
- package/dist/src/flow-control/input-handler.d.ts +33 -0
- package/dist/src/flow-control/input-handler.js +73 -0
- package/dist/src/flow-control/kill-on-signal.d.ts +17 -0
- package/{src → dist/src}/flow-control/kill-on-signal.js +15 -13
- package/dist/src/flow-control/kill-others.d.ts +18 -0
- package/dist/src/flow-control/kill-others.js +35 -0
- package/dist/src/flow-control/log-error.d.ts +15 -0
- package/dist/src/flow-control/log-error.js +21 -0
- package/dist/src/flow-control/log-exit.d.ts +15 -0
- package/dist/src/flow-control/log-exit.js +19 -0
- package/dist/src/flow-control/log-output.d.ts +15 -0
- package/{src → dist/src}/flow-control/log-output.js +13 -5
- package/dist/src/flow-control/log-timings.d.ts +27 -0
- package/dist/src/flow-control/log-timings.js +88 -0
- package/dist/src/flow-control/restart-process.d.ts +22 -0
- package/dist/src/flow-control/restart-process.js +71 -0
- package/dist/src/get-spawn-opts.d.ts +30 -0
- package/dist/src/get-spawn-opts.js +11 -0
- package/dist/src/index.d.ts +74 -0
- package/dist/src/index.js +70 -0
- package/dist/src/logger.d.ts +72 -0
- package/{src → dist/src}/logger.js +77 -58
- package/dist/src/output-writer.d.ts +19 -0
- package/dist/src/output-writer.js +69 -0
- package/index.js +6 -68
- package/index.mjs +9 -0
- package/package.json +42 -12
- package/bin/concurrently.js +0 -186
- package/bin/concurrently.spec.js +0 -428
- package/bin/epilogue.txt +0 -46
- package/src/command-parser/expand-npm-shortcut.js +0 -13
- package/src/command-parser/expand-npm-shortcut.spec.js +0 -36
- package/src/command-parser/expand-npm-wildcard.js +0 -52
- package/src/command-parser/expand-npm-wildcard.spec.js +0 -104
- package/src/command-parser/strip-quotes.js +0 -12
- package/src/command-parser/strip-quotes.spec.js +0 -20
- package/src/command.spec.js +0 -275
- package/src/completion-listener.js +0 -39
- package/src/completion-listener.spec.js +0 -89
- package/src/concurrently.js +0 -116
- package/src/concurrently.spec.js +0 -199
- package/src/defaults.js +0 -35
- package/src/flow-control/base-handler.js +0 -16
- package/src/flow-control/base-handler.spec.js +0 -22
- package/src/flow-control/input-handler.js +0 -50
- package/src/flow-control/input-handler.spec.js +0 -113
- package/src/flow-control/kill-on-signal.spec.js +0 -79
- package/src/flow-control/kill-others.js +0 -38
- package/src/flow-control/kill-others.spec.js +0 -66
- package/src/flow-control/log-error.js +0 -18
- package/src/flow-control/log-error.spec.js +0 -40
- package/src/flow-control/log-exit.js +0 -11
- package/src/flow-control/log-exit.spec.js +0 -36
- package/src/flow-control/log-output.spec.js +0 -41
- package/src/flow-control/log-timings.js +0 -64
- package/src/flow-control/log-timings.spec.js +0 -137
- package/src/flow-control/restart-process.js +0 -56
- package/src/flow-control/restart-process.spec.js +0 -139
- package/src/get-spawn-opts.js +0 -16
- package/src/get-spawn-opts.spec.js +0 -30
- package/src/logger.spec.js +0 -318
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.concurrently = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
+
const spawn_command_1 = __importDefault(require("spawn-command"));
|
|
10
|
+
const tree_kill_1 = __importDefault(require("tree-kill"));
|
|
11
|
+
const command_1 = require("./command");
|
|
12
|
+
const expand_arguments_1 = require("./command-parser/expand-arguments");
|
|
13
|
+
const expand_npm_shortcut_1 = require("./command-parser/expand-npm-shortcut");
|
|
14
|
+
const expand_npm_wildcard_1 = require("./command-parser/expand-npm-wildcard");
|
|
15
|
+
const strip_quotes_1 = require("./command-parser/strip-quotes");
|
|
16
|
+
const completion_listener_1 = require("./completion-listener");
|
|
17
|
+
const get_spawn_opts_1 = require("./get-spawn-opts");
|
|
18
|
+
const output_writer_1 = require("./output-writer");
|
|
19
|
+
const defaults = {
|
|
20
|
+
spawn: spawn_command_1.default,
|
|
21
|
+
kill: tree_kill_1.default,
|
|
22
|
+
raw: false,
|
|
23
|
+
controllers: [],
|
|
24
|
+
cwd: undefined,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Core concurrently functionality -- spawns the given commands concurrently and
|
|
28
|
+
* returns the commands themselves + the result according to the specified success condition.
|
|
29
|
+
*
|
|
30
|
+
* @see CompletionListener
|
|
31
|
+
*/
|
|
32
|
+
function concurrently(baseCommands, baseOptions) {
|
|
33
|
+
assert_1.default.ok(Array.isArray(baseCommands), '[concurrently] commands should be an array');
|
|
34
|
+
assert_1.default.notStrictEqual(baseCommands.length, 0, '[concurrently] no commands provided');
|
|
35
|
+
const options = lodash_1.default.defaults(baseOptions, defaults);
|
|
36
|
+
const commandParsers = [
|
|
37
|
+
new strip_quotes_1.StripQuotes(),
|
|
38
|
+
new expand_npm_shortcut_1.ExpandNpmShortcut(),
|
|
39
|
+
new expand_npm_wildcard_1.ExpandNpmWildcard(),
|
|
40
|
+
];
|
|
41
|
+
if (options.additionalArguments) {
|
|
42
|
+
commandParsers.push(new expand_arguments_1.ExpandArguments(options.additionalArguments));
|
|
43
|
+
}
|
|
44
|
+
let lastColor = '';
|
|
45
|
+
let commands = (0, lodash_1.default)(baseCommands)
|
|
46
|
+
.map(mapToCommandInfo)
|
|
47
|
+
.flatMap(command => parseCommand(command, commandParsers))
|
|
48
|
+
.map((command, index) => {
|
|
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(Object.assign({
|
|
52
|
+
index,
|
|
53
|
+
prefixColor: lastColor,
|
|
54
|
+
}, command), (0, get_spawn_opts_1.getSpawnOpts)({
|
|
55
|
+
raw: options.raw,
|
|
56
|
+
env: command.env,
|
|
57
|
+
cwd: command.cwd || options.cwd,
|
|
58
|
+
}), options.spawn, options.kill);
|
|
59
|
+
})
|
|
60
|
+
.value();
|
|
61
|
+
const handleResult = options.controllers.reduce(({ commands: prevCommands, onFinishCallbacks }, controller) => {
|
|
62
|
+
const { commands, onFinish } = controller.handle(prevCommands);
|
|
63
|
+
return {
|
|
64
|
+
commands,
|
|
65
|
+
onFinishCallbacks: lodash_1.default.concat(onFinishCallbacks, onFinish ? [onFinish] : []),
|
|
66
|
+
};
|
|
67
|
+
}, { commands, onFinishCallbacks: [] });
|
|
68
|
+
commands = handleResult.commands;
|
|
69
|
+
if (options.logger) {
|
|
70
|
+
const outputWriter = new output_writer_1.OutputWriter({
|
|
71
|
+
outputStream: options.outputStream,
|
|
72
|
+
group: options.group,
|
|
73
|
+
commands,
|
|
74
|
+
});
|
|
75
|
+
options.logger.output.subscribe(({ command, text }) => outputWriter.write(command, text));
|
|
76
|
+
}
|
|
77
|
+
const commandsLeft = commands.slice();
|
|
78
|
+
const maxProcesses = Math.max(1, Number(options.maxProcesses) || commandsLeft.length);
|
|
79
|
+
for (let i = 0; i < maxProcesses; i++) {
|
|
80
|
+
maybeRunMore(commandsLeft);
|
|
81
|
+
}
|
|
82
|
+
const result = new completion_listener_1.CompletionListener({ successCondition: options.successCondition })
|
|
83
|
+
.listen(commands)
|
|
84
|
+
.finally(() => {
|
|
85
|
+
handleResult.onFinishCallbacks.forEach((onFinish) => onFinish());
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
result,
|
|
89
|
+
commands,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
exports.concurrently = concurrently;
|
|
93
|
+
;
|
|
94
|
+
function mapToCommandInfo(command) {
|
|
95
|
+
if (typeof command === 'string') {
|
|
96
|
+
return {
|
|
97
|
+
command,
|
|
98
|
+
name: '',
|
|
99
|
+
env: {},
|
|
100
|
+
cwd: '',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return Object.assign({
|
|
104
|
+
command: command.command,
|
|
105
|
+
name: command.name || '',
|
|
106
|
+
env: command.env || {},
|
|
107
|
+
cwd: command.cwd || '',
|
|
108
|
+
}, command.prefixColor ? {
|
|
109
|
+
prefixColor: command.prefixColor,
|
|
110
|
+
} : {});
|
|
111
|
+
}
|
|
112
|
+
function parseCommand(command, parsers) {
|
|
113
|
+
return parsers.reduce((commands, parser) => lodash_1.default.flatMap(commands, command => parser.parse(command)), lodash_1.default.castArray(command));
|
|
114
|
+
}
|
|
115
|
+
function maybeRunMore(commandsLeft) {
|
|
116
|
+
const command = commandsLeft.shift();
|
|
117
|
+
if (!command) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
command.start();
|
|
121
|
+
command.close.subscribe(() => {
|
|
122
|
+
maybeRunMore(commandsLeft);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { SuccessCondition } from './completion-listener';
|
|
2
|
+
export declare const defaultInputTarget = 0;
|
|
3
|
+
/**
|
|
4
|
+
* Whether process.stdin should be forwarded to child processes.
|
|
5
|
+
*/
|
|
6
|
+
export declare const handleInput = false;
|
|
7
|
+
/**
|
|
8
|
+
* How many processes to run at once.
|
|
9
|
+
*/
|
|
10
|
+
export declare const maxProcesses = 0;
|
|
11
|
+
/**
|
|
12
|
+
* Indices and names of commands whose output are not to be logged.
|
|
13
|
+
*/
|
|
14
|
+
export declare const hide = "";
|
|
15
|
+
/**
|
|
16
|
+
* The character to split <names> on.
|
|
17
|
+
*/
|
|
18
|
+
export declare const nameSeparator = ",";
|
|
19
|
+
/**
|
|
20
|
+
* Which prefix style to use when logging processes output.
|
|
21
|
+
*/
|
|
22
|
+
export declare const prefix = "";
|
|
23
|
+
/**
|
|
24
|
+
* Default prefix color.
|
|
25
|
+
* @see https://www.npmjs.com/package/chalk
|
|
26
|
+
*/
|
|
27
|
+
export declare const prefixColors = "reset";
|
|
28
|
+
/**
|
|
29
|
+
* How many bytes we'll show on the command prefix.
|
|
30
|
+
*/
|
|
31
|
+
export declare const prefixLength = 10;
|
|
32
|
+
export declare const raw = false;
|
|
33
|
+
/**
|
|
34
|
+
* Number of attempts of restarting a process, if it exits with non-0 code.
|
|
35
|
+
*/
|
|
36
|
+
export declare const restartTries = 0;
|
|
37
|
+
/**
|
|
38
|
+
* How many milliseconds concurrently should wait before restarting a process.
|
|
39
|
+
*/
|
|
40
|
+
export declare const restartDelay = 0;
|
|
41
|
+
/**
|
|
42
|
+
* Condition of success for concurrently itself.
|
|
43
|
+
*/
|
|
44
|
+
export declare const success: SuccessCondition;
|
|
45
|
+
/**
|
|
46
|
+
* Date format used when logging date/time.
|
|
47
|
+
* @see https://date-fns.org/v2.0.1/docs/format
|
|
48
|
+
*/
|
|
49
|
+
export declare const timestampFormat = "yyyy-MM-dd HH:mm:ss.SSS";
|
|
50
|
+
/**
|
|
51
|
+
* Current working dir passed as option to spawn command.
|
|
52
|
+
* Defaults to process.cwd()
|
|
53
|
+
*/
|
|
54
|
+
export declare const cwd: string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Whether to show timing information for processes in console output.
|
|
57
|
+
*/
|
|
58
|
+
export declare const timings = false;
|
|
59
|
+
/**
|
|
60
|
+
* Passthrough additional arguments to commands (accessible via placeholders) instead of treating them as commands.
|
|
61
|
+
*/
|
|
62
|
+
export declare const passthroughArguments = false;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This file is meant to be a shared place for default configs.
|
|
3
|
+
// It's read by the flow controllers, the executable, etc.
|
|
4
|
+
// Refer to tests for the meaning of the different possible values.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.passthroughArguments = exports.timings = exports.cwd = exports.timestampFormat = exports.success = exports.restartDelay = exports.restartTries = exports.raw = exports.prefixLength = exports.prefixColors = exports.prefix = exports.nameSeparator = exports.hide = exports.maxProcesses = exports.handleInput = exports.defaultInputTarget = void 0;
|
|
7
|
+
exports.defaultInputTarget = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Whether process.stdin should be forwarded to child processes.
|
|
10
|
+
*/
|
|
11
|
+
exports.handleInput = false;
|
|
12
|
+
/**
|
|
13
|
+
* How many processes to run at once.
|
|
14
|
+
*/
|
|
15
|
+
exports.maxProcesses = 0;
|
|
16
|
+
/**
|
|
17
|
+
* Indices and names of commands whose output are not to be logged.
|
|
18
|
+
*/
|
|
19
|
+
exports.hide = '';
|
|
20
|
+
/**
|
|
21
|
+
* The character to split <names> on.
|
|
22
|
+
*/
|
|
23
|
+
exports.nameSeparator = ',';
|
|
24
|
+
/**
|
|
25
|
+
* Which prefix style to use when logging processes output.
|
|
26
|
+
*/
|
|
27
|
+
exports.prefix = '';
|
|
28
|
+
/**
|
|
29
|
+
* Default prefix color.
|
|
30
|
+
* @see https://www.npmjs.com/package/chalk
|
|
31
|
+
*/
|
|
32
|
+
exports.prefixColors = 'reset';
|
|
33
|
+
/**
|
|
34
|
+
* How many bytes we'll show on the command prefix.
|
|
35
|
+
*/
|
|
36
|
+
exports.prefixLength = 10;
|
|
37
|
+
exports.raw = false;
|
|
38
|
+
/**
|
|
39
|
+
* Number of attempts of restarting a process, if it exits with non-0 code.
|
|
40
|
+
*/
|
|
41
|
+
exports.restartTries = 0;
|
|
42
|
+
/**
|
|
43
|
+
* How many milliseconds concurrently should wait before restarting a process.
|
|
44
|
+
*/
|
|
45
|
+
exports.restartDelay = 0;
|
|
46
|
+
/**
|
|
47
|
+
* Condition of success for concurrently itself.
|
|
48
|
+
*/
|
|
49
|
+
exports.success = 'all';
|
|
50
|
+
/**
|
|
51
|
+
* Date format used when logging date/time.
|
|
52
|
+
* @see https://date-fns.org/v2.0.1/docs/format
|
|
53
|
+
*/
|
|
54
|
+
exports.timestampFormat = 'yyyy-MM-dd HH:mm:ss.SSS';
|
|
55
|
+
/**
|
|
56
|
+
* Current working dir passed as option to spawn command.
|
|
57
|
+
* Defaults to process.cwd()
|
|
58
|
+
*/
|
|
59
|
+
exports.cwd = undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Whether to show timing information for processes in console output.
|
|
62
|
+
*/
|
|
63
|
+
exports.timings = false;
|
|
64
|
+
/**
|
|
65
|
+
* Passthrough additional arguments to commands (accessible via placeholders) instead of treating them as commands.
|
|
66
|
+
*/
|
|
67
|
+
exports.passthroughArguments = false;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from '../command';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for a class that controls and/or watches the behavior of commands.
|
|
4
|
+
*
|
|
5
|
+
* This may include logging their output, creating interactions between them, or changing when they
|
|
6
|
+
* actually finish.
|
|
7
|
+
*/
|
|
8
|
+
export interface FlowController {
|
|
9
|
+
handle(commands: Command[]): {
|
|
10
|
+
commands: Command[];
|
|
11
|
+
onFinish?: () => void;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Readable } from 'stream';
|
|
3
|
+
import { Command, CommandIdentifier } from '../command';
|
|
4
|
+
import { Logger } from '../logger';
|
|
5
|
+
import { FlowController } from './flow-controller';
|
|
6
|
+
/**
|
|
7
|
+
* Sends input from concurrently through to commands.
|
|
8
|
+
*
|
|
9
|
+
* Input can start with a command identifier, in which case it will be sent to that specific command.
|
|
10
|
+
* For instance, `0:bla` will send `bla` to command at index `0`, and `server:stop` will send `stop`
|
|
11
|
+
* to command with name `server`.
|
|
12
|
+
*
|
|
13
|
+
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
|
14
|
+
*/
|
|
15
|
+
export declare class InputHandler implements FlowController {
|
|
16
|
+
private readonly logger;
|
|
17
|
+
private readonly defaultInputTarget;
|
|
18
|
+
private readonly inputStream;
|
|
19
|
+
private readonly pauseInputStreamOnFinish;
|
|
20
|
+
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }: {
|
|
21
|
+
inputStream: Readable;
|
|
22
|
+
logger: Logger;
|
|
23
|
+
defaultInputTarget?: CommandIdentifier;
|
|
24
|
+
pauseInputStreamOnFinish?: boolean;
|
|
25
|
+
});
|
|
26
|
+
handle(commands: Command[]): {
|
|
27
|
+
commands: Command[];
|
|
28
|
+
onFinish?: undefined;
|
|
29
|
+
} | {
|
|
30
|
+
commands: Command[];
|
|
31
|
+
onFinish: () => void;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.InputHandler = void 0;
|
|
23
|
+
const Rx = __importStar(require("rxjs"));
|
|
24
|
+
const operators_1 = require("rxjs/operators");
|
|
25
|
+
const defaults = __importStar(require("../defaults"));
|
|
26
|
+
/**
|
|
27
|
+
* Sends input from concurrently through to commands.
|
|
28
|
+
*
|
|
29
|
+
* Input can start with a command identifier, in which case it will be sent to that specific command.
|
|
30
|
+
* For instance, `0:bla` will send `bla` to command at index `0`, and `server:stop` will send `stop`
|
|
31
|
+
* to command with name `server`.
|
|
32
|
+
*
|
|
33
|
+
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
|
34
|
+
*/
|
|
35
|
+
class InputHandler {
|
|
36
|
+
constructor({ defaultInputTarget, inputStream, pauseInputStreamOnFinish, logger }) {
|
|
37
|
+
this.logger = logger;
|
|
38
|
+
this.defaultInputTarget = defaultInputTarget || defaults.defaultInputTarget;
|
|
39
|
+
this.inputStream = inputStream;
|
|
40
|
+
this.pauseInputStreamOnFinish = pauseInputStreamOnFinish !== false;
|
|
41
|
+
}
|
|
42
|
+
handle(commands) {
|
|
43
|
+
if (!this.inputStream) {
|
|
44
|
+
return { commands };
|
|
45
|
+
}
|
|
46
|
+
Rx.fromEvent(this.inputStream, 'data')
|
|
47
|
+
.pipe((0, operators_1.map)(data => data.toString()))
|
|
48
|
+
.subscribe(data => {
|
|
49
|
+
const dataParts = data.split(/:(.+)/);
|
|
50
|
+
const targetId = dataParts.length > 1 ? dataParts[0] : this.defaultInputTarget;
|
|
51
|
+
const input = dataParts[1] || data;
|
|
52
|
+
const command = commands.find(command => (command.name === targetId ||
|
|
53
|
+
command.index.toString() === targetId.toString()));
|
|
54
|
+
if (command && command.stdin) {
|
|
55
|
+
command.stdin.write(input);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.logger.logGlobalEvent(`Unable to find command ${targetId}, or it has no stdin open\n`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
commands,
|
|
63
|
+
onFinish: () => {
|
|
64
|
+
if (this.pauseInputStreamOnFinish) {
|
|
65
|
+
// https://github.com/kimmobrunfeldt/concurrently/issues/252
|
|
66
|
+
this.inputStream.pause();
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.InputHandler = InputHandler;
|
|
73
|
+
;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import { Command } from '../command';
|
|
4
|
+
import { FlowController } from './flow-controller';
|
|
5
|
+
/**
|
|
6
|
+
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
|
7
|
+
* command.
|
|
8
|
+
*/
|
|
9
|
+
export declare class KillOnSignal implements FlowController {
|
|
10
|
+
private readonly process;
|
|
11
|
+
constructor({ process }: {
|
|
12
|
+
process: EventEmitter;
|
|
13
|
+
});
|
|
14
|
+
handle(commands: Command[]): {
|
|
15
|
+
commands: Command[];
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KillOnSignal = void 0;
|
|
4
|
+
const operators_1 = require("rxjs/operators");
|
|
5
|
+
/**
|
|
6
|
+
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
|
7
|
+
* command.
|
|
8
|
+
*/
|
|
9
|
+
class KillOnSignal {
|
|
6
10
|
constructor({ process }) {
|
|
7
|
-
super();
|
|
8
|
-
|
|
9
11
|
this.process = process;
|
|
10
12
|
}
|
|
11
|
-
|
|
12
13
|
handle(commands) {
|
|
13
14
|
let caughtSignal;
|
|
14
15
|
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(signal => {
|
|
@@ -17,19 +18,20 @@ module.exports = class KillOnSignal extends BaseHandler {
|
|
|
17
18
|
commands.forEach(command => command.kill(signal));
|
|
18
19
|
});
|
|
19
20
|
});
|
|
20
|
-
|
|
21
21
|
return {
|
|
22
22
|
commands: commands.map(command => {
|
|
23
|
-
const closeStream = command.close.pipe(map(exitInfo => {
|
|
23
|
+
const closeStream = command.close.pipe((0, operators_1.map)(exitInfo => {
|
|
24
24
|
const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
|
|
25
25
|
return Object.assign({}, exitInfo, { exitCode });
|
|
26
26
|
}));
|
|
27
27
|
return new Proxy(command, {
|
|
28
28
|
get(target, prop) {
|
|
29
29
|
return prop === 'close' ? closeStream : target[prop];
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
31
|
});
|
|
32
|
-
})
|
|
32
|
+
}),
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
|
+
exports.KillOnSignal = KillOnSignal;
|
|
37
|
+
;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from '../command';
|
|
2
|
+
import { Logger } from '../logger';
|
|
3
|
+
import { FlowController } from './flow-controller';
|
|
4
|
+
export declare type ProcessCloseCondition = 'failure' | 'success';
|
|
5
|
+
/**
|
|
6
|
+
* Sends a SIGTERM signal to all commands when one of the exits with a matching condition.
|
|
7
|
+
*/
|
|
8
|
+
export declare class KillOthers implements FlowController {
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private readonly conditions;
|
|
11
|
+
constructor({ logger, conditions }: {
|
|
12
|
+
logger: Logger;
|
|
13
|
+
conditions: ProcessCloseCondition | ProcessCloseCondition[];
|
|
14
|
+
});
|
|
15
|
+
handle(commands: Command[]): {
|
|
16
|
+
commands: Command[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.KillOthers = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
+
const operators_1 = require("rxjs/operators");
|
|
9
|
+
/**
|
|
10
|
+
* Sends a SIGTERM signal to all commands when one of the exits with a matching condition.
|
|
11
|
+
*/
|
|
12
|
+
class KillOthers {
|
|
13
|
+
constructor({ logger, conditions }) {
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
this.conditions = lodash_1.default.castArray(conditions);
|
|
16
|
+
}
|
|
17
|
+
handle(commands) {
|
|
18
|
+
const conditions = this.conditions.filter(condition => (condition === 'failure' ||
|
|
19
|
+
condition === 'success'));
|
|
20
|
+
if (!conditions.length) {
|
|
21
|
+
return { commands };
|
|
22
|
+
}
|
|
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);
|
|
26
|
+
if (killableCommands.length) {
|
|
27
|
+
this.logger.logGlobalEvent('Sending SIGTERM to other processes..');
|
|
28
|
+
killableCommands.forEach(command => command.kill());
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
return { commands };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.KillOthers = KillOthers;
|
|
35
|
+
;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '../command';
|
|
2
|
+
import { Logger } from '../logger';
|
|
3
|
+
import { FlowController } from './flow-controller';
|
|
4
|
+
/**
|
|
5
|
+
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LogError implements FlowController {
|
|
8
|
+
private readonly logger;
|
|
9
|
+
constructor({ logger }: {
|
|
10
|
+
logger: Logger;
|
|
11
|
+
});
|
|
12
|
+
handle(commands: Command[]): {
|
|
13
|
+
commands: Command[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
|
6
|
+
*/
|
|
7
|
+
class LogError {
|
|
8
|
+
constructor({ logger }) {
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
handle(commands) {
|
|
12
|
+
commands.forEach(command => command.error.subscribe(event => {
|
|
13
|
+
this.logger.logCommandEvent(`Error occurred when executing command: ${command.command}`, command);
|
|
14
|
+
const errorText = String(event instanceof Error ? (event.stack || event) : event);
|
|
15
|
+
this.logger.logCommandEvent(errorText, command);
|
|
16
|
+
}));
|
|
17
|
+
return { commands };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.LogError = LogError;
|
|
21
|
+
;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '../command';
|
|
2
|
+
import { Logger } from '../logger';
|
|
3
|
+
import { FlowController } from './flow-controller';
|
|
4
|
+
/**
|
|
5
|
+
* Logs the exit code/signal of commands.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LogExit implements FlowController {
|
|
8
|
+
private readonly logger;
|
|
9
|
+
constructor({ logger }: {
|
|
10
|
+
logger: Logger;
|
|
11
|
+
});
|
|
12
|
+
handle(commands: Command[]): {
|
|
13
|
+
commands: Command[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogExit = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Logs the exit code/signal of commands.
|
|
6
|
+
*/
|
|
7
|
+
class LogExit {
|
|
8
|
+
constructor({ logger }) {
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
handle(commands) {
|
|
12
|
+
commands.forEach(command => command.close.subscribe(({ exitCode }) => {
|
|
13
|
+
this.logger.logCommandEvent(`${command.command} exited with code ${exitCode}`, command);
|
|
14
|
+
}));
|
|
15
|
+
return { commands };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.LogExit = LogExit;
|
|
19
|
+
;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '../command';
|
|
2
|
+
import { Logger } from '../logger';
|
|
3
|
+
import { FlowController } from './flow-controller';
|
|
4
|
+
/**
|
|
5
|
+
* Logs the stdout and stderr output of commands.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LogOutput implements FlowController {
|
|
8
|
+
private readonly logger;
|
|
9
|
+
constructor({ logger }: {
|
|
10
|
+
logger: Logger;
|
|
11
|
+
});
|
|
12
|
+
handle(commands: Command[]): {
|
|
13
|
+
commands: Command[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogOutput = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Logs the stdout and stderr output of commands.
|
|
6
|
+
*/
|
|
7
|
+
class LogOutput {
|
|
8
|
+
constructor({ logger }) {
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
4
11
|
handle(commands) {
|
|
5
12
|
commands.forEach(command => {
|
|
6
13
|
command.stdout.subscribe(text => this.logger.logCommandText(text.toString(), command));
|
|
7
14
|
command.stderr.subscribe(text => this.logger.logCommandText(text.toString(), command));
|
|
8
15
|
});
|
|
9
|
-
|
|
10
16
|
return { commands };
|
|
11
17
|
}
|
|
12
|
-
}
|
|
18
|
+
}
|
|
19
|
+
exports.LogOutput = LogOutput;
|
|
20
|
+
;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CloseEvent, Command } from '../command';
|
|
2
|
+
import { Logger } from '../logger';
|
|
3
|
+
import { FlowController } from './flow-controller';
|
|
4
|
+
interface TimingInfo {
|
|
5
|
+
name: string;
|
|
6
|
+
duration: string;
|
|
7
|
+
'exit code': string | number;
|
|
8
|
+
killed: boolean;
|
|
9
|
+
command: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LogTimings implements FlowController {
|
|
15
|
+
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode }: CloseEvent): TimingInfo;
|
|
16
|
+
private readonly logger?;
|
|
17
|
+
private readonly timestampFormat;
|
|
18
|
+
constructor({ logger, timestampFormat }: {
|
|
19
|
+
logger?: Logger;
|
|
20
|
+
timestampFormat?: string;
|
|
21
|
+
});
|
|
22
|
+
printExitInfoTimingTable(exitInfos: CloseEvent[]): CloseEvent[];
|
|
23
|
+
handle(commands: Command[]): {
|
|
24
|
+
commands: Command[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export {};
|