Skip to content

Positional variadic options that may contain dashes #1821

@gabegorelick

Description

@gabegorelick

I want to implement an interface that collects all options after a positional option. The options are not known ahead of time.

Usage would look something like:

script.js --scriptOption script2 positionalArgToScript2 --optionForScript2

If a real life example helps, this is similar to how docker run works:

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

allowing you to run something like this:

docker run --rm alpine echo -n hi

Crucially, in this example, -n hi is passed to echo and is not treated as an option to docker run.

Here's how you might try to do that in yargs:

const yargs = require('yargs');
const { hideBin } = require('yargs/helpers');

const argv = yargs(hideBin(process.argv))
    .command('$0 <cmd> [args...]')
    .argv;

But when run like so

test.js echo -n hi there

argv ends up as

{ _: [],
  n: 'hi',
  '$0': 'test.js',
  cmd: 'echo',
  args: [ 'there' ] }

Notice how args is [ 'there' ] instead of [ '-n', 'hi', 'there' ].

Workarounds

Force callers to put -- after your options. If you only had a default command, then you could just drop it:

yargs(hideBin(process.argv))
    // .command('$0 <cmd> [args...]')
    .argv;

Then you'd call your script with test.js -- echo -n hi there and get the args from _.

See yargs/yargs-parser#145 for a related discussion around quoting arguments containing dashes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions