open-cli-tools / open-cli-tools/concurrently
escaping pass-through arguments is too eager
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.9k
- Forks
- 281
- Avg merge
- 17h 12m
- Merged PRs (30d)
- 1
Description
Background
When trying to use concurrently with --passthrough-arguments option, any passed arguments get escaped too eagerly.
The issue has been observed while developing an application when trying to concurrently run a local web server and gherkin-testcafe for testing with the latter requring tags to start with @ character.
Since that application can't be shared here for legal reasons I've tried a simpler scenario which is reproducing the issue, too.
Scenario
- windows platform
- npm 10.5.2
- node 20.13.1
- concurrently 8.2.2
- files:
- package.json contains scripts:
{"scripts": { "foo": "concurrently -k -n \"bar,baz\" -P npm:foo:bar \"npm:foo:baz -- {@}\"", "foo:bar": "node block.js", "foo:baz": "node log.js", }} - file block.js looks like this:
setTimeout(() => console.log("delayed"), 1000); - file log.js looks like this:
console.dir(process.argv);
- package.json contains scripts:
Test
invoke without arguments
$ npm run foo
> logistics-client@0.0.0 foo
> concurrently -k -n "bar,baz" -P npm:foo:bar "npm:foo:baz -- {@}"
[bar]
[bar] > logistics-client@0.0.0 foo:bar
[bar] > node block.js
[bar]
[baz]
[baz] > logistics-client@0.0.0 foo:baz
[baz] > node log.js
[baz]
[baz] [
[baz] 'C:\\Program Files\\nodejs\\node.exe',
[baz] 'C:\\Users\\cepharum\\PhpstormProjects\\UID\\Logistics\\WebClient\\Source\\UiNew\\log.js'
[baz] ]
[baz] npm run foo:baz -- exited with code 0
--> Sending SIGTERM to other processes..
[bar] npm run foo:bar exited with code 1
looks good ... setup is working as expected
invoke with arguments to pass
$ npm run foo -- -- --tags=@foo
> logistics-client@0.0.0 foo
> concurrently -k -n "bar,baz" -P npm:foo:bar "npm:foo:baz -- {@}" -- --tags=@foo
[bar]
[bar] > logistics-client@0.0.0 foo:bar
[bar] > node block.js
[bar]
[baz]
[baz] > logistics-client@0.0.0 foo:baz
[baz] > node log.js --tags\=\@foo
[baz]
[baz] [
[baz] 'C:\\Program Files\\nodejs\\node.exe',
[baz] 'C:\\Users\\cepharum\\PhpstormProjects\\UID\\Logistics\\WebClient\\Source\\UiNew\\log.js',
[baz] '--tags\\=\\@foo'
[baz] ]
[baz] npm run foo:baz -- --tags\=\@foo exited with code 0
--> Sending SIGTERM to other processes..
[bar] npm run foo:bar exited with code 1
Problem here:
- the assignment operator gets escaped
- the
@gets escaped
Escaping seems to be eligible due to cmd.exe being involved. But eventually that escaping is found in invoked sub-process, too. Trying to fix it in that sub-process is not an option for it is a third-party application (gherkin-testcafe).
gherkin-testcafe illustrates the provision of tags without assignment operator, so I tried that one, too:
$ npm run foo -- -- --tags @foo
> logistics-client@0.0.0 foo
> concurrently -k -n "bar,baz" -P npm:foo:bar "npm:foo:baz -- {@}" -- --tags @foo
[baz]
[baz] > logistics-client@0.0.0 foo:baz
[baz] > node log.js --tags \@foo
[baz]
[bar]
[bar] > logistics-client@0.0.0 foo:bar
[bar] > node block.js
[bar]
[baz] [
[baz] 'C:\\Program Files\\nodejs\\node.exe',
[baz] 'C:\\Users\\cepharum\\PhpstormProjects\\UID\\Logistics\\WebClient\\Source\\UiNew\\log.js',
[baz] '--tags',
[baz] '\\@foo'
[baz] ]
[baz] npm run foo:baz -- --tags \@foo exited with code 0
--> Sending SIGTERM to other processes..
[bar] npm run foo:bar exited with code 1
The @ character still ends up escaped.
I've also tried using {*} on invoking concurrently. So, the script in package.json is now:
"foo": "concurrently -k -n \"bar,baz\" -P npm:foo:bar \"npm:foo:baz -- {*}\"",
Invoking as before prevents the escaping, but yields a different issue:
$ npm run foo -- -- --tags @foo
> logistics-client@0.0.0 foo
> concurrently -k -n "bar,baz" -P npm:foo:bar "npm:foo:baz -- {*}" -- --tags @foo
[baz]
[baz] > logistics-client@0.0.0 foo:baz
[baz] > node log.js '--tags @foo'
[baz]
[bar]
[bar] > logistics-client@0.0.0 foo:bar
[bar] > node block.js
[bar]
[baz] [
[baz] 'C:\\Program Files\\nodejs\\node.exe',
[baz] 'C:\\Users\\cepharum\\PhpstormProjects\\UID\\Logistics\\WebClient\\Source\\UiNew\\log.js',
[baz] "'--tags",
[baz] "@foo'"
[baz] ]
[baz] npm run foo:baz -- '--tags @foo' exited with code 0
--> Sending SIGTERM to other processes..
[bar] npm run foo:bar exited with code 1
So, the {*} seems to wrap all additional arguments in a single pair quotes. This may be intentional, but it definitely doesn't help here:
$ npm run foo -- -- --tags @foo --debug-on-fail
> logistics-client@0.0.0 foo
> concurrently -k -n "bar,baz" -P npm:foo:bar "npm:foo:baz -- {*}" -- --tags @foo --debug-on-fail
[baz]
[baz] > logistics-client@0.0.0 foo:baz
[baz] > node log.js '--tags @foo --debug-on-fail'
[baz]
[bar]
[bar] > logistics-client@0.0.0 foo:bar
[bar] > node block.js
[bar]
[baz] [
[baz] 'C:\\Program Files\\nodejs\\node.exe',
[baz] 'C:\\Users\\cepharum\\PhpstormProjects\\UID\\Logistics\\WebClient\\Source\\UiNew\\log.js',
[baz] "'--tags",
[baz] '@foo',
[baz] "--debug-on-fail'"
[baz] ]
[baz] npm run foo:baz -- '--tags @foo --debug-on-fail' exited with code 0
--> Sending SIGTERM to other processes..
[bar] npm run foo:bar exited with code 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the Windows reproduction from the package.json scripts using block.js and log.js, first comparing --passthrough-arguments with {*} and inspecting the resulting process.argv output. Trace the argument handling for the concurrently CLI entry point; done means pass-through arguments reach the child process without unwanted escaping or grouping.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100