yargs / yargs

yargs the modern, pirate-themed successor to optimist.
https://yargs.js.org/
MIT License
11k stars 996 forks source link

`halt-at-non-option` is not working as expected. #2423

Open sergei-dyshel opened 1 week ago

sergei-dyshel commented 1 week ago

I'm trying to write a CLI similar to ssh. Here's the minimal example:

import yargs from "yargs";

function main() {
  yargs(process.argv.slice(2))
    .usage(
      "$0 <host> [<cmd>...]",
      "Run command via ssh",
      (yargs) =>
        yargs
          .positional("host", { type: "string", demandOption: true })
          .positional("cmd", { array: true, type: "string" })
          .options({
            verbose: { type: "boolean", alias: "v", count: true },
          }),
      (args) => {
        console.log(args);
      },
    )
    .strict()
    .parserConfiguration({
      "halt-at-non-option": true,
    })
    .parseSync();
}

main()

which just adds one option. When parsing node my-script.js my-host ls, I get this error:

Not enough non-option arguments: got 0, need at least 1

The only way I manage to get this work is with default command syntax:

  const args = yargs(process.argv.slice(2))
    .usage("$0 <host> [<cmd>...]")
    .options({
      verbose: { type: "boolean", alias: "v", count: true },
      zone: { type: "string", alias: "z", describe: "Availability Zone" },
    })
    .strict()
    .parserConfiguration({
      "halt-at-non-option": true,
    })
    .parse();

though in this case positional arguments are not supported so I can't mix <host> with option flags but at least I can extract it as first element of args._

shadowspawn commented 1 week ago

I reproduced the problem.

Deep in the code... At the point the error is being thrown, the arguments are in arg.-- instead of argv._. I can see code "counting" the positionals with and without taking -- into account. I suspect need the first case to include -- length like in the second case.

https://github.com/yargs/yargs/blob/0c95f9c79e1810cf9c8964fbf7d139009412f7e7/lib/command.ts#L511

https://github.com/yargs/yargs/blob/0c95f9c79e1810cf9c8964fbf7d139009412f7e7/lib/validation.ts#L32

(I don't currently understand why halt-at-non-option triggers the failure.)