concurrently 5.0.0 → 5.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.
Files changed (37) hide show
  1. package/README.md +19 -18
  2. package/bin/concurrently.js +9 -1
  3. package/bin/epilogue.txt +0 -4
  4. package/index.js +3 -1
  5. package/package.json +11 -4
  6. package/src/completion-listener.js +26 -22
  7. package/src/concurrently.js +27 -9
  8. package/src/defaults.js +2 -0
  9. package/src/flow-control/kill-on-signal.js +1 -1
  10. package/src/get-spawn-opts.js +5 -4
  11. package/.editorconfig +0 -28
  12. package/.eslintrc.json +0 -23
  13. package/.travis.yml +0 -11
  14. package/.vscode/settings.json +0 -6
  15. package/CONTRIBUTING.md +0 -23
  16. package/appveyor.yml +0 -19
  17. package/bin/concurrently.spec.js +0 -365
  18. package/bin/fixtures/read-echo.js +0 -10
  19. package/docs/demo.gif +0 -0
  20. package/docs/frontend-demo.gif +0 -0
  21. package/docs/kill-demo.gif +0 -0
  22. package/docs/raw-demo.gif +0 -0
  23. package/src/command-parser/expand-npm-shortcut.spec.js +0 -36
  24. package/src/command-parser/expand-npm-wildcard.spec.js +0 -58
  25. package/src/command-parser/strip-quotes.spec.js +0 -20
  26. package/src/command.spec.js +0 -142
  27. package/src/completion-listener.spec.js +0 -88
  28. package/src/concurrently.spec.js +0 -77
  29. package/src/flow-control/input-handler.spec.js +0 -79
  30. package/src/flow-control/kill-on-signal.spec.js +0 -79
  31. package/src/flow-control/kill-others.spec.js +0 -66
  32. package/src/flow-control/log-error.spec.js +0 -40
  33. package/src/flow-control/log-exit.spec.js +0 -36
  34. package/src/flow-control/log-output.spec.js +0 -41
  35. package/src/flow-control/restart-process.spec.js +0 -129
  36. package/src/get-spawn-opts.spec.js +0 -18
  37. package/src/logger.spec.js +0 -178
package/README.md CHANGED
@@ -113,18 +113,21 @@ Help:
113
113
  concurrently [options] <command ...>
114
114
 
115
115
  General
116
- -n, --names List of custom names to be used in prefix template.
117
- Example names: "main,browser,server" [string]
118
- --name-separator The character to split <names> on. Example usage:
119
- concurrently -n "styles|scripts|server" --name-separator "|"
120
- [default: ","]
121
- -r, --raw Output only raw output of processes, disables prettifying
122
- and concurrently coloring. [boolean]
123
- -s, --success Return exit code of zero or one based on the success or
124
- failure of the "first" child to terminate, the "last child",
125
- or succeed only if "all" child processes succeed.
116
+ -m, --max-processes How many processes should run at once.
117
+ New processes only spawn after all restart tries of a
118
+ process. [number]
119
+ -n, --names List of custom names to be used in prefix template.
120
+ Example names: "main,browser,server" [string]
121
+ --name-separator The character to split <names> on. Example usage:
122
+ concurrently -n "styles|scripts|server" --name-separator
123
+ "|" [default: ","]
124
+ -r, --raw Output only raw output of processes, disables prettifying
125
+ and concurrently coloring. [boolean]
126
+ -s, --success Return exit code of zero or one based on the success or
127
+ failure of the "first" child to terminate, the "last
128
+ child", or succeed only if "all" child processes succeed.
126
129
  [choices: "first", "last", "all"] [default: "all"]
127
- --no-color Disables colors from logging [boolean]
130
+ --no-color Disables colors from logging [boolean]
128
131
 
129
132
  Prefix styling
130
133
  -p, --prefix Prefix used in logging for each process.
@@ -191,10 +194,6 @@ Examples:
191
194
  $ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold"
192
195
  "http-server" "npm run watch"
193
196
 
194
- - Shortened NPM run commands
195
-
196
- $ concurrently npm:watch-node npm:watch-js npm:watch-css
197
-
198
197
  - Send input to default
199
198
 
200
199
  $ concurrently --handle-input "nodemon" "npm run watch-js"
@@ -226,7 +225,7 @@ concurrently can be used programmatically by using the API documented below:
226
225
 
227
226
  ### `concurrently(commands[, options])`
228
227
  - `commands`: an array of either strings (containing the commands to run) or objects
229
- with the shape `{ command, name, prefixColor }`.
228
+ with the shape `{ command, name, prefixColor, env }`.
230
229
  - `options` (optional): an object containing any of the below:
231
230
  - `defaultInputTarget`: the default input target when reading from `inputStream`.
232
231
  Default: `0`.
@@ -234,6 +233,7 @@ concurrently can be used programmatically by using the API documented below:
234
233
  to read the input from, eg `process.stdin`.
235
234
  - `killOthers`: an array of exitting conditions that will cause a process to kill others.
236
235
  Can contain any of `success` or `failure`.
236
+ - `maxProcesses`: how many processes should run at once.
237
237
  - `outputStream`: a [`Writable` stream](https://nodejs.org/dist/latest-v10.x/docs/api/stream.html#stream_writable_streams)
238
238
  to write logs to. Default: `process.stdout`.
239
239
  - `prefix`: the prefix type to use when logging processes output.
@@ -251,7 +251,7 @@ concurrently can be used programmatically by using the API documented below:
251
251
  to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
252
252
 
253
253
  > Returns: a `Promise` that resolves if the run was successful (according to `successCondition` option),
254
- > or rejects otherwise.
254
+ > or rejects, containing an array with the exit codes of each command that has been run.
255
255
 
256
256
  Example:
257
257
 
@@ -259,7 +259,8 @@ Example:
259
259
  const concurrently = require('concurrently');
260
260
  concurrently([
261
261
  'npm:watch-*',
262
- { command: 'nodemon', name: 'server' }
262
+ { command: 'nodemon', name: 'server' },
263
+ { command: 'deploy', name: 'deploy', env: { PUBLIC_KEY: '...' } }
263
264
  ], {
264
265
  prefix: 'name',
265
266
  killOthers: ['failure', 'success'],
@@ -13,6 +13,13 @@ const args = yargs
13
13
  .alias('v', 'version')
14
14
  .options({
15
15
  // General
16
+ 'm': {
17
+ alias: 'max-processes',
18
+ describe:
19
+ 'How many processes should run at once.\n' +
20
+ 'New processes only spawn after all restart tries of a process.',
21
+ type: 'number'
22
+ },
16
23
  'n': {
17
24
  alias: 'names',
18
25
  describe:
@@ -125,7 +132,7 @@ const args = yargs
125
132
  'Can be either the index or the name of the process.'
126
133
  }
127
134
  })
128
- .group(['n', 'name-separator', 'raw', 's', 'no-color'], 'General')
135
+ .group(['m', 'n', 'name-separator', 'raw', 's', 'no-color'], 'General')
129
136
  .group(['p', 'c', 'l', 't'], 'Prefix styling')
130
137
  .group(['i', 'default-input-target'], 'Input handling')
131
138
  .group(['k', 'kill-others-on-fail'], 'Killing other processes')
@@ -152,6 +159,7 @@ concurrently(args._.map((command, index) => {
152
159
  killOthers: args.killOthers
153
160
  ? ['success', 'failure']
154
161
  : (args.killOthersOnFail ? ['failure'] : []),
162
+ maxProcesses: args.maxProcesses,
155
163
  raw: args.raw,
156
164
  prefix: args.prefix,
157
165
  prefixLength: args.prefixLength,
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/index.js CHANGED
@@ -19,6 +19,7 @@ module.exports = (commands, options = {}) => {
19
19
  });
20
20
 
21
21
  return concurrently(commands, {
22
+ maxProcesses: options.maxProcesses,
22
23
  raw: options.raw,
23
24
  successCondition: options.successCondition,
24
25
  controllers: [
@@ -30,7 +31,7 @@ module.exports = (commands, options = {}) => {
30
31
  defaultInputTarget: options.defaultInputTarget,
31
32
  inputStream: options.inputStream,
32
33
  }),
33
- new KillOnSignal(),
34
+ new KillOnSignal({ process }),
34
35
  new RestartProcess({
35
36
  logger,
36
37
  delay: options.restartDelay,
@@ -47,6 +48,7 @@ module.exports = (commands, options = {}) => {
47
48
  // Export all flow controllers and the main concurrently function,
48
49
  // so that 3rd-parties can use them however they want
49
50
  exports.concurrently = concurrently;
51
+ exports.Logger = Logger;
50
52
  exports.InputHandler = InputHandler;
51
53
  exports.KillOnSignal = KillOnSignal;
52
54
  exports.KillOthers = KillOthers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "concurrently",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "description": "Run commands concurrently",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -35,9 +35,9 @@
35
35
  "read-pkg": "^4.0.1",
36
36
  "rxjs": "^6.5.2",
37
37
  "spawn-command": "^0.0.2-1",
38
- "supports-color": "^4.5.0",
39
- "tree-kill": "^1.2.1",
40
- "yargs": "^12.0.5"
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
- listen(commands) {
11
- const closeStreams = commands.map(command => command.close);
12
- const allClosed = Rx.zip(...closeStreams);
13
- return Rx.merge(...closeStreams).pipe(
14
- bufferCount(closeStreams.length),
15
- map(exitCodes => {
16
- switch (this.successCondition) {
17
- /* eslint-disable indent */
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
- case 'last':
22
- return exitCodes[exitCodes.length - 1] === 0;
19
+ default:
20
+ return exitCodes.every(exitCode => exitCode === 0);
21
+ /* eslint-enable indent */
22
+ }
23
+ }
23
24
 
24
- default:
25
- return exitCodes.every(exitCode => exitCode === 0);
26
- /* eslint-enable indent */
27
- }
28
- }),
29
- switchMap(success => success
30
- ? Rx.of(null, this.scheduler)
31
- : Rx.throwError(new Error(), this.scheduler)),
32
- take(1)
33
- ).toPromise();
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
  };
@@ -31,17 +31,17 @@ module.exports = (commands, options) => {
31
31
  new ExpandNpmWildcard()
32
32
  ];
33
33
 
34
- const spawnOpts = getSpawnOpts({ raw: options.raw });
35
-
36
34
  commands = _(commands)
37
35
  .map(mapToCommandInfo)
38
36
  .flatMap(command => parseCommand(command, commandParsers))
39
- .map((command, index) => new Command(Object.assign({
40
- index,
41
- spawnOpts,
42
- killProcess: options.kill,
43
- spawn: options.spawn,
44
- }, command)))
37
+ .map((command, index) => new Command(
38
+ Object.assign({
39
+ index,
40
+ spawnOpts: getSpawnOpts({ raw: options.raw, env: command.env }),
41
+ killProcess: options.kill,
42
+ spawn: options.spawn,
43
+ }, command)
44
+ ))
45
45
  .value();
46
46
 
47
47
  commands = options.controllers.reduce(
@@ -49,7 +49,12 @@ module.exports = (commands, options) => {
49
49
  commands
50
50
  );
51
51
 
52
- commands.forEach(command => command.start());
52
+ const commandsLeft = commands.slice();
53
+ const maxProcesses = Math.max(1, Number(options.maxProcesses) || commandsLeft.length);
54
+ for (let i = 0; i < maxProcesses; i++) {
55
+ maybeRunMore(commandsLeft);
56
+ }
57
+
53
58
  return new CompletionListener({ successCondition: options.successCondition }).listen(commands);
54
59
  };
55
60
 
@@ -58,6 +63,7 @@ function mapToCommandInfo(command) {
58
63
  command: command.command || command,
59
64
  name: command.name || '',
60
65
  prefixColor: command.prefixColor || '',
66
+ env: command.env || {},
61
67
  };
62
68
  }
63
69
 
@@ -67,3 +73,15 @@ function parseCommand(command, parsers) {
67
73
  _.castArray(command)
68
74
  );
69
75
  }
76
+
77
+ function maybeRunMore(commandsLeft) {
78
+ const command = commandsLeft.shift();
79
+ if (!command) {
80
+ return;
81
+ }
82
+
83
+ command.start();
84
+ command.close.subscribe(() => {
85
+ maybeRunMore(commandsLeft);
86
+ });
87
+ }
package/src/defaults.js CHANGED
@@ -8,6 +8,8 @@ module.exports = {
8
8
  defaultInputTarget: 0,
9
9
  // Whether process.stdin should be forwarded to child processes
10
10
  handleInput: false,
11
+ // How many processes to run at once
12
+ maxProcesses: 0,
11
13
  nameSeparator: ',',
12
14
  // Which prefix style to use when logging processes output.
13
15
  prefix: '',
@@ -2,7 +2,7 @@ const { map } = require('rxjs/operators');
2
2
 
3
3
 
4
4
  module.exports = class KillOnSignal {
5
- constructor({ process = global.process } = {}) {
5
+ constructor({ process }) {
6
6
  this.process = process;
7
7
  }
8
8
 
@@ -1,12 +1,13 @@
1
1
  const supportsColor = require('supports-color');
2
2
 
3
3
  module.exports = ({
4
- colorSupport = supportsColor,
4
+ colorSupport = supportsColor.stdout,
5
5
  process = global.process,
6
- raw = false
7
- } = {}) => Object.assign(
6
+ raw = false,
7
+ env = {}
8
+ }) => Object.assign(
8
9
  {},
9
10
  raw && { stdio: 'inherit' },
10
11
  /^win/.test(process.platform) && { detached: false },
11
- colorSupport && { env: Object.assign({ FORCE_COLOR: colorSupport.level }, process.env) }
12
+ { env: Object.assign(colorSupport ? { FORCE_COLOR: colorSupport.level } : {}, process.env, env) }
12
13
  );
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
@@ -1,11 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - 12
4
- - 10
5
- - 8
6
- - 6
7
- script:
8
- - npm test
9
- - npm run lint
10
- after_success:
11
- - npm run report-coverage
@@ -1,6 +0,0 @@
1
- {
2
- "eslint.enable": true,
3
- "jest.autoEnable": true,
4
- "jest.showCoverageOnLoad": true,
5
- "editor.rulers": [100]
6
- }
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,19 +0,0 @@
1
- environment:
2
- matrix:
3
- - nodejs_version: '12'
4
- - nodejs_version: '10'
5
- - nodejs_version: '8'
6
- - nodejs_version: '6'
7
- install:
8
- - ps: Install-Product node $env:nodejs_version
9
- - set CI=true
10
- - npm -g install npm@latest
11
- - set PATH=%APPDATA%\npm;%PATH%
12
- - npm install
13
- build: off
14
- test_script:
15
- - node --version
16
- - npm --version
17
- - set SHELL=cmd.exe
18
- - set SHELL_EXECUTION_FLAG=/c
19
- - npm test