0

I'm trying to pass 2 mandatory arguments for a Node.js program I'm creating.

I'm using Yargs to do it like this:

const yarg = require("yargs")
.usage("hi")
.options("m", {demandOption: true})
.options("m2", {demandOption: true})
.argv;

This works fine with a slight issue. I want to activate the script like this:

node index.js -m val -m2 val2

It doesn't work and I get an error saying m2 is missing. Only when I add another - before m2 it works, meaning I have to do it like this:

node index.js -m val1 --m2 val2

Is there a way to make it accept the args like I wanted to in the first place?

CodeMonkey
  • 11,196
  • 30
  • 112
  • 203
  • You can have it how you wanted in the first place if you dont use yargs - process command line arguments by yourself. –  Jan 29 '19 at 15:46

1 Answers1

1

You can't do what you're asking for with yargs, and arguably you shouldn't. It's easy to see why you can't by looking at what yargs-parser (the module yargs uses to parse your arguments) returns for the different argument styles you mentioned:

console.log(yargsParser(['-m', 'A']));
console.log(yargsParser(['-m2', 'B']));
console.log(yargsParser(['--m2', 'C']));
<script src="https://bundle.run/yargs-parser@11.1.1"></script>

As you can see:

  1. -m A is parsed as option m with value A.
  2. -m2 B is parsed as option m with value 2 and, separately, array parameter B.
  3. --m2 C is parsed as option m2 with value C.

There is not a way to make the parser behave differently. This is with good reason: Most command line tools (Windows notwithstanding) behave this way.

By decades-old convention, "long" options use two dashes followed by a human-readable name, like --max-count. "Short" options, which are often aliases for long ones, use a single dash followed by a single character, like -m, and—this is the crucial bit—if the option takes a value, the space between the option and the value can be omitted. This is why when yargs sees -m2, it assumes 2 is the value for the m option.

If you want to use yargs (and not confuse command line-savvy users) you'll you need to change your options to either 1. --m and --m2 or, 2. -m and (for example) -n.

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
  • 1) is there a possibility to make the parser not omit the space between the name and value? 2) How can I make the user put 2 dashes before the first parameter? I just defined m and it takes a single dash automatically... – CodeMonkey Jan 14 '19 at 08:32
  • This might be helpful for you https://unix.stackexchange.com/questions/21852/single-dashes-for-single-character-options-but-double-dashes-for-words –  Jan 17 '19 at 01:58
  • @Jordan Running so do you have an answer? – CodeMonkey Jan 20 '19 at 12:57