concurrently 4.1.2 → 5.1.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 +4 -8
- package/bin/epilogue.txt +0 -4
- package/package.json +12 -5
- package/src/completion-listener.js +26 -22
- package/src/defaults.js +2 -2
- package/src/flow-control/kill-on-signal.js +1 -1
- package/src/get-spawn-opts.js +1 -1
- package/.editorconfig +0 -28
- package/.eslintrc.json +0 -23
- package/.travis.yml +0 -11
- package/.vscode/settings.json +0 -6
- package/CONTRIBUTING.md +0 -23
- package/appveyor.yml +0 -18
- package/bin/concurrently.spec.js +0 -365
- package/bin/fixtures/read-echo.js +0 -10
- package/docs/demo.gif +0 -0
- package/docs/frontend-demo.gif +0 -0
- package/docs/kill-demo.gif +0 -0
- package/docs/raw-demo.gif +0 -0
- package/src/command-parser/expand-npm-shortcut.spec.js +0 -36
- package/src/command-parser/expand-npm-wildcard.spec.js +0 -58
- package/src/command-parser/strip-quotes.spec.js +0 -20
- package/src/command.spec.js +0 -142
- package/src/completion-listener.spec.js +0 -88
- package/src/concurrently.spec.js +0 -77
- package/src/flow-control/input-handler.spec.js +0 -79
- package/src/flow-control/kill-on-signal.spec.js +0 -70
- package/src/flow-control/kill-others.spec.js +0 -66
- package/src/flow-control/log-error.spec.js +0 -40
- package/src/flow-control/log-exit.spec.js +0 -36
- package/src/flow-control/log-output.spec.js +0 -41
- package/src/flow-control/restart-process.spec.js +0 -129
- package/src/get-spawn-opts.spec.js +0 -18
- package/src/logger.spec.js +0 -178
package/README.md
CHANGED
|
@@ -147,7 +147,7 @@ Prefix styling
|
|
|
147
147
|
prefix when it is set to "command"
|
|
148
148
|
[number] [default: 10]
|
|
149
149
|
-t, --timestamp-format Specify the timestamp in moment/date-fns format.
|
|
150
|
-
[string] [default: "
|
|
150
|
+
[string] [default: "yyyy-MM-dd HH:mm:ss.SSS"]
|
|
151
151
|
|
|
152
152
|
Input handling
|
|
153
153
|
-i, --handle-input Whether input should be forwarded to the child
|
|
@@ -191,10 +191,6 @@ Examples:
|
|
|
191
191
|
$ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold"
|
|
192
192
|
"http-server" "npm run watch"
|
|
193
193
|
|
|
194
|
-
- Shortened NPM run commands
|
|
195
|
-
|
|
196
|
-
$ concurrently npm:watch-node npm:watch-js npm:watch-css
|
|
197
|
-
|
|
198
194
|
- Send input to default
|
|
199
195
|
|
|
200
196
|
$ concurrently --handle-input "nodemon" "npm run watch-js"
|
|
@@ -247,11 +243,11 @@ concurrently can be used programmatically by using the API documented below:
|
|
|
247
243
|
Anything else means all processes should exit successfully.
|
|
248
244
|
- `restartTries`: how many attempts to restart a process that dies will be made. Default: `0`.
|
|
249
245
|
- `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
|
|
250
|
-
- `timestampFormat`: a [date-fns
|
|
251
|
-
to use when prefixing with `time`. Default: `
|
|
246
|
+
- `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
|
|
247
|
+
to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
|
|
252
248
|
|
|
253
249
|
> Returns: a `Promise` that resolves if the run was successful (according to `successCondition` option),
|
|
254
|
-
> or rejects
|
|
250
|
+
> or rejects, containing an array with the exit codes of each command that has been run.
|
|
255
251
|
|
|
256
252
|
Example:
|
|
257
253
|
|
package/bin/epilogue.txt
CHANGED
|
@@ -16,10 +16,6 @@ Examples:
|
|
|
16
16
|
|
|
17
17
|
$ $0 --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold" "http-server" "npm run watch"
|
|
18
18
|
|
|
19
|
-
- Shortened NPM run commands
|
|
20
|
-
|
|
21
|
-
$ $0 npm:watch-node npm:watch-js npm:watch-css
|
|
22
|
-
|
|
23
19
|
- Send input to default
|
|
24
20
|
|
|
25
21
|
$ $0 --handle-input "nodemon" "npm run watch-js"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "concurrently",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Run commands concurrently",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"chalk": "^2.4.2",
|
|
33
|
-
"date-fns": "^
|
|
33
|
+
"date-fns": "^2.0.1",
|
|
34
34
|
"lodash": "^4.17.15",
|
|
35
35
|
"read-pkg": "^4.0.1",
|
|
36
36
|
"rxjs": "^6.5.2",
|
|
37
37
|
"spawn-command": "^0.0.2-1",
|
|
38
|
-
"supports-color": "^
|
|
39
|
-
"tree-kill": "^1.2.
|
|
40
|
-
"yargs": "^
|
|
38
|
+
"supports-color": "^6.1.0",
|
|
39
|
+
"tree-kill": "^1.2.2",
|
|
40
|
+
"yargs": "^13.3.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"coveralls": "^3.0.4",
|
|
@@ -45,6 +45,13 @@
|
|
|
45
45
|
"jest": "^24.8.0",
|
|
46
46
|
"jest-create-mock-instance": "^1.1.0"
|
|
47
47
|
},
|
|
48
|
+
"files": [
|
|
49
|
+
"bin",
|
|
50
|
+
"!**/fixtures",
|
|
51
|
+
"index.js",
|
|
52
|
+
"src",
|
|
53
|
+
"!*.spec.js"
|
|
54
|
+
],
|
|
48
55
|
"jest": {
|
|
49
56
|
"collectCoverage": true,
|
|
50
57
|
"collectCoverageFrom": [
|
|
@@ -7,29 +7,33 @@ module.exports = class CompletionListener {
|
|
|
7
7
|
this.scheduler = scheduler;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
case 'first':
|
|
19
|
-
return exitCodes[0] === 0;
|
|
10
|
+
isSuccess(exitCodes) {
|
|
11
|
+
switch (this.successCondition) {
|
|
12
|
+
/* eslint-disable indent */
|
|
13
|
+
case 'first':
|
|
14
|
+
return exitCodes[0] === 0;
|
|
15
|
+
|
|
16
|
+
case 'last':
|
|
17
|
+
return exitCodes[exitCodes.length - 1] === 0;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
default:
|
|
20
|
+
return exitCodes.every(exitCode => exitCode === 0);
|
|
21
|
+
/* eslint-enable indent */
|
|
22
|
+
}
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
listen(commands) {
|
|
26
|
+
const closeStreams = commands.map(command => command.close);
|
|
27
|
+
return Rx.merge(...closeStreams)
|
|
28
|
+
.pipe(
|
|
29
|
+
bufferCount(closeStreams.length),
|
|
30
|
+
switchMap(exitCodes =>
|
|
31
|
+
this.isSuccess(exitCodes)
|
|
32
|
+
? Rx.of(exitCodes, this.scheduler)
|
|
33
|
+
: Rx.throwError(exitCodes, this.scheduler)
|
|
34
|
+
),
|
|
35
|
+
take(1)
|
|
36
|
+
)
|
|
37
|
+
.toPromise();
|
|
34
38
|
}
|
|
35
39
|
};
|
package/src/defaults.js
CHANGED
|
@@ -22,6 +22,6 @@ module.exports = {
|
|
|
22
22
|
restartDelay: 0,
|
|
23
23
|
// Condition of success for concurrently itself.
|
|
24
24
|
success: 'all',
|
|
25
|
-
// Refer to https://date-fns.org/
|
|
26
|
-
timestampFormat: '
|
|
25
|
+
// Refer to https://date-fns.org/v2.0.1/docs/format
|
|
26
|
+
timestampFormat: 'yyyy-MM-dd HH:mm:ss.SSS'
|
|
27
27
|
};
|
|
@@ -8,7 +8,7 @@ module.exports = class KillOnSignal {
|
|
|
8
8
|
|
|
9
9
|
handle(commands) {
|
|
10
10
|
let caughtSignal;
|
|
11
|
-
['SIGINT', 'SIGTERM'].forEach(signal => {
|
|
11
|
+
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(signal => {
|
|
12
12
|
this.process.on(signal, () => {
|
|
13
13
|
caughtSignal = signal;
|
|
14
14
|
commands.forEach(command => command.kill(signal));
|
package/src/get-spawn-opts.js
CHANGED
package/.editorconfig
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# EditorConfig is awesome: http://EditorConfig.org
|
|
2
|
-
|
|
3
|
-
# top-most EditorConfig file
|
|
4
|
-
root = true
|
|
5
|
-
|
|
6
|
-
# Unix-style newlines with a newline ending every file
|
|
7
|
-
[*]
|
|
8
|
-
end_of_line = lf
|
|
9
|
-
insert_final_newline = true
|
|
10
|
-
|
|
11
|
-
# 4 space indentation
|
|
12
|
-
[*.py]
|
|
13
|
-
indent_style = space
|
|
14
|
-
indent_size = 4
|
|
15
|
-
|
|
16
|
-
# Tab indentation (no size specified)
|
|
17
|
-
[*.js]
|
|
18
|
-
indent_style = space
|
|
19
|
-
indent_size = 4
|
|
20
|
-
|
|
21
|
-
# Matches the exact files package.json and .travis.yml
|
|
22
|
-
[{package.json,.travis.yml,Gruntfile.js}]
|
|
23
|
-
indent_style = space
|
|
24
|
-
indent_size = 2
|
|
25
|
-
|
|
26
|
-
[Makefile]
|
|
27
|
-
indent_style = tab
|
|
28
|
-
indent_size = 4
|
package/.eslintrc.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"env": {
|
|
4
|
-
"browser": false,
|
|
5
|
-
"node": true
|
|
6
|
-
},
|
|
7
|
-
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 6
|
|
9
|
-
},
|
|
10
|
-
"rules": {
|
|
11
|
-
"block-spacing": "error",
|
|
12
|
-
"curly": "error",
|
|
13
|
-
"eqeqeq": ["error", "always", { "null": "ignore" }],
|
|
14
|
-
"indent": ["error", 4],
|
|
15
|
-
"keyword-spacing": "error",
|
|
16
|
-
"no-var": "error",
|
|
17
|
-
"prefer-const": "error",
|
|
18
|
-
"quotes": ["error", "single"],
|
|
19
|
-
"semi": "error",
|
|
20
|
-
"space-before-blocks": "error",
|
|
21
|
-
"space-before-function-paren": ["error", "never"]
|
|
22
|
-
}
|
|
23
|
-
}
|
package/.travis.yml
DELETED
package/.vscode/settings.json
DELETED
package/CONTRIBUTING.md
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Contributing
|
|
2
|
-
|
|
3
|
-
Pull requests and contributions are warmly welcome.
|
|
4
|
-
Please follow existing code style and commit message conventions. Also remember to keep documentation
|
|
5
|
-
updated.
|
|
6
|
-
|
|
7
|
-
**Pull requests:** You don't need to bump version numbers or modify anything related to releasing. That stuff is fully automated, just write the functionality.
|
|
8
|
-
|
|
9
|
-
# Maintaining
|
|
10
|
-
|
|
11
|
-
## Test
|
|
12
|
-
|
|
13
|
-
Tests can be run with command:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm run test
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Release
|
|
20
|
-
|
|
21
|
-
* Commit all changes
|
|
22
|
-
* Run `./node_modules/.bin/releasor --bump minor`, which will create new tag and publish code to GitHub and npm. See https://github.com/kimmobrunfeldt/releasor for options
|
|
23
|
-
* Edit GitHub release notes
|
package/appveyor.yml
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
environment:
|
|
2
|
-
matrix:
|
|
3
|
-
- nodejs_version: '10'
|
|
4
|
-
- nodejs_version: '8'
|
|
5
|
-
- nodejs_version: '6'
|
|
6
|
-
install:
|
|
7
|
-
- ps: Install-Product node $env:nodejs_version
|
|
8
|
-
- set CI=true
|
|
9
|
-
- npm -g install npm@latest
|
|
10
|
-
- set PATH=%APPDATA%\npm;%PATH%
|
|
11
|
-
- npm install
|
|
12
|
-
build: off
|
|
13
|
-
test_script:
|
|
14
|
-
- node --version
|
|
15
|
-
- npm --version
|
|
16
|
-
- set SHELL=cmd.exe
|
|
17
|
-
- set SHELL_EXECUTION_FLAG=/c
|
|
18
|
-
- npm test
|
package/bin/concurrently.spec.js
DELETED
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
const readline = require('readline');
|
|
2
|
-
const _ = require('lodash');
|
|
3
|
-
const Rx = require('rxjs');
|
|
4
|
-
const { buffer, map } = require('rxjs/operators');
|
|
5
|
-
const spawn = require('spawn-command');
|
|
6
|
-
|
|
7
|
-
const isWindows = process.platform === 'win32';
|
|
8
|
-
const createKillMessage = prefix => new RegExp(
|
|
9
|
-
_.escapeRegExp(prefix) +
|
|
10
|
-
' exited with code ' +
|
|
11
|
-
(isWindows ? 1 : '(SIGTERM|143)')
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const run = args => {
|
|
15
|
-
const child = spawn('node ./concurrently.js ' + args, {
|
|
16
|
-
cwd: __dirname,
|
|
17
|
-
env: Object.assign({}, process.env, {
|
|
18
|
-
// When upgrading from jest 23 -> 24, colors started printing in the test output.
|
|
19
|
-
// They are forcibly disabled here
|
|
20
|
-
FORCE_COLOR: 0
|
|
21
|
-
}),
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const stdout = readline.createInterface({
|
|
25
|
-
input: child.stdout,
|
|
26
|
-
output: null
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const stderr = readline.createInterface({
|
|
30
|
-
input: child.stderr,
|
|
31
|
-
output: null
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const close = Rx.fromEvent(child, 'close');
|
|
35
|
-
const log = Rx.merge(
|
|
36
|
-
Rx.fromEvent(stdout, 'line'),
|
|
37
|
-
Rx.fromEvent(stderr, 'line')
|
|
38
|
-
).pipe(map(data => data.toString()));
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
close,
|
|
42
|
-
log,
|
|
43
|
-
stdin: child.stdin,
|
|
44
|
-
pid: child.pid
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
it('has help command', done => {
|
|
49
|
-
run('--help').close.subscribe(event => {
|
|
50
|
-
expect(event[0]).toBe(0);
|
|
51
|
-
done();
|
|
52
|
-
}, done);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('has version command', done => {
|
|
56
|
-
Rx.combineLatest(
|
|
57
|
-
run('--version').close,
|
|
58
|
-
run('-V').close,
|
|
59
|
-
run('-v').close
|
|
60
|
-
).subscribe(events => {
|
|
61
|
-
expect(events[0][0]).toBe(0);
|
|
62
|
-
expect(events[1][0]).toBe(0);
|
|
63
|
-
expect(events[2][0]).toBe(0);
|
|
64
|
-
done();
|
|
65
|
-
}, done);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('exiting conditions', () => {
|
|
69
|
-
it('is of success by default when running successful commands', done => {
|
|
70
|
-
run('"echo foo" "echo bar"')
|
|
71
|
-
.close
|
|
72
|
-
.subscribe(exit => {
|
|
73
|
-
expect(exit[0]).toBe(0);
|
|
74
|
-
done();
|
|
75
|
-
}, done);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('is of failure by default when one of the command fails', done => {
|
|
79
|
-
run('"echo foo" "exit 1"')
|
|
80
|
-
.close
|
|
81
|
-
.subscribe(exit => {
|
|
82
|
-
expect(exit[0]).toBeGreaterThan(0);
|
|
83
|
-
done();
|
|
84
|
-
}, done);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('is of success when --success=first and first command to exit succeeds', done => {
|
|
88
|
-
run('--success=first "echo foo" "sleep 0.5 && exit 1"')
|
|
89
|
-
.close
|
|
90
|
-
.subscribe(exit => {
|
|
91
|
-
expect(exit[0]).toBe(0);
|
|
92
|
-
done();
|
|
93
|
-
}, done);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('is of failure when --success=first and first command to exit fails', done => {
|
|
97
|
-
run('--success=first "exit 1" "sleep 0.5 && echo foo"')
|
|
98
|
-
.close
|
|
99
|
-
.subscribe(exit => {
|
|
100
|
-
expect(exit[0]).toBeGreaterThan(0);
|
|
101
|
-
done();
|
|
102
|
-
}, done);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('is of success when --success=last and last command to exit succeeds', done => {
|
|
106
|
-
run('--success=last "exit 1" "sleep 0.5 && echo foo"')
|
|
107
|
-
.close
|
|
108
|
-
.subscribe(exit => {
|
|
109
|
-
expect(exit[0]).toBe(0);
|
|
110
|
-
done();
|
|
111
|
-
}, done);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('is of failure when --success=last and last command to exit fails', done => {
|
|
115
|
-
run('--success=last "echo foo" "sleep 0.5 && exit 1"')
|
|
116
|
-
.close
|
|
117
|
-
.subscribe(exit => {
|
|
118
|
-
expect(exit[0]).toBeGreaterThan(0);
|
|
119
|
-
done();
|
|
120
|
-
}, done);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it.skip('is of success when a SIGINT is sent', done => {
|
|
124
|
-
const child = run('"node fixtures/read-echo.js"');
|
|
125
|
-
child.close.subscribe(exit => {
|
|
126
|
-
// TODO This is null within Node, but should be 0 outside (eg from real terminal)
|
|
127
|
-
expect(exit[0]).toBe(0);
|
|
128
|
-
done();
|
|
129
|
-
}, done);
|
|
130
|
-
|
|
131
|
-
process.kill(child.pid, 'SIGINT');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('is aliased to -s', done => {
|
|
135
|
-
run('-s last "exit 1" "sleep 0.5 && echo foo"')
|
|
136
|
-
.close
|
|
137
|
-
.subscribe(exit => {
|
|
138
|
-
expect(exit[0]).toBe(0);
|
|
139
|
-
done();
|
|
140
|
-
}, done);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe('--raw', () => {
|
|
145
|
-
it('is aliased to -r', done => {
|
|
146
|
-
const child = run('-r "echo foo" "echo bar"');
|
|
147
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
148
|
-
expect(lines).toHaveLength(2);
|
|
149
|
-
expect(lines).toContainEqual(expect.stringContaining('foo'));
|
|
150
|
-
expect(lines).toContainEqual(expect.stringContaining('bar'));
|
|
151
|
-
done();
|
|
152
|
-
}, done);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('does not log any extra output', done => {
|
|
156
|
-
const child = run('--raw "echo foo" "echo bar"');
|
|
157
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
158
|
-
expect(lines).toHaveLength(2);
|
|
159
|
-
expect(lines).toContainEqual(expect.stringContaining('foo'));
|
|
160
|
-
expect(lines).toContainEqual(expect.stringContaining('bar'));
|
|
161
|
-
done();
|
|
162
|
-
}, done);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('--names', () => {
|
|
167
|
-
it('is aliased to -n', done => {
|
|
168
|
-
const child = run('-n foo,bar "echo foo" "echo bar"');
|
|
169
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
170
|
-
expect(lines).toContainEqual(expect.stringContaining('[foo] foo'));
|
|
171
|
-
expect(lines).toContainEqual(expect.stringContaining('[bar] bar'));
|
|
172
|
-
done();
|
|
173
|
-
}, done);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('prefixes with names', done => {
|
|
177
|
-
const child = run('--names foo,bar "echo foo" "echo bar"');
|
|
178
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
179
|
-
expect(lines).toContainEqual(expect.stringContaining('[foo] foo'));
|
|
180
|
-
expect(lines).toContainEqual(expect.stringContaining('[bar] bar'));
|
|
181
|
-
done();
|
|
182
|
-
}, done);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('is split using --name-separator arg', done => {
|
|
186
|
-
const child = run('--names "foo|bar" --name-separator "|" "echo foo" "echo bar"');
|
|
187
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
188
|
-
expect(lines).toContainEqual(expect.stringContaining('[foo] foo'));
|
|
189
|
-
expect(lines).toContainEqual(expect.stringContaining('[bar] bar'));
|
|
190
|
-
done();
|
|
191
|
-
}, done);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('--prefix', () => {
|
|
196
|
-
it('is alised to -p', done => {
|
|
197
|
-
const child = run('-p command "echo foo" "echo bar"');
|
|
198
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
199
|
-
expect(lines).toContainEqual(expect.stringContaining('[echo foo] foo'));
|
|
200
|
-
expect(lines).toContainEqual(expect.stringContaining('[echo bar] bar'));
|
|
201
|
-
done();
|
|
202
|
-
}, done);
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('specifies custom prefix', done => {
|
|
206
|
-
const child = run('--prefix command "echo foo" "echo bar"');
|
|
207
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
208
|
-
expect(lines).toContainEqual(expect.stringContaining('[echo foo] foo'));
|
|
209
|
-
expect(lines).toContainEqual(expect.stringContaining('[echo bar] bar'));
|
|
210
|
-
done();
|
|
211
|
-
}, done);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('--prefix-length', () => {
|
|
216
|
-
it('is alised to -l', done => {
|
|
217
|
-
const child = run('-p command -l 5 "echo foo" "echo bar"');
|
|
218
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
219
|
-
expect(lines).toContainEqual(expect.stringContaining('[ec..o] foo'));
|
|
220
|
-
expect(lines).toContainEqual(expect.stringContaining('[ec..r] bar'));
|
|
221
|
-
done();
|
|
222
|
-
}, done);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('specifies custom prefix length', done => {
|
|
226
|
-
const child = run('--prefix command --prefix-length 5 "echo foo" "echo bar"');
|
|
227
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
228
|
-
expect(lines).toContainEqual(expect.stringContaining('[ec..o] foo'));
|
|
229
|
-
expect(lines).toContainEqual(expect.stringContaining('[ec..r] bar'));
|
|
230
|
-
done();
|
|
231
|
-
}, done);
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
describe('--restart-tries', () => {
|
|
236
|
-
it('changes how many times a command will restart', done => {
|
|
237
|
-
const child = run('--restart-tries 1 "exit 1"');
|
|
238
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
239
|
-
expect(lines).toEqual([
|
|
240
|
-
expect.stringContaining('[0] exit 1 exited with code 1'),
|
|
241
|
-
expect.stringContaining('[0] exit 1 restarted'),
|
|
242
|
-
expect.stringContaining('[0] exit 1 exited with code 1'),
|
|
243
|
-
]);
|
|
244
|
-
done();
|
|
245
|
-
}, done);
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe('--kill-others', () => {
|
|
250
|
-
it('is alised to -k', done => {
|
|
251
|
-
const child = run('-k "sleep 10" "exit 0"');
|
|
252
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
253
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] exit 0 exited with code 0'));
|
|
254
|
-
expect(lines).toContainEqual(expect.stringContaining('Sending SIGTERM to other processes'));
|
|
255
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] sleep 10')));
|
|
256
|
-
done();
|
|
257
|
-
}, done);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('kills on success', done => {
|
|
261
|
-
const child = run('--kill-others "sleep 10" "exit 0"');
|
|
262
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
263
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] exit 0 exited with code 0'));
|
|
264
|
-
expect(lines).toContainEqual(expect.stringContaining('Sending SIGTERM to other processes'));
|
|
265
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] sleep 10')));
|
|
266
|
-
done();
|
|
267
|
-
}, done);
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
it('kills on failure', done => {
|
|
271
|
-
const child = run('--kill-others "sleep 10" "exit 1"');
|
|
272
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
273
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] exit 1 exited with code 1'));
|
|
274
|
-
expect(lines).toContainEqual(expect.stringContaining('Sending SIGTERM to other processes'));
|
|
275
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] sleep 10')));
|
|
276
|
-
done();
|
|
277
|
-
}, done);
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
describe('--kill-others-on-fail', () => {
|
|
282
|
-
it('does not kill on success', done => {
|
|
283
|
-
const child = run('--kill-others-on-fail "sleep 0.5" "exit 0"');
|
|
284
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
285
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] exit 0 exited with code 0'));
|
|
286
|
-
expect(lines).toContainEqual(expect.stringContaining('[0] sleep 0.5 exited with code 0'));
|
|
287
|
-
done();
|
|
288
|
-
}, done);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it('kills on failure', done => {
|
|
292
|
-
const child = run('--kill-others-on-fail "sleep 10" "exit 1"');
|
|
293
|
-
child.log.pipe(buffer(child.close)).subscribe(lines => {
|
|
294
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] exit 1 exited with code 1'));
|
|
295
|
-
expect(lines).toContainEqual(expect.stringContaining('Sending SIGTERM to other processes'));
|
|
296
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] sleep 10')));
|
|
297
|
-
done();
|
|
298
|
-
}, done);
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
describe('--handle-input', () => {
|
|
303
|
-
it('is alised to -i', done => {
|
|
304
|
-
const child = run('-i "node fixtures/read-echo.js"');
|
|
305
|
-
child.log.subscribe(line => {
|
|
306
|
-
if (/READING/.test(line)) {
|
|
307
|
-
child.stdin.write('stop\n');
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (/\[0\] stop/.test(line)) {
|
|
311
|
-
done();
|
|
312
|
-
}
|
|
313
|
-
}, done);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it('forwards input to first process by default', done => {
|
|
317
|
-
const child = run('--handle-input "node fixtures/read-echo.js"');
|
|
318
|
-
child.log.subscribe(line => {
|
|
319
|
-
if (/READING/.test(line)) {
|
|
320
|
-
child.stdin.write('stop\n');
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (/\[0\] stop/.test(line)) {
|
|
324
|
-
done();
|
|
325
|
-
}
|
|
326
|
-
}, done);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
it('forwards input to process --default-input-target', done => {
|
|
331
|
-
const lines = [];
|
|
332
|
-
const child = run('-ki --default-input-target 1 "node fixtures/read-echo.js" "node fixtures/read-echo.js"');
|
|
333
|
-
child.log.subscribe(line => {
|
|
334
|
-
lines.push(line);
|
|
335
|
-
if (/\[1\] READING/.test(line)) {
|
|
336
|
-
child.stdin.write('stop\n');
|
|
337
|
-
}
|
|
338
|
-
}, done);
|
|
339
|
-
|
|
340
|
-
child.close.subscribe(exit => {
|
|
341
|
-
expect(exit[0]).toBeGreaterThan(0);
|
|
342
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] stop'));
|
|
343
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] node fixtures/read-echo.js')));
|
|
344
|
-
done();
|
|
345
|
-
}, done);
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
it('forwards input to specified process', done => {
|
|
349
|
-
const lines = [];
|
|
350
|
-
const child = run('-ki "node fixtures/read-echo.js" "node fixtures/read-echo.js"');
|
|
351
|
-
child.log.subscribe(line => {
|
|
352
|
-
lines.push(line);
|
|
353
|
-
if (/\[1\] READING/.test(line)) {
|
|
354
|
-
child.stdin.write('1:stop\n');
|
|
355
|
-
}
|
|
356
|
-
}, done);
|
|
357
|
-
|
|
358
|
-
child.close.subscribe(exit => {
|
|
359
|
-
expect(exit[0]).toBeGreaterThan(0);
|
|
360
|
-
expect(lines).toContainEqual(expect.stringContaining('[1] stop'));
|
|
361
|
-
expect(lines).toContainEqual(expect.stringMatching(createKillMessage('[0] node fixtures/read-echo.js')));
|
|
362
|
-
done();
|
|
363
|
-
}, done);
|
|
364
|
-
});
|
|
365
|
-
});
|
package/docs/demo.gif
DELETED
|
Binary file
|
package/docs/frontend-demo.gif
DELETED
|
Binary file
|
package/docs/kill-demo.gif
DELETED
|
Binary file
|
package/docs/raw-demo.gif
DELETED
|
Binary file
|