command-line-args icon indicating copy to clipboard operation
command-line-args copied to clipboard

Support positional args

Open 75lb opened this issue 6 years ago • 5 comments

Support positional args, similar to what is available in argparse.

75lb avatar Jan 21 '19 20:01 75lb

I think they can be emulated via { name: 'defaults', defaultOption: true, multiple: true }, but then command-line-usage will print this option...

Ahh, with hide: 'defaults' complements it.

ghost avatar Jan 31 '19 18:01 ghost

That emulation technique is very clever! One drawback with it, however, is that it cannot coerce the arguments to different data types (which I realized after trying it).

tnunamak avatar May 28 '19 15:05 tnunamak

I'd also love to see this. I have a set of commands of the form

cmd1 <positional1> <positional2>
cmd2 <positional1>
<positional1> subcmd1 <positional2>
<positional1> subcmd2 <positional3> [flags]
<positional1> <positional2> <multiple-positionals..>

and command-line-args' stopAtFirstUnknown is very useful for dealing with the subcommands preceded by positionals (which e.g. yargs can't handle), but the lack of explicit support for positionals makes implementing commands that can take multiple positionals, e.g. cmd1 here, annoying. If possible I'd like to be able to do something like

if (mainCommand.command === "cmd1") {
    const cmd1 = commandLineArgs([
        { name: "positional1", defaultOption: true },
        { name: "positional2", defaultOption: true }
    ], { argv: mainCommand._unknown })
}

but this gives an error saying that only one option can be a defaultOption.

I'd rather not have to use multiple, since no error would be thrown if less or more than two positionals are supplied.

Myaamori avatar Sep 23 '19 22:09 Myaamori

Hi @Myaamori, positional args are planned for the next release. In the meantime, you can emulate positional args with code like this.

const commandLineArgs = require('command-line-args')

const optionDefinitions = [
  {
    name: 'positionals',
    multiple: true,
    defaultOption: true
  }
]

const options = commandLineArgs(optionDefinitions)
console.log(options)

/* validate positionals */
const validArgs = options.positionals
  && options.positionals.length === 2
  && options.positionals.every(p => p)

if (validArgs) {
  console.log('Valid args')
} else {
  throw new Error('Exactly two args are required.')
}

Example invocations:

$ node example.js image.jpg
{ positionals: [ 'image.jpg' ] }
/Users/lloyd/Documents/75lb/command-line-args/tmp/examples/positionals.js:22
  throw new Error('Exactly two args are required.')

$ node example.js image.jpg imgs
{ positionals: [ 'image.jpg', 'imgs' ] }
Valid args

75lb avatar Sep 24 '19 10:09 75lb

Using the above example, if using command-line-usage the positionals option would appear in your usage guide (as @ghost mentioned above). See here for instructions how to hide it.

75lb avatar Sep 24 '19 10:09 75lb