concurrently 9.2.1 → 10.0.1
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 +25 -14
- package/dist/bin/bin-options.d.ts +1 -0
- package/dist/bin/bin-options.js +1 -0
- package/dist/bin/{concurrently.js → index.js} +23 -62
- package/dist/bin/normalize-cli-command.d.ts +1 -0
- package/dist/bin/normalize-cli-command.js +15 -0
- package/dist/bin/read-package-json.d.ts +4 -0
- package/dist/bin/read-package-json.js +17 -0
- package/dist/lib/assert.d.ts +10 -0
- package/dist/lib/assert.js +24 -0
- package/dist/{src → lib}/command-parser/expand-arguments.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-arguments.js +7 -12
- package/dist/{src → lib}/command-parser/expand-shortcut.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-shortcut.js +1 -5
- package/dist/{src → lib}/command-parser/expand-wildcard.d.ts +2 -2
- package/dist/{src → lib}/command-parser/expand-wildcard.js +21 -28
- package/dist/{src → lib}/command.d.ts +5 -4
- package/dist/{src → lib}/command.js +3 -39
- package/dist/{src → lib}/completion-listener.d.ts +2 -2
- package/dist/{src → lib}/completion-listener.js +9 -46
- package/dist/{src → lib}/concurrently.d.ts +10 -10
- package/dist/{src → lib}/concurrently.js +29 -40
- package/dist/{src → lib}/date-format.d.ts +2 -2
- package/dist/{src → lib}/date-format.js +97 -76
- package/dist/{src → lib}/defaults.d.ts +2 -6
- package/dist/{src → lib}/defaults.js +16 -23
- package/dist/{src → lib}/flow-control/flow-controller.d.ts +1 -1
- package/dist/lib/flow-control/flow-controller.js +1 -0
- package/dist/{src → lib}/flow-control/input-handler.d.ts +4 -4
- package/dist/{src → lib}/flow-control/input-handler.js +8 -44
- package/dist/{src → lib}/flow-control/kill-on-signal.d.ts +3 -3
- package/dist/{src → lib}/flow-control/kill-on-signal.js +3 -7
- package/dist/{src → lib}/flow-control/kill-others.d.ts +3 -3
- package/dist/{src → lib}/flow-control/kill-others.js +8 -12
- package/dist/{src → lib}/flow-control/log-error.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-error.js +1 -5
- package/dist/{src → lib}/flow-control/log-exit.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-exit.js +1 -5
- package/dist/{src → lib}/flow-control/log-output.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-output.js +1 -5
- package/dist/{src → lib}/flow-control/log-timings.d.ts +3 -3
- package/dist/{src → lib}/flow-control/log-timings.js +8 -45
- package/dist/{src → lib}/flow-control/logger-padding.d.ts +3 -3
- package/dist/{src → lib}/flow-control/logger-padding.js +7 -7
- package/dist/{src → lib}/flow-control/output-error-handler.d.ts +4 -4
- package/dist/{src → lib}/flow-control/output-error-handler.js +3 -7
- package/dist/{src → lib}/flow-control/restart-process.d.ts +4 -4
- package/dist/lib/flow-control/restart-process.js +61 -0
- package/dist/{src → lib}/flow-control/teardown.d.ts +4 -5
- package/dist/lib/flow-control/teardown.js +45 -0
- package/dist/{src → lib}/index.d.ts +21 -19
- package/dist/lib/index.js +98 -0
- package/dist/{src → lib}/jsonc.js +3 -8
- package/dist/{src → lib}/logger.d.ts +3 -2
- package/dist/{src → lib}/logger.js +109 -65
- package/dist/{src → lib}/observables.d.ts +1 -1
- package/dist/{src → lib}/observables.js +3 -6
- package/dist/{src → lib}/output-writer.d.ts +3 -3
- package/dist/{src → lib}/output-writer.js +4 -41
- package/dist/lib/prefix-color-selector.d.ts +21 -0
- package/dist/{src → lib}/prefix-color-selector.js +14 -31
- package/dist/{src → lib}/spawn.d.ts +14 -5
- package/dist/lib/spawn.js +105 -0
- package/dist/lib/utils.d.ts +25 -0
- package/dist/lib/utils.js +52 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/README.md +6 -0
- package/docs/cli/prefixing.md +44 -4
- package/docs/shell-resolution.md +48 -0
- package/package.json +48 -67
- package/dist/bin/read-package.d.ts +0 -6
- package/dist/bin/read-package.js +0 -56
- package/dist/src/assert.d.ts +0 -5
- package/dist/src/assert.js +0 -15
- package/dist/src/command-parser/command-parser.d.ts +0 -19
- package/dist/src/command-parser/command-parser.js +0 -2
- package/dist/src/command-parser/strip-quotes.d.ts +0 -16
- package/dist/src/command-parser/strip-quotes.js +0 -17
- package/dist/src/flow-control/flow-controller.js +0 -2
- package/dist/src/flow-control/restart-process.js +0 -98
- package/dist/src/flow-control/teardown.js +0 -82
- package/dist/src/index.js +0 -96
- package/dist/src/prefix-color-selector.d.ts +0 -11
- package/dist/src/spawn.js +0 -49
- package/dist/src/utils.d.ts +0 -10
- package/dist/src/utils.js +0 -16
- package/index.d.mts +0 -7
- package/index.d.ts +0 -11
- package/index.js +0 -14
- package/index.mjs +0 -9
- /package/dist/bin/{concurrently.d.ts → index.d.ts} +0 -0
- /package/dist/{src → lib}/jsonc.d.ts +0 -0
|
@@ -1,42 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.InputHandler = void 0;
|
|
37
|
-
const Rx = __importStar(require("rxjs"));
|
|
38
|
-
const operators_1 = require("rxjs/operators");
|
|
39
|
-
const defaults = __importStar(require("../defaults"));
|
|
1
|
+
import Rx from 'rxjs';
|
|
2
|
+
import { map } from 'rxjs/operators';
|
|
3
|
+
import * as defaults from '../defaults.js';
|
|
40
4
|
/**
|
|
41
5
|
* Sends input from concurrently through to commands.
|
|
42
6
|
*
|
|
@@ -46,7 +10,7 @@ const defaults = __importStar(require("../defaults"));
|
|
|
46
10
|
*
|
|
47
11
|
* If the input doesn't start with a command identifier, it is then always sent to the default target.
|
|
48
12
|
*/
|
|
49
|
-
class InputHandler {
|
|
13
|
+
export class InputHandler {
|
|
50
14
|
logger;
|
|
51
15
|
defaultInputTarget;
|
|
52
16
|
inputStream;
|
|
@@ -68,12 +32,13 @@ class InputHandler {
|
|
|
68
32
|
commandsMap.set(command.name, command);
|
|
69
33
|
}
|
|
70
34
|
Rx.fromEvent(inputStream, 'data')
|
|
71
|
-
.pipe(
|
|
35
|
+
.pipe(map((data) => String(data)))
|
|
72
36
|
.subscribe((data) => {
|
|
73
|
-
let command, input;
|
|
74
37
|
const dataParts = data.split(/:(.+)/s);
|
|
75
38
|
let target = dataParts[0];
|
|
76
|
-
|
|
39
|
+
let command = commandsMap.get(target);
|
|
40
|
+
let input;
|
|
41
|
+
if (dataParts.length > 1 && command) {
|
|
77
42
|
input = dataParts[1];
|
|
78
43
|
}
|
|
79
44
|
else {
|
|
@@ -101,4 +66,3 @@ class InputHandler {
|
|
|
101
66
|
};
|
|
102
67
|
}
|
|
103
68
|
}
|
|
104
|
-
exports.InputHandler = InputHandler;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import EventEmitter from 'events';
|
|
2
|
-
import { Command } from '../command';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
2
|
+
import { Command } from '../command.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
/**
|
|
5
5
|
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
|
6
6
|
* command.
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.KillOnSignal = void 0;
|
|
4
|
-
const operators_1 = require("rxjs/operators");
|
|
1
|
+
import { map } from 'rxjs/operators';
|
|
5
2
|
const SIGNALS = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
6
3
|
/**
|
|
7
4
|
* Watches the main concurrently process for signals and sends the same signal down to each spawned
|
|
8
5
|
* command.
|
|
9
6
|
*/
|
|
10
|
-
class KillOnSignal {
|
|
7
|
+
export class KillOnSignal {
|
|
11
8
|
process;
|
|
12
9
|
abortController;
|
|
13
10
|
constructor({ process, abortController, }) {
|
|
@@ -24,7 +21,7 @@ class KillOnSignal {
|
|
|
24
21
|
SIGNALS.forEach((signal) => this.process.on(signal, signalListener));
|
|
25
22
|
return {
|
|
26
23
|
commands: commands.map((command) => {
|
|
27
|
-
const closeStream = command.close.pipe(
|
|
24
|
+
const closeStream = command.close.pipe(map((exitInfo) => {
|
|
28
25
|
const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode;
|
|
29
26
|
return { ...exitInfo, exitCode };
|
|
30
27
|
}));
|
|
@@ -44,4 +41,3 @@ class KillOnSignal {
|
|
|
44
41
|
};
|
|
45
42
|
}
|
|
46
43
|
}
|
|
47
|
-
exports.KillOnSignal = KillOnSignal;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
export type ProcessCloseCondition = 'failure' | 'success';
|
|
5
5
|
/**
|
|
6
6
|
* Sends a SIGTERM signal to all commands when one of the commands exits with a matching condition.
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const operators_1 = require("rxjs/operators");
|
|
5
|
-
const command_1 = require("../command");
|
|
6
|
-
const utils_1 = require("../utils");
|
|
1
|
+
import { filter, map } from 'rxjs/operators';
|
|
2
|
+
import { Command } from '../command.js';
|
|
3
|
+
import { castArray } from '../utils.js';
|
|
7
4
|
/**
|
|
8
5
|
* Sends a SIGTERM signal to all commands when one of the commands exits with a matching condition.
|
|
9
6
|
*/
|
|
10
|
-
class KillOthers {
|
|
7
|
+
export class KillOthers {
|
|
11
8
|
logger;
|
|
12
9
|
abortController;
|
|
13
10
|
conditions;
|
|
@@ -16,7 +13,7 @@ class KillOthers {
|
|
|
16
13
|
constructor({ logger, abortController, conditions, killSignal, timeoutMs, }) {
|
|
17
14
|
this.logger = logger;
|
|
18
15
|
this.abortController = abortController;
|
|
19
|
-
this.conditions =
|
|
16
|
+
this.conditions = castArray(conditions);
|
|
20
17
|
this.killSignal = killSignal;
|
|
21
18
|
this.timeoutMs = timeoutMs;
|
|
22
19
|
}
|
|
@@ -25,10 +22,10 @@ class KillOthers {
|
|
|
25
22
|
if (!conditions.length) {
|
|
26
23
|
return { commands };
|
|
27
24
|
}
|
|
28
|
-
const closeStates = commands.map((command) => command.close.pipe(
|
|
25
|
+
const closeStates = commands.map((command) => command.close.pipe(map(({ exitCode }) => exitCode === 0 ? 'success' : 'failure'), filter((state) => conditions.includes(state))));
|
|
29
26
|
closeStates.forEach((closeState) => closeState.subscribe(() => {
|
|
30
27
|
this.abortController?.abort();
|
|
31
|
-
const killableCommands = commands.filter((command) =>
|
|
28
|
+
const killableCommands = commands.filter((command) => Command.canKill(command));
|
|
32
29
|
if (killableCommands.length) {
|
|
33
30
|
this.logger.logGlobalEvent(`Sending ${this.killSignal || 'SIGTERM'} to other processes..`);
|
|
34
31
|
killableCommands.forEach((command) => command.kill(this.killSignal));
|
|
@@ -43,7 +40,7 @@ class KillOthers {
|
|
|
43
40
|
return;
|
|
44
41
|
}
|
|
45
42
|
setTimeout(() => {
|
|
46
|
-
const killableCommands = commands.filter((command) =>
|
|
43
|
+
const killableCommands = commands.filter((command) => Command.canKill(command));
|
|
47
44
|
if (killableCommands) {
|
|
48
45
|
this.logger.logGlobalEvent(`Sending SIGKILL to ${killableCommands.length} processes..`);
|
|
49
46
|
killableCommands.forEach((command) => command.kill('SIGKILL'));
|
|
@@ -51,4 +48,3 @@ class KillOthers {
|
|
|
51
48
|
}, this.timeoutMs);
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
|
-
exports.KillOthers = KillOthers;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
/**
|
|
5
5
|
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
|
6
6
|
*/
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogError = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Logs when commands failed executing, e.g. due to the executable not existing in the system.
|
|
6
3
|
*/
|
|
7
|
-
class LogError {
|
|
4
|
+
export class LogError {
|
|
8
5
|
logger;
|
|
9
6
|
constructor({ logger }) {
|
|
10
7
|
this.logger = logger;
|
|
@@ -18,4 +15,3 @@ class LogError {
|
|
|
18
15
|
return { commands };
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
exports.LogError = LogError;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
/**
|
|
5
5
|
* Logs the exit code/signal of commands.
|
|
6
6
|
*/
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogExit = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Logs the exit code/signal of commands.
|
|
6
3
|
*/
|
|
7
|
-
class LogExit {
|
|
4
|
+
export class LogExit {
|
|
8
5
|
logger;
|
|
9
6
|
constructor({ logger }) {
|
|
10
7
|
this.logger = logger;
|
|
@@ -16,4 +13,3 @@ class LogExit {
|
|
|
16
13
|
return { commands };
|
|
17
14
|
}
|
|
18
15
|
}
|
|
19
|
-
exports.LogExit = LogExit;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
/**
|
|
5
5
|
* Logs the stdout and stderr output of commands.
|
|
6
6
|
*/
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogOutput = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Logs the stdout and stderr output of commands.
|
|
6
3
|
*/
|
|
7
|
-
class LogOutput {
|
|
4
|
+
export class LogOutput {
|
|
8
5
|
logger;
|
|
9
6
|
constructor({ logger }) {
|
|
10
7
|
this.logger = logger;
|
|
@@ -17,4 +14,3 @@ class LogOutput {
|
|
|
17
14
|
return { commands };
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
exports.LogOutput = LogOutput;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CloseEvent, Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { CloseEvent, Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
type TimingInfo = {
|
|
5
5
|
name: string;
|
|
6
6
|
duration: string;
|
|
@@ -1,48 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.LogTimings = void 0;
|
|
37
|
-
const assert = __importStar(require("assert"));
|
|
38
|
-
const Rx = __importStar(require("rxjs"));
|
|
39
|
-
const operators_1 = require("rxjs/operators");
|
|
40
|
-
const date_format_1 = require("../date-format");
|
|
41
|
-
const defaults = __importStar(require("../defaults"));
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import Rx from 'rxjs';
|
|
3
|
+
import { bufferCount, combineLatestWith, take } from 'rxjs/operators';
|
|
4
|
+
import { DateFormatter } from '../date-format.js';
|
|
5
|
+
import * as defaults from '../defaults.js';
|
|
42
6
|
/**
|
|
43
7
|
* Logs timing information about commands as they start/stop and then a summary when all commands finish.
|
|
44
8
|
*/
|
|
45
|
-
class LogTimings {
|
|
9
|
+
export class LogTimings {
|
|
46
10
|
static mapCloseEventToTimingInfo({ command, timings, killed, exitCode, }) {
|
|
47
11
|
const readableDurationMs = (timings.endDate.getTime() - timings.startDate.getTime()).toLocaleString();
|
|
48
12
|
return {
|
|
@@ -57,7 +21,7 @@ class LogTimings {
|
|
|
57
21
|
dateFormatter;
|
|
58
22
|
constructor({ logger, timestampFormat = defaults.timestampFormat, }) {
|
|
59
23
|
this.logger = logger;
|
|
60
|
-
this.dateFormatter = new
|
|
24
|
+
this.dateFormatter = new DateFormatter(timestampFormat);
|
|
61
25
|
}
|
|
62
26
|
printExitInfoTimingTable(exitInfos) {
|
|
63
27
|
assert.ok(this.logger);
|
|
@@ -90,9 +54,8 @@ class LogTimings {
|
|
|
90
54
|
// overall summary timings
|
|
91
55
|
const closeStreams = commands.map((command) => command.close);
|
|
92
56
|
const finished = new Rx.Subject();
|
|
93
|
-
const allProcessesClosed = Rx.merge(...closeStreams).pipe(
|
|
57
|
+
const allProcessesClosed = Rx.merge(...closeStreams).pipe(bufferCount(closeStreams.length), take(1), combineLatestWith(finished));
|
|
94
58
|
allProcessesClosed.subscribe(([exitInfos]) => this.printExitInfoTimingTable(exitInfos));
|
|
95
59
|
return { commands, onFinish: () => finished.next() };
|
|
96
60
|
}
|
|
97
61
|
}
|
|
98
|
-
exports.LogTimings = LogTimings;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
export declare class LoggerPadding implements FlowController {
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor({ logger }: {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { COLOR_MARKER_RE } from '../logger.js';
|
|
2
|
+
function visibleLength(value) {
|
|
3
|
+
return value ? value.replace(COLOR_MARKER_RE, '').length : 0;
|
|
4
|
+
}
|
|
5
|
+
export class LoggerPadding {
|
|
5
6
|
logger;
|
|
6
7
|
constructor({ logger }) {
|
|
7
8
|
this.logger = logger;
|
|
@@ -11,7 +12,7 @@ class LoggerPadding {
|
|
|
11
12
|
// Compute the prefix length now, which works for all styles but those with a PID.
|
|
12
13
|
let length = commands.reduce((length, command) => {
|
|
13
14
|
const content = this.logger.getPrefixContent(command);
|
|
14
|
-
return Math.max(length, content?.value
|
|
15
|
+
return Math.max(length, visibleLength(content?.value));
|
|
15
16
|
}, 0);
|
|
16
17
|
this.logger.setPrefixLength(length);
|
|
17
18
|
// The length of prefixes is somewhat stable, except for PIDs, which might change when a
|
|
@@ -20,7 +21,7 @@ class LoggerPadding {
|
|
|
20
21
|
const subs = commands.map((command) => command.timer.subscribe((event) => {
|
|
21
22
|
if (!event.endDate) {
|
|
22
23
|
const content = this.logger.getPrefixContent(command);
|
|
23
|
-
length = Math.max(length, content?.value
|
|
24
|
+
length = Math.max(length, visibleLength(content?.value));
|
|
24
25
|
this.logger.setPrefixLength(length);
|
|
25
26
|
}
|
|
26
27
|
}));
|
|
@@ -32,4 +33,3 @@ class LoggerPadding {
|
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
exports.LoggerPadding = LoggerPadding;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Writable } from 'stream';
|
|
2
|
-
import { Command } from '../command';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Writable } from 'node:stream';
|
|
2
|
+
import { Command } from '../command.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
/**
|
|
5
5
|
* Kills processes and aborts further command spawning on output stream error (namely, SIGPIPE).
|
|
6
6
|
*/
|
|
@@ -13,6 +13,6 @@ export declare class OutputErrorHandler implements FlowController {
|
|
|
13
13
|
});
|
|
14
14
|
handle(commands: Command[]): {
|
|
15
15
|
commands: Command[];
|
|
16
|
-
onFinish()
|
|
16
|
+
onFinish: () => void;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OutputErrorHandler = void 0;
|
|
4
|
-
const observables_1 = require("../observables");
|
|
1
|
+
import { fromSharedEvent } from '../observables.js';
|
|
5
2
|
/**
|
|
6
3
|
* Kills processes and aborts further command spawning on output stream error (namely, SIGPIPE).
|
|
7
4
|
*/
|
|
8
|
-
class OutputErrorHandler {
|
|
5
|
+
export class OutputErrorHandler {
|
|
9
6
|
outputStream;
|
|
10
7
|
abortController;
|
|
11
8
|
constructor({ abortController, outputStream, }) {
|
|
@@ -13,7 +10,7 @@ class OutputErrorHandler {
|
|
|
13
10
|
this.outputStream = outputStream;
|
|
14
11
|
}
|
|
15
12
|
handle(commands) {
|
|
16
|
-
const subscription =
|
|
13
|
+
const subscription = fromSharedEvent(this.outputStream, 'error').subscribe(() => {
|
|
17
14
|
commands.forEach((command) => command.kill());
|
|
18
15
|
// Avoid further commands from spawning, e.g. if `RestartProcess` is used.
|
|
19
16
|
this.abortController.abort();
|
|
@@ -24,4 +21,3 @@ class OutputErrorHandler {
|
|
|
24
21
|
};
|
|
25
22
|
}
|
|
26
23
|
}
|
|
27
|
-
exports.OutputErrorHandler = OutputErrorHandler;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Command } from '../command';
|
|
3
|
-
import { Logger } from '../logger';
|
|
4
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import Rx from 'rxjs';
|
|
2
|
+
import { Command } from '../command.js';
|
|
3
|
+
import { Logger } from '../logger.js';
|
|
4
|
+
import { FlowController } from './flow-controller.js';
|
|
5
5
|
export type RestartDelay = number | 'exponential';
|
|
6
6
|
/**
|
|
7
7
|
* Restarts commands that fail up to a defined number of times.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import Rx from 'rxjs';
|
|
2
|
+
import { defaultIfEmpty, delayWhen, filter, map, skip, take, takeWhile } from 'rxjs/operators';
|
|
3
|
+
import * as defaults from '../defaults.js';
|
|
4
|
+
/**
|
|
5
|
+
* Restarts commands that fail up to a defined number of times.
|
|
6
|
+
*/
|
|
7
|
+
export class RestartProcess {
|
|
8
|
+
logger;
|
|
9
|
+
scheduler;
|
|
10
|
+
delay;
|
|
11
|
+
tries;
|
|
12
|
+
constructor({ delay, tries, logger, scheduler, }) {
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
this.delay = delay ?? 0;
|
|
15
|
+
this.tries = tries != null ? +tries : defaults.restartTries;
|
|
16
|
+
this.tries = this.tries < 0 ? Infinity : this.tries;
|
|
17
|
+
this.scheduler = scheduler;
|
|
18
|
+
}
|
|
19
|
+
handle(commands) {
|
|
20
|
+
if (this.tries === 0) {
|
|
21
|
+
return { commands };
|
|
22
|
+
}
|
|
23
|
+
const delayOperator = delayWhen((_, index) => {
|
|
24
|
+
const { delay } = this;
|
|
25
|
+
const value = delay === 'exponential' ? 2 ** index * 1000 : delay;
|
|
26
|
+
return Rx.timer(value, this.scheduler);
|
|
27
|
+
});
|
|
28
|
+
commands
|
|
29
|
+
.map((command) => command.close.pipe(take(this.tries), takeWhile(({ exitCode }) => exitCode !== 0)))
|
|
30
|
+
.forEach((failure, index) => Rx.merge(
|
|
31
|
+
// Delay the emission (so that the restarts happen on time),
|
|
32
|
+
// explicitly telling the subscriber that a restart is needed
|
|
33
|
+
failure.pipe(delayOperator, map(() => true)),
|
|
34
|
+
// Skip the first N emissions (as these would be duplicates of the above),
|
|
35
|
+
// meaning it will be empty because of success, or failed all N times,
|
|
36
|
+
// and no more restarts should be attempted.
|
|
37
|
+
failure.pipe(skip(this.tries), map(() => false), defaultIfEmpty(false))).subscribe((restart) => {
|
|
38
|
+
const command = commands[index];
|
|
39
|
+
if (restart) {
|
|
40
|
+
this.logger.logCommandEvent(`${command.command} restarted`, command);
|
|
41
|
+
command.start();
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
return {
|
|
45
|
+
commands: commands.map((command) => {
|
|
46
|
+
const closeStream = command.close.pipe(filter(({ exitCode }, emission) => {
|
|
47
|
+
// We let all success codes pass, and failures only after restarting won't happen again
|
|
48
|
+
return exitCode === 0 || emission >= this.tries;
|
|
49
|
+
}));
|
|
50
|
+
// Return a proxy so that mutations happen on the original Command object.
|
|
51
|
+
// If either `Object.assign()` or `Object.create()` were used, it'd be hard to
|
|
52
|
+
// reflect the mutations on Command objects referenced by previous flow controllers.
|
|
53
|
+
return new Proxy(command, {
|
|
54
|
+
get(target, prop) {
|
|
55
|
+
return prop === 'close' ? closeStream : target[prop];
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command, SpawnCommand } from '../command';
|
|
2
|
-
import { Logger } from '../logger';
|
|
3
|
-
import { FlowController } from './flow-controller';
|
|
1
|
+
import { Command, SpawnCommand } from '../command.js';
|
|
2
|
+
import { Logger } from '../logger.js';
|
|
3
|
+
import { FlowController } from './flow-controller.js';
|
|
4
4
|
export declare class Teardown implements FlowController {
|
|
5
5
|
private readonly logger;
|
|
6
6
|
private readonly spawn;
|
|
@@ -9,9 +9,8 @@ export declare class Teardown implements FlowController {
|
|
|
9
9
|
logger: Logger;
|
|
10
10
|
/**
|
|
11
11
|
* Which function to use to spawn commands.
|
|
12
|
-
* Defaults to the same used by the rest of concurrently.
|
|
13
12
|
*/
|
|
14
|
-
spawn
|
|
13
|
+
spawn: SpawnCommand;
|
|
15
14
|
commands: readonly string[];
|
|
16
15
|
});
|
|
17
16
|
handle(commands: Command[]): {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Rx from 'rxjs';
|
|
2
|
+
import { getSpawnOpts } from '../spawn.js';
|
|
3
|
+
export class Teardown {
|
|
4
|
+
logger;
|
|
5
|
+
spawn;
|
|
6
|
+
teardown;
|
|
7
|
+
constructor({ logger, spawn, commands, }) {
|
|
8
|
+
this.logger = logger;
|
|
9
|
+
this.spawn = spawn;
|
|
10
|
+
this.teardown = commands;
|
|
11
|
+
}
|
|
12
|
+
handle(commands) {
|
|
13
|
+
const { logger, teardown, spawn } = this;
|
|
14
|
+
const onFinish = async () => {
|
|
15
|
+
if (!teardown.length) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
for (const command of teardown) {
|
|
19
|
+
logger.logGlobalEvent(`Running teardown command "${command}"`);
|
|
20
|
+
const child = spawn(command, getSpawnOpts({ stdio: 'raw' }));
|
|
21
|
+
const error = Rx.fromEvent(child, 'error');
|
|
22
|
+
const close = Rx.fromEvent(child, 'close');
|
|
23
|
+
try {
|
|
24
|
+
const [exitCode, signal] = await Promise.race([
|
|
25
|
+
Rx.firstValueFrom(error).then((event) => {
|
|
26
|
+
throw event;
|
|
27
|
+
}),
|
|
28
|
+
Rx.firstValueFrom(close).then((event) => event),
|
|
29
|
+
]);
|
|
30
|
+
logger.logGlobalEvent(`Teardown command "${command}" exited with code ${exitCode ?? signal}`);
|
|
31
|
+
if (signal === 'SIGINT') {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const errorText = String(error instanceof Error ? error.stack || error : error);
|
|
37
|
+
logger.logGlobalEvent(`Teardown command "${command}" errored:`);
|
|
38
|
+
logger.logGlobalEvent(errorText);
|
|
39
|
+
return Promise.reject(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return { commands, onFinish };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Readable } from 'stream';
|
|
2
|
-
import { CloseEvent, Command, CommandIdentifier, TimerEvent } from './command';
|
|
3
|
-
import { concurrently as createConcurrently, ConcurrentlyCommandInput, ConcurrentlyOptions as BaseConcurrentlyOptions, ConcurrentlyResult } from './concurrently';
|
|
4
|
-
import { FlowController } from './flow-control/flow-controller';
|
|
5
|
-
import { InputHandler } from './flow-control/input-handler';
|
|
6
|
-
import { KillOnSignal } from './flow-control/kill-on-signal';
|
|
7
|
-
import { KillOthers, ProcessCloseCondition } from './flow-control/kill-others';
|
|
8
|
-
import { LogError } from './flow-control/log-error';
|
|
9
|
-
import { LogExit } from './flow-control/log-exit';
|
|
10
|
-
import { LogOutput } from './flow-control/log-output';
|
|
11
|
-
import { LogTimings } from './flow-control/log-timings';
|
|
12
|
-
import { RestartDelay, RestartProcess } from './flow-control/restart-process';
|
|
13
|
-
import { Logger } from './logger';
|
|
14
|
-
export type ConcurrentlyOptions = Omit<BaseConcurrentlyOptions, 'abortSignal' | 'hide'> & {
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { CloseEvent, Command, CommandIdentifier, TimerEvent } from './command.js';
|
|
3
|
+
import { concurrently as createConcurrently, ConcurrentlyCommandInput, ConcurrentlyOptions as BaseConcurrentlyOptions, ConcurrentlyResult } from './concurrently.js';
|
|
4
|
+
import type { FlowController } from './flow-control/flow-controller.js';
|
|
5
|
+
import { InputHandler } from './flow-control/input-handler.js';
|
|
6
|
+
import { KillOnSignal } from './flow-control/kill-on-signal.js';
|
|
7
|
+
import { KillOthers, ProcessCloseCondition } from './flow-control/kill-others.js';
|
|
8
|
+
import { LogError } from './flow-control/log-error.js';
|
|
9
|
+
import { LogExit } from './flow-control/log-exit.js';
|
|
10
|
+
import { LogOutput } from './flow-control/log-output.js';
|
|
11
|
+
import { LogTimings } from './flow-control/log-timings.js';
|
|
12
|
+
import { RestartDelay, RestartProcess } from './flow-control/restart-process.js';
|
|
13
|
+
import { Logger } from './logger.js';
|
|
14
|
+
export type ConcurrentlyOptions = Omit<BaseConcurrentlyOptions, 'abortSignal' | 'hide' | 'spawn'> & {
|
|
15
15
|
/**
|
|
16
16
|
* Which command(s) should have their output hidden.
|
|
17
17
|
*/
|
|
@@ -54,11 +54,6 @@ export type ConcurrentlyOptions = Omit<BaseConcurrentlyOptions, 'abortSignal' |
|
|
|
54
54
|
* @see RestartProcess
|
|
55
55
|
*/
|
|
56
56
|
restartTries?: number;
|
|
57
|
-
/**
|
|
58
|
-
* @deprecated Use `killOthersOn` instead.
|
|
59
|
-
* @see KillOthers
|
|
60
|
-
*/
|
|
61
|
-
killOthers?: ProcessCloseCondition | ProcessCloseCondition[];
|
|
62
57
|
/**
|
|
63
58
|
* Once the first command exits with one of these statuses, kill other commands.
|
|
64
59
|
* @see KillOthers
|
|
@@ -88,8 +83,15 @@ export type ConcurrentlyOptions = Omit<BaseConcurrentlyOptions, 'abortSignal' |
|
|
|
88
83
|
* If not defined, no argument replacing will happen.
|
|
89
84
|
*/
|
|
90
85
|
additionalArguments?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Shell executable used to run command strings.
|
|
88
|
+
* When unset, uses the `npm_config_script_shell` env variable if present. Otherwise, falls back
|
|
89
|
+
* to `cmd.exe` on Windows, and `/bin/sh` elsewhere.
|
|
90
|
+
*/
|
|
91
|
+
shell?: string;
|
|
91
92
|
};
|
|
92
93
|
export declare function concurrently(commands: ConcurrentlyCommandInput[], options?: Partial<ConcurrentlyOptions>): ConcurrentlyResult;
|
|
94
|
+
export default concurrently;
|
|
93
95
|
export { ConcurrentlyCommandInput, ConcurrentlyResult, createConcurrently, Logger };
|
|
94
96
|
export { CloseEvent, Command, CommandIdentifier, TimerEvent };
|
|
95
97
|
export { FlowController, InputHandler, KillOnSignal, KillOthers, LogError, LogExit, LogOutput, LogTimings, RestartProcess, };
|