48

As an example, double dash or two hyphens -- is used like so:

npm test -- --coverage

Running npm without the double dash flag does not run in coverage mode so it seems to append subsequent flags, is this correct? I couldn't find the documentation on this.

Kunal
  • 1,125
  • 2
  • 11
  • 18

2 Answers2

77

-- as an argument on its own is standardized across all UNIX commands: It means that further arguments should be treated as positional arguments, not options. See Guideline 10 in POSIX Utility Syntax Conventions.

To give you a non-NPM-based example, ls -- -l will look for a file named -l, because the -- specified that all subsequent arguments are positional.

In this context, it means that --coverage isn't an option to npm itself; presumably, then, it's subsequently read by the test subcommand. For a tool that were following the conventions properly this wouldn't be necessary, because Guideline 9 specifies that all options shall be given before any arguments (thus that in this context --coverage should be treated as an argument since it comes after the argument test); however, inasmuch as NPM is only partially following the guidelines, this is a foreseeable result.

(Long --option-style options are actually a GNU extension as a whole, so what we have here is a mismash of multiple parsing styles; such is life, unfortunately).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • You mentioned that because `test` is argument, anything after it should also be arguments according to the guideline. I wonder that how does `npm` or `bash`, if I am wrong, know `test` is not an option? Match the string `test` with any expected options of the command? – krave Mar 08 '22 at 12:38
  • @krave, read the link. If something doesn't start with a dash, it's not an option. (Also, bash doesn't _need_ to know what's an option or an argument to any external command -- it's the command's problem to parse the argument vector into options and arguments; the shell's job ends after it's created the vector). – Charles Duffy Mar 08 '22 at 13:33
  • @krave, ...btw, one of the interesting results one gets from following the rules strictly is that in POSIX-compliant uses of `find` (where one or more path used to start the search from is mandatory), things like `-name` are positional arguments, not options. That's part of why find takes "primaries" and "operands", not options. – Charles Duffy Mar 08 '22 at 13:38
1

I've done some further digging; according to the docs for my node version -

"--" Indicates the end of node options. Pass the rest of the arguments to the script. If no script filename or eval/print script is supplied prior to this, then the next argument will be used as a script filename.

But, a simple script that contains -

console.log(`process.execArgv:${process.execArgv}`);
console.log(`process.argv:${process.argv}`);

behaves as -

>node --prof argv.js --myArg
process.execArgv:--prof
process.argv:C:\Program Files\nodejs\node.exe,C:\Dev\Web\QA_Web_POC\argv.js,--myArg

>node --prof argv.js -- --myArg
process.execArgv:--prof
process.argv:C:\Program Files\nodejs\node.exe,C:\Dev\Web\QA_Web_POC\argv.js,--, --myArg

>node argv.js --prof -- --myArg
process.execArgv:
process.argv:C:\Program Files\nodejs\node.exe,C:\Dev\Web\QA_Web_POC\argv.js,--prof,--,--myArg

>node argv.js -- --prof --myArg
process.execArgv:
process.argv:C:\Program Files\nodejs\node.exe,C:\Dev\Web\QA_Web_POC\argv.js,--,--prof,--myArg

So, it seems there's a bug?

martinp999
  • 419
  • 6
  • 10