Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pass arguments support #282

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Expand Up @@ -175,6 +175,18 @@ Restarting
--restart-after Delay time to respawn the process, in milliseconds.
[number] [default: 0]

shorten command
-P, --prepend prepend string to each command
but make sure you not using dash, else use
`-D prepend="foobar"` [string] [default: ""]
-A, --append append string to each command
eg: pass arguments
but make sure you not using dash, else use
`-D append="foobar"` [string] [default: ""]
-D, --define add definition to render
template `{{prepend}} <command> {{append}}`
[string] [default: []]

Options:
-h, --help Show help [boolean]
-v, -V, --version Show version number [boolean]
Expand All @@ -193,6 +205,19 @@ Examples:

$ concurrently --prefix "{time}-{pid}" "npm run watch" "http-server"

- Custom cmd prepend

$ concurrently -P 'npm run' 'example:echo:A' 'example:echo:B'

$ concurrently -D prepend='npm run' 'example:echo:A' 'example:echo:B'

- Custom cmd append

$ concurrently -A ' -- --watch' 'npm:example:echo*'
# Add one space to prevent yargs parse this string as an option

$ concurrently -D append='-- --watch' 'npm:example:echo*'

- Custom names and colored prefixes

$ concurrently --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold"
Expand Down
53 changes: 53 additions & 0 deletions bin/concurrently.js
Expand Up @@ -133,26 +133,79 @@ const args = yargs
'Identifier for child process to which input on stdin ' +
'should be sent if not specified at start of input.\n' +
'Can be either the index or the name of the process.'
},

// shorten command
'P': {
alias: 'prepend',
describe:
'prepend string to each command\n' +
'but make sure you not using dash, else use \n' +
'`-D prepend="foobar"`',
default: '',
type: 'string'
},
'A': {
alias: 'append',
describe:
'append string to each command\n' +
'eg: pass arguments\n' +
'but make sure you not using dash, else use \n' +
'`-D append="foobar"`',
default: '',
type: 'string'
},

// force to use `-D A=B` style
// to prevent yargs mis-parsed dash, eg: `--append --watch`
'D': {
alias: 'define',
describe:
'add definition to render \n' +
'template `{{prepend}} <command> {{append}}`',
default: [],
type: 'string'
}
})
.group(['m', 'n', 'name-separator', 'raw', 's', 'no-color'], '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')
.group(['P', 'A', 'D'], 'shorten command')
// Too much text to write as JS strings, .txt file is better
.epilogue(fs.readFileSync(__dirname + '/epilogue.txt', { encoding: 'utf8' }))
.argv;

const prefixColors = args.prefixColors.split(',');
const names = (args.names || '').split(args.nameSeparator);

const _ObjectFromEntries = (l) => {
const d = {};
l.forEach(el=>d[el[0]] = el[1]);
return d;
};
const _define = Array.isArray(args.define) ? args.define : [args.define];
const definition = Object.assign(
{},
{ prepend: args.prepend, append: args.append },
// desc: convert ["a=1","b=2"] into {"a":"1","b":"2"}
_ObjectFromEntries(
_define
.map(el=>el.split('='))
.map(x=>[x[0],x.slice(1).join('=')])
)
);

let lastColor;
concurrently(args._.map((command, index) => {
// Use documented behaviour of repeating last colour when specifying more commands than colours
lastColor = prefixColors[index] || lastColor;
return {
command,
argPend: {
definition
},
prefixColor: lastColor,
name: names[index]
};
Expand Down
13 changes: 13 additions & 0 deletions bin/epilogue.txt
Expand Up @@ -12,6 +12,19 @@ Examples:

$ $0 --prefix "{time}-{pid}" "npm run watch" "http-server"

- Custom cmd prepend

$ $0 -P 'npm run' 'example:echo:A' 'example:echo:B'

$ $0 -D prepend='npm run' 'example:echo:A' 'example:echo:B'

- Custom cmd append

$ $0 -A ' -- --watch' 'npm:example:echo*'
# Add one space to prevent yargs parse this string as an option

$ $0 -D append='-- --watch' 'npm:example:echo*'

- Custom names and colored prefixes

$ $0 --names "HTTP,WATCH" -c "bgBlue.bold,bgMagenta.bold" "http-server" "npm run watch"
Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -10,6 +10,8 @@
"node": ">=10.0.0"
},
"scripts": {
"example:echo:A": "echo A",
"example:echo:B": "echo B",
"lint": "eslint . --ignore-path .gitignore",
"report-coverage": "cat coverage/lcov.info | coveralls",
"test": "jest"
Expand Down
18 changes: 18 additions & 0 deletions src/command-parser/zz-expand-arguments.js
@@ -0,0 +1,18 @@
module.exports = class StripQuotes {
parse(commandInfo) {
let { command } = commandInfo;
const { argPend } = commandInfo;
if (!argPend || !argPend.definition) {
return commandInfo;
}

const argPrepend = argPend.definition.prepend ? (argPend.definition.prepend + ' ') : '';
const argAppend = argPend.definition.append ? (' ' + argPend.definition.append) : '';
if (argPrepend === '' && argAppend === '') {
return commandInfo;
}

command = argPrepend + command + argAppend;
return Object.assign({}, commandInfo, { command });
}
};
46 changes: 46 additions & 0 deletions src/command-parser/zz-expand-arguments.spec.js
@@ -0,0 +1,46 @@
const ZZ_ExpandArguments = require('./zz-expand-arguments');
const parser = new ZZ_ExpandArguments();

it('noop if no argPend', () => {
const commandInfo = {
command: 'foo bar'
};
expect(parser.parse(commandInfo).command)
.toEqual('foo bar');
});

it('noop if empty argPend', () => {
const commandInfo = {
command: 'foo bar',
argPend: { definition: {} }
};
expect(parser.parse(commandInfo).command)
.toEqual('foo bar');
});

it('argPend prepend', () => {
const commandInfo = {
command: 'foo bar',
argPend: { definition: { prepend: 'echo' } },
};
expect(parser.parse(commandInfo).command)
.toEqual('echo foo bar');
});

it('argPend append', () => {
const commandInfo = {
command: 'foo bar',
argPend: { definition: { append: '--watch' } },
};
expect(parser.parse(commandInfo).command)
.toEqual('foo bar --watch');
});

it('argPend prepend + append', () => {
const commandInfo = {
command: 'foo bar',
argPend: { definition: { prepend: 'echo', append: '--watch' } },
};
expect(parser.parse(commandInfo).command)
.toEqual('echo foo bar --watch');
});
5 changes: 4 additions & 1 deletion src/concurrently.js
Expand Up @@ -6,6 +6,7 @@ const treeKill = require('tree-kill');
const StripQuotes = require('./command-parser/strip-quotes');
const ExpandNpmShortcut = require('./command-parser/expand-npm-shortcut');
const ExpandNpmWildcard = require('./command-parser/expand-npm-wildcard');
const ZZ_ExpandArguments = require('./command-parser/zz-expand-arguments');

const CompletionListener = require('./completion-listener');

Expand All @@ -29,7 +30,8 @@ module.exports = (commands, options) => {
const commandParsers = [
new StripQuotes(),
new ExpandNpmShortcut(),
new ExpandNpmWildcard()
new ExpandNpmWildcard(),
new ZZ_ExpandArguments(),
];

commands = _(commands)
Expand Down Expand Up @@ -66,6 +68,7 @@ module.exports = (commands, options) => {
function mapToCommandInfo(command) {
return {
command: command.command || command,
argPend: command.argPend,
name: command.name || '',
prefixColor: command.prefixColor || '',
env: command.env || {},
Expand Down