pkgjs / parseargs

Polyfill of `util.parseArgs()`
Apache License 2.0
123 stars 10 forks source link

`required` option #150

Open Semigradsky opened 1 year ago

Semigradsky commented 1 year ago

Currently, Node.js is checking that arg has the correct type (by the strict option). By I need manually check that this arg was provided by user. How about boolean flag required for this?

Before:

const { values } = parseArgs({
  options: {
    param: { type: 'string', short: 'p' },
  },
})

if (!values.param) {
  console.error('The "--param" param is required!')
  process.exit(1)
}

After:

const { values } = parseArgs({
  options: {
    param: { type: 'string', short: 'p', required: true },
  },
})
Eomm commented 1 year ago

I think we should define the following:


I would like to share this interesting discussion from the JSON Schema spec, that adopted the pattern:

const { values } = parseArgs({
  required: [ 'param' ]
  options: {
    param: { type: 'string', short: 'p' },
  },
})

https://github.com/json-schema-org/json-schema-spec/issues/846

bakkot commented 1 year ago

See some discussion at https://github.com/nodejs/node/issues/44564 / https://github.com/nodejs/node/pull/44565.

Personally I agree with the argument against doing this made in this comment.

shadowspawn commented 1 year ago

required functionality is a reasonable suggestion, but I personally don't think it is clean enough and compelling enough to add. --help and --version from the linked comment are good examples of complications.


Side note on potential naming confusion. The terms "required" and "optional" also get used to describe whether an option must have an option value. Given these three uses:

my-util
my-util --param
my-util --param VALUE

parseArgs does not currently allow the middle one (when strict) because type: 'string' means an option-value is required when the option is used. So I might think required: false would allow that case.

A possible name to reduce this confusion is requiredOption, for when the option must be supplied by the end user.

(Edit: for interest, yargs has demandOption and requiresArg.)


should a required: true, default: foo option be rejected?

That is simple to understand. I took a different approach when implementing required-option functionality myself, in case the author was using the default as simple support for environment variables. This does makes the behaviour of required-option more subtle, it means the option must have a value after parsing, rather than requiring it is specified on command-line.

  options: {
    password: { type: 'string', requiredOption: true, default: process.env.PASSWORD },
  },