concurrently 3.4.0 → 3.6.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/.eslintrc.json +23 -0
- package/.travis.yml +4 -3
- package/README.md +115 -18
- package/appveyor.yml +1 -2
- package/package.json +11 -3
- package/src/findChild.js +11 -0
- package/src/main.js +251 -126
- package/src/parseCmds.js +65 -0
- package/src/pkgInfo.js +17 -0
- package/test/support/read-echo.js +12 -0
- package/test/support/signal.js +5 -5
- package/test/test-findChild.js +39 -0
- package/test/test-functional.js +329 -88
- package/test/test-parseCmds.js +204 -0
- package/test/utils.js +42 -17
- package/.eslintrc +0 -31
- package/.jshintrc +0 -17
- package/.npmignore +0 -31
- package/tst.js +0 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const sinon = require('sinon');
|
|
4
|
+
|
|
5
|
+
const parseCmds = require('../src/parseCmds');
|
|
6
|
+
|
|
7
|
+
const sandbox = sinon.createSandbox();
|
|
8
|
+
|
|
9
|
+
describe('parseCmds', () => {
|
|
10
|
+
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
sandbox.restore();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns a list of command objects', () => {
|
|
16
|
+
const cmds = parseCmds([ 'echo test' ]);
|
|
17
|
+
|
|
18
|
+
assert.deepStrictEqual(cmds, [
|
|
19
|
+
{
|
|
20
|
+
cmd: 'echo test',
|
|
21
|
+
name: '',
|
|
22
|
+
color: undefined
|
|
23
|
+
}
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('strips quotes', () => {
|
|
28
|
+
const cmds = parseCmds([ '"echo test"' ]);
|
|
29
|
+
|
|
30
|
+
assert.deepStrictEqual(cmds, [
|
|
31
|
+
{
|
|
32
|
+
cmd: 'echo test',
|
|
33
|
+
name: '',
|
|
34
|
+
color: undefined
|
|
35
|
+
}
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('assigns names', () => {
|
|
40
|
+
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
41
|
+
names: 'echo-test,echo-test2'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
assert.deepStrictEqual(cmds, [
|
|
45
|
+
{
|
|
46
|
+
cmd: 'echo test',
|
|
47
|
+
name: 'echo-test',
|
|
48
|
+
color: undefined
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
cmd: 'echo test2',
|
|
52
|
+
name: 'echo-test2',
|
|
53
|
+
color: undefined
|
|
54
|
+
}
|
|
55
|
+
]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('assigns names with custom separator', () => {
|
|
59
|
+
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
60
|
+
names: 'echo-test|echo-test2',
|
|
61
|
+
nameSeparator: '|'
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
assert.deepStrictEqual(cmds, [
|
|
65
|
+
{
|
|
66
|
+
cmd: 'echo test',
|
|
67
|
+
name: 'echo-test',
|
|
68
|
+
color: undefined
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
cmd: 'echo test2',
|
|
72
|
+
name: 'echo-test2',
|
|
73
|
+
color: undefined
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('assigns colours', () => {
|
|
79
|
+
const cmds = parseCmds([ 'echo test', 'echo test2' ], {
|
|
80
|
+
prefixColors: 'blue'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
assert.deepStrictEqual(cmds, [
|
|
84
|
+
{
|
|
85
|
+
cmd: 'echo test',
|
|
86
|
+
name: '',
|
|
87
|
+
color: 'blue'
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
cmd: 'echo test2',
|
|
91
|
+
name: '',
|
|
92
|
+
color: undefined
|
|
93
|
+
}
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('expands npm: shortcut', () => {
|
|
98
|
+
const cmds = parseCmds([ 'npm:watch:js' ]);
|
|
99
|
+
|
|
100
|
+
assert.deepStrictEqual(cmds, [
|
|
101
|
+
{
|
|
102
|
+
cmd: 'npm run watch:js',
|
|
103
|
+
name: 'watch:js',
|
|
104
|
+
color: undefined
|
|
105
|
+
}
|
|
106
|
+
]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('expands npm: shortcut with assigned name', () => {
|
|
110
|
+
const cmds = parseCmds([ 'npm:watch:js' ], {
|
|
111
|
+
names: 'js'
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
assert.deepStrictEqual(cmds, [
|
|
115
|
+
{
|
|
116
|
+
cmd: 'npm run watch:js',
|
|
117
|
+
name: 'js',
|
|
118
|
+
color: undefined
|
|
119
|
+
}
|
|
120
|
+
]);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('expands npm: shortcut with wildcard', () => {
|
|
124
|
+
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
125
|
+
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
const cmds = parseCmds([ 'npm:watch:*' ]);
|
|
129
|
+
|
|
130
|
+
assert.deepStrictEqual(cmds, [
|
|
131
|
+
{
|
|
132
|
+
cmd: 'npm run watch:js',
|
|
133
|
+
name: 'js',
|
|
134
|
+
color: undefined
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
cmd: 'npm run watch:css',
|
|
138
|
+
name: 'css',
|
|
139
|
+
color: undefined
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
cmd: 'npm run watch:node',
|
|
143
|
+
name: 'node',
|
|
144
|
+
color: undefined
|
|
145
|
+
}
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('expands npm: shortcut with wildcard and name prefix', () => {
|
|
150
|
+
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
151
|
+
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
152
|
+
]);
|
|
153
|
+
|
|
154
|
+
const cmds = parseCmds([ 'npm:watch:*' ], {
|
|
155
|
+
names: 'w:'
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
assert.deepStrictEqual(cmds, [
|
|
159
|
+
{
|
|
160
|
+
cmd: 'npm run watch:js',
|
|
161
|
+
name: 'w:js',
|
|
162
|
+
color: undefined
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
cmd: 'npm run watch:css',
|
|
166
|
+
name: 'w:css',
|
|
167
|
+
color: undefined
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
cmd: 'npm run watch:node',
|
|
171
|
+
name: 'w:node',
|
|
172
|
+
color: undefined
|
|
173
|
+
}
|
|
174
|
+
]);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('applies prefix colors to expanded commands', () => {
|
|
178
|
+
sandbox.stub(require('../src/pkgInfo'), 'getScripts').returns([
|
|
179
|
+
'test', 'start', 'watch:js', 'watch:css', 'watch:node'
|
|
180
|
+
]);
|
|
181
|
+
|
|
182
|
+
const cmds = parseCmds([ 'npm:watch:*' ], {
|
|
183
|
+
prefixColors: 'blue,magenta,cyan'
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
assert.deepStrictEqual(cmds, [
|
|
187
|
+
{
|
|
188
|
+
cmd: 'npm run watch:js',
|
|
189
|
+
name: 'js',
|
|
190
|
+
color: 'blue'
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
cmd: 'npm run watch:css',
|
|
194
|
+
name: 'css',
|
|
195
|
+
color: 'magenta'
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
cmd: 'npm run watch:node',
|
|
199
|
+
name: 'node',
|
|
200
|
+
color: 'cyan'
|
|
201
|
+
}
|
|
202
|
+
]);
|
|
203
|
+
});
|
|
204
|
+
});
|
package/test/utils.js
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
const childProcess = require('child_process');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const readline = require('readline');
|
|
5
|
+
const shellQuote = require('shell-quote');
|
|
6
|
+
|
|
7
|
+
// If true, output of commands are shown
|
|
8
|
+
const DEBUG_TESTS = process.env.DEBUG_TESTS === 'true';
|
|
4
9
|
|
|
5
10
|
function run(cmd, opts) {
|
|
6
11
|
opts = _.merge({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// this callback if one wants to access the child
|
|
12
|
-
// process reference
|
|
13
|
-
// Called immediately after successful child process
|
|
14
|
-
// spawn
|
|
15
|
-
}
|
|
12
|
+
// If set to a function, it will be called for each line
|
|
13
|
+
// written to the child process's stdout as (line, child)
|
|
14
|
+
onOutputLine: undefined,
|
|
15
|
+
onErrorLine: undefined
|
|
16
16
|
}, opts);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
let child;
|
|
19
|
+
const parts = shellQuote.parse(cmd);
|
|
20
20
|
try {
|
|
21
21
|
child = childProcess.spawn(_.head(parts), _.tail(parts), {
|
|
22
|
-
|
|
23
|
-
stdio: opts.pipe ? "inherit" : null
|
|
22
|
+
stdio: DEBUG_TESTS && !opts.onOutputLine ? 'inherit': null,
|
|
24
23
|
});
|
|
25
24
|
} catch (e) {
|
|
26
25
|
return Promise.reject(e);
|
|
27
26
|
}
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
if (opts.onOutputLine) {
|
|
29
|
+
readLines(child, opts.onOutputLine);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (opts.onErrorLine) {
|
|
33
|
+
readLines(child, opts.onErrorLine, 'stderr');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
readLines(child, (l) => { console.log(l); }, 'stderr');
|
|
29
37
|
|
|
30
38
|
return new Promise(function(resolve, reject) {
|
|
31
39
|
child.on('error', function(err) {
|
|
@@ -38,6 +46,23 @@ function run(cmd, opts) {
|
|
|
38
46
|
});
|
|
39
47
|
}
|
|
40
48
|
|
|
49
|
+
function readLines(child, callback, src) {
|
|
50
|
+
src = src || 'stdout';
|
|
51
|
+
|
|
52
|
+
const rl = readline.createInterface({
|
|
53
|
+
input: child[src],
|
|
54
|
+
output: null
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
rl.on('line', function(line) {
|
|
58
|
+
if (DEBUG_TESTS) {
|
|
59
|
+
console.log(line);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
callback(line, child);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
41
66
|
module.exports = {
|
|
42
67
|
run: run
|
|
43
68
|
};
|
package/.eslintrc
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"node": true
|
|
5
|
-
},
|
|
6
|
-
"globals": {},
|
|
7
|
-
"rules": {
|
|
8
|
-
"no-bitwise": 2,
|
|
9
|
-
"camelcase": 2,
|
|
10
|
-
"curly": 2,
|
|
11
|
-
"eqeqeq": 2,
|
|
12
|
-
"wrap-iife": [
|
|
13
|
-
2,
|
|
14
|
-
"any"
|
|
15
|
-
],
|
|
16
|
-
"indent": [
|
|
17
|
-
2,
|
|
18
|
-
4,
|
|
19
|
-
{
|
|
20
|
-
"SwitchCase": 1
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
"no-use-before-define": 0,
|
|
24
|
-
"new-cap": 2,
|
|
25
|
-
"no-caller": 2,
|
|
26
|
-
"quotes": [
|
|
27
|
-
2,
|
|
28
|
-
"single"
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
|
-
}
|
package/.jshintrc
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"node": true,
|
|
3
|
-
"browser": true,
|
|
4
|
-
"predef": [ "Promise" ],
|
|
5
|
-
"bitwise": true,
|
|
6
|
-
"camelcase": true,
|
|
7
|
-
"curly": true,
|
|
8
|
-
"eqeqeq": true,
|
|
9
|
-
"immed": true,
|
|
10
|
-
"indent": 4,
|
|
11
|
-
"latedef": false,
|
|
12
|
-
"newcap": true,
|
|
13
|
-
"noarg": true,
|
|
14
|
-
"quotmark": "single",
|
|
15
|
-
"regexp": true,
|
|
16
|
-
"devel": true
|
|
17
|
-
}
|
package/.npmignore
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Logs
|
|
2
|
-
logs
|
|
3
|
-
*.log
|
|
4
|
-
|
|
5
|
-
# Runtime data
|
|
6
|
-
pids
|
|
7
|
-
*.pid
|
|
8
|
-
*.seed
|
|
9
|
-
|
|
10
|
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
11
|
-
lib-cov
|
|
12
|
-
|
|
13
|
-
# Coverage directory used by tools like istanbul
|
|
14
|
-
coverage
|
|
15
|
-
|
|
16
|
-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
17
|
-
.grunt
|
|
18
|
-
|
|
19
|
-
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
20
|
-
build/Release
|
|
21
|
-
|
|
22
|
-
# Dependency directory
|
|
23
|
-
# Deployed apps should consider commenting this line out:
|
|
24
|
-
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
|
25
|
-
node_modules
|
|
26
|
-
|
|
27
|
-
# OS X
|
|
28
|
-
.DS_Store
|
|
29
|
-
|
|
30
|
-
# Vagrant directory
|
|
31
|
-
.vagrant
|
package/tst.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
setTimeout(() =>console.log("i win!"), 3000);
|