Skip to content

Commit

Permalink
Merge branch 'master' into success-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
paescuj committed May 9, 2022
2 parents 093f58b + e9d2b94 commit 19f1f91
Show file tree
Hide file tree
Showing 15 changed files with 465 additions and 110 deletions.
9 changes: 5 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
# Unix-style newlines with newline ending and space indentation for all files
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space

# Tab indentation (no size specified)
[*.js]
# 4 space indentation and max line length of 100 in *.ts files
[*.ts]
indent_size = 4
max_line_length = 100

# Matches the exact files package.json
# 2 space indentation in package.json
[package.json]
indent_size = 2
87 changes: 56 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,38 +134,43 @@ Good frontend one-liner example [here](https://github.com/kimmobrunfeldt/dont-co
Help:

```
concurrently [options] <command ...>
General
-m, --max-processes How many processes should run at once.
New processes only spawn after all restart tries of a
process. [number]
-n, --names List of custom names to be used in prefix template.
Example names: "main,browser,server" [string]
--name-separator The character to split <names> on. Example usage:
concurrently -n "styles|scripts|server" --name-separator
"|" [default: ","]
-r, --raw Output only raw output of processes, disables
prettifying and concurrently coloring. [boolean]
-s, --success Which command(s) must exit with code 0 in order for
concurrently exit with code 0 too. Options are:
- "first" for the first command to exit;
- "last" for the last command to exit;
- "all" for all commands;
- "command-{name}"/"command-{index}" for the command
with that name or index;
- "!command-{name}"/"!command-{index}" for all commands
but the one with that name or index.
-m, --max-processes How many processes should run at once.
New processes only spawn after all restart tries
of a process. [number]
-n, --names List of custom names to be used in prefix
template.
Example names: "main,browser,server" [string]
--name-separator The character to split <names> on. Example usage:
concurrently -n "styles|scripts|server"
--name-separator "|" [default: ","]
-s, --success Which command(s) must exit with code 0 in order
for concurrently exit with code 0 too. Options
are:
- "first" for the first command to exit;
- "last" for the last command to exit;
- "all" for all commands;
- "command-{name}"/"command-{index}" for the
command with that name or index;
- "!command-{name}"/"!command-{index}" for all
commands but the one with that name or index.
[default: "all"]
--no-color Disables colors from logging [boolean]
--hide Comma-separated list of processes to hide the output.
The processes can be identified by their name or index.
[string] [default: ""]
-g, --group Order the output as if the commands were run
sequentially. [boolean]
--timings Show timing information for all processes
-r, --raw Output only raw output of processes, disables
prettifying and concurrently coloring. [boolean]
--no-color Disables colors from logging. [boolean]
--hide Comma-separated list of processes to hide the
output.
The processes can be identified by their name or
index. [string] [default: ""]
-g, --group Order the output as if the commands were run
sequentially. [boolean]
--timings Show timing information for all processes.
[boolean] [default: false]
-P, --passthrough-arguments Passthrough additional arguments to commands
(accessible via placeholders) instead of treating
them as commands. [boolean] [default: false]
Prefix styling
-p, --prefix Prefix used in logging for each process.
Expand Down Expand Up @@ -202,9 +207,9 @@ Input handling
process. [default: 0]
Killing other processes
-k, --kill-others kill other processes if one exits or dies [boolean]
--kill-others-on-fail kill other processes if one exits with non zero
status code [boolean]
-k, --kill-others Kill other processes if one exits or dies.[boolean]
--kill-others-on-fail Kill other processes if one exits with non zero
status code. [boolean]
Restarting
--restart-tries How many times a process that died should restart.
Expand All @@ -217,6 +222,7 @@ Options:
-h, --help Show help [boolean]
-v, -V, --version Show version number [boolean]
Examples:
- Output nothing more than stdout+stderr of child processes
Expand All @@ -238,7 +244,8 @@ Examples:
- Configuring via environment variables with CONCURRENTLY_ prefix
$ CONCURRENTLY_RAW=true CONCURRENTLY_KILL_OTHERS=true concurrently "echo hello" "echo world"
$ CONCURRENTLY_RAW=true CONCURRENTLY_KILL_OTHERS=true concurrently "echo
hello" "echo world"
- Send input to default
Expand All @@ -263,6 +270,23 @@ Examples:
$ concurrently "npm:watch-*"
- Exclude patterns so that between "lint:js" and "lint:fix:js", only "lint:js"
is ran
$ concurrently "npm:*(!fix)"
- Passthrough some additional arguments via '{<number>}' placeholder
$ concurrently -P "echo {1}" -- foo
- Passthrough all additional arguments via '{@}' placeholder
$ concurrently -P "npm:dev-* -- {@}" -- --watch --noEmit
- Passthrough all additional arguments combined via '{*}' placeholder
$ concurrently -P "npm:dev-* -- {*}" -- --watch --noEmit
For more details, visit https://github.com/open-cli-tools/concurrently
```

Expand Down Expand Up @@ -304,6 +328,7 @@ concurrently can be used programmatically by using the API documented below:
- `restartDelay`: how many milliseconds to wait between process restarts. Default: `0`.
- `timestampFormat`: a [date-fns format](https://date-fns.org/v2.0.1/docs/format)
to use when prefixing with `time`. Default: `yyyy-MM-dd HH:mm:ss.ZZZ`
- `additionalArguments`: list of additional arguments passed that will get replaced in each command. If not defined, no argument replacing will happen.

> **Returns:** an object in the shape `{ result, commands }`.
> - `result`: a `Promise` that resolves if the run was successful (according to `successCondition` option),
Expand Down
23 changes: 21 additions & 2 deletions bin/concurrently.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ it('has help command', done => {
});

it('has version command', done => {
Rx.combineLatest(
Rx.combineLatest([
run('--version').close,
run('-V').close,
run('-v').close,
).subscribe(events => {
]).subscribe(events => {
expect(events[0][0]).toBe(0);
expect(events[1][0]).toBe(0);
expect(events[2][0]).toBe(0);
Expand Down Expand Up @@ -446,3 +446,22 @@ describe('--timings', () => {
}, done);
});
});

describe('--passthrough-arguments', () => {
it('argument placeholders are properly replaced when passthrough-arguments is enabled', done => {
const child = run('--passthrough-arguments "echo {1}" -- echo');
child.log.pipe(buffer(child.close)).subscribe(lines => {
expect(lines).toContainEqual(expect.stringContaining('[0] echo echo exited with code 0'));
done();
}, done);
});

it('argument placeholders are not replaced when passthrough-arguments is disabled', done => {
const child = run('"echo {1}" -- echo');
child.log.pipe(buffer(child.close)).subscribe(lines => {
expect(lines).toContainEqual(expect.stringContaining('[0] echo {1} exited with code 0'));
expect(lines).toContainEqual(expect.stringContaining('[1] echo exited with code 0'));
done();
}, done);
});
});
83 changes: 54 additions & 29 deletions bin/concurrently.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#!/usr/bin/env node
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import * as defaults from '../src/defaults';
import concurrently from '../src/index';
import { epilogue } from './epilogue';

const args = yargs
// Clean-up arguments (yargs expects only the arguments after the program name)
const cleanArgs = hideBin(process.argv);
// Find argument separator (double dash)
const argsSepIdx = cleanArgs.findIndex((arg) => arg === '--');
// Arguments before separator
const argsBeforeSep = argsSepIdx >= 0 ? cleanArgs.slice(0, argsSepIdx) : cleanArgs;
// Arguments after separator
const argsAfterSep = argsSepIdx >= 0 ? cleanArgs.slice(argsSepIdx + 1) : [];

const args = yargs(argsBeforeSep)
.usage('$0 [options] <command ...>')
.help('h')
.alias('h', 'help')
Expand Down Expand Up @@ -74,19 +84,27 @@ const args = yargs
type: 'boolean',
},
'timings': {
describe: 'Show timing information for all processes',
describe: 'Show timing information for all processes.',
type: 'boolean',
default: defaults.timings,
},
'passthrough-arguments': {
alias: 'P',
describe:
'Passthrough additional arguments to commands (accessible via placeholders) ' +
'instead of treating them as commands.',
type: 'boolean',
default: defaults.passthroughArguments,
},

// Kill others
'kill-others': {
alias: 'k',
describe: 'kill other processes if one exits or dies',
describe: 'Kill other processes if one exits or dies.',
type: 'boolean',
},
'kill-others-on-fail': {
describe: 'kill other processes if one exits with non zero status code',
describe: 'Kill other processes if one exits with non zero status code.',
type: 'boolean',
},

Expand Down Expand Up @@ -158,38 +176,45 @@ const args = yargs
'Can be either the index or the name of the process.',
},
})
.group(['m', 'n', 'name-separator', 'raw', 's', 'no-color', 'hide', 'group', 'timings'], 'General')
.group(['m', 'n', 'name-separator', 's', 'r', 'no-color', 'hide', 'g', 'timings', 'P'], 'General')
.group(['p', 'c', 'l', 't'], 'Prefix styling')
.group(['i', 'default-input-target'], 'Input handling')
.group(['k', 'kill-others-on-fail'], 'Killing other processes')
.group(['restart-tries', 'restart-after'], 'Restarting')
.epilogue(epilogue)
.argv;
.parseSync();

const names = (args.names || '').split(args['name-separator']);
// Get names of commands by the specified separator
const names = (args.names || '').split(args.nameSeparator);
// If "passthrough-arguments" is disabled, treat additional arguments as commands
const commands = args.passthroughArguments ? args._ : [...args._, ...argsAfterSep];

concurrently(args._.map((command, index) => ({
command: String(command),
name: names[index],
})), {
handleInput: args['handle-input'],
defaultInputTarget: args['default-input-target'],
killOthers: args.killOthers
? ['success', 'failure']
: (args.killOthersOnFail ? ['failure'] : []),
maxProcesses: args['max-processes'],
raw: args.raw,
hide: args.hide.split(','),
group: args.group,
prefix: args.prefix,
prefixColors: args['prefix-colors'].split(','),
prefixLength: args['prefix-length'],
restartDelay: args['restart-after'],
restartTries: args['restart-tries'],
successCondition: args.success,
timestampFormat: args['timestamp-format'],
timings: args.timings,
}).result.then(
concurrently(
commands.map((command, index) => ({
command: String(command),
name: names[index],
})),
{
handleInput: args.handleInput,
defaultInputTarget: args.defaultInputTarget,
killOthers: args.killOthers
? ['success', 'failure']
: (args.killOthersOnFail ? ['failure'] : []),
maxProcesses: args.maxProcesses,
raw: args.raw,
hide: args.hide.split(','),
group: args.group,
prefix: args.prefix,
prefixColors: args.prefixColors.split(','),
prefixLength: args.prefixLength,
restartDelay: args.restartAfter,
restartTries: args.restartTries,
successCondition: args.success,
timestampFormat: args.timestampFormat,
timings: args.timings,
additionalArguments: args.passthroughArguments ? argsAfterSep : undefined,
},
).result.then(
() => process.exit(0),
() => process.exit(1),
);
12 changes: 12 additions & 0 deletions bin/epilogue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ const examples = [
description: 'Exclude patterns so that between "lint:js" and "lint:fix:js", only "lint:js" is ran',
example: '$ $0 "npm:*(!fix)"',
},
{
description: 'Passthrough some additional arguments via \'{<number>}\' placeholder',
example: '$ $0 -P "echo {1}" -- foo',
},
{
description: 'Passthrough all additional arguments via \'{@}\' placeholder',
example: '$ $0 -P "npm:dev-* -- {@}" -- --watch --noEmit',
},
{
description: 'Passthrough all additional arguments combined via \'{*}\' placeholder',
example: '$ $0 -P "npm:dev-* -- {*}" -- --watch --noEmit',
},
];

export const epilogue = `
Expand Down
Loading

0 comments on commit 19f1f91

Please sign in to comment.