2

I have a cli script that accepts commandline parameters.
For the pages parameter I would like the behaviour to be:

> script.js

-> pages parameter not set. don't process pages

> script.js -p 100

-> pages parameter set with value 100: process 100 pages

> script.js -p

-> pages parameter set without value: process infinite (however much available) pages

In other words: I want to give an optional parameter a default value. The problem is that I can't figure out how to distinguish between the situation where it's set by the user without value and when it's not set.

When defined like this:

  var argv = require('yargs')
  // omitted code
  .alias('p', 'pages')
  .describe('p', 'number of pages; infinite by default')
  .default('p', -1)
  .number('p')

argv.pages is always -1 whether I set -p or not

And when defined like this:

  .alias('p', 'pages')
  .describe('p', 'number of pages; infinite by default')
  .number('p')

typeof argv.pages is always undefined, whether I set -p or not

How can I give a default value while treating the parameter as an optional argument; so, no default when it's not set and only a default when it's set without value.


(of course there is a workaround : I could manually parse the arguments by looping through process.argv, but I want to avoid that as that defeats the purpose of using yargs)

marty
  • 61
  • 1
  • 6
  • It seems as if it's not processing the command line arguments at all. Can you try with other options and see if that's the case? Also need to know the yargs version, and how you are calling the argument parser. (.argv, .parse, .parseSync) – karizma Jun 29 '21 at 15:10
  • I was describing the situation where I leave the command-line values empty (so, "no -p" parameter vs "-p without value". If I add a value ("-p 100") then that is picked up. So it's definitely picking up the command line argument – marty Jun 30 '21 at 17:06

1 Answers1

2

I don't believe yargs has a method for something like this, I thought of using #coerce(), but that function gets called regardless if the command line has -p or not, so it wouldn't work (unless you checked for '-p' and '--pages' in the process.argv).

One solution would be to remove the default and modify it after yargs is done. If you remove the default and specify -p, in argv it will just be undefined. If you don't specify -p at all it won't be a property at all.

script -p 100 // => { _: [], $: "", pages: 100, p: 100 }
script -p // => { _: [], $: "" pages: undefined, p: undefined }
script // => { _: [], $: "" }

Now we can check if pages exists in the object but is undefined, and then do whatever:

var argv = require('yargs')
    // omitted code
    .alias('p', 'pages')
    .describe('p', 'number of pages; infinite by default')
    .number('p').argv;

if ('pages' in argv && typeof argv.pages === 'undefined') {
    // set to whatever you want
    argv.pages = Infinity;
    argv.p = Infinity;
}

console.log(argv);
karizma
  • 284
  • 2
  • 11