tj / commander.js

node.js command-line interfaces made easy
MIT License
26.64k stars 1.69k forks source link

[Feature request] More than 2 flags per option / case-insensitive flags #2222

Closed KaKi87 closed 1 month ago

KaKi87 commented 3 months ago

Hi,

I'm trying to add a -f, -F, --foo option, but when doing so, the first two flags are passed as options.F and the last one is ignored.

So, it seems that option() only supports up to 2 flags.

Therefore, I would like to request being able to either specify any number of flags, or optionally mark flags as case-insensitive.

Thanks

shadowspawn commented 3 months ago

Having more than 1 short and 1 long flag does come up very occasionally: #1862

This is not something I want to add to Commander.

For an extra flag, you could perhaps add a hidden option which sets the "real" option value when used.

For case insensitive, you could perhaps subclass the Option class to change how options are matched

import { Command, Option } from 'commander';

class MyOption extends Option {
  is(arg) {
    return this.short?.toLowerCase() === arg.toLowerCase() || this.long === arg;
  }
}

class MyCommand extends Command {
  createOption(flags, description) {
    return new MyOption(flags, description);
  }
  createCommand(name) {
    return new MyCommand(name);
  }
}

const program = new MyCommand();
program.option('-f, --foo', 'enable some foo');
program.parse();

console.log(program.opts());
% node index.mjs -f
{ foo: true }
% node index.mjs -F
{ foo: true }
KaKi87 commented 3 months ago

This is not something I want to add to Commander.

Why not ?

For an extra flag, you could perhaps add a hidden option

Okay, for anyone else interested, here's a workaround :

.option('-f, -F, --foo')
.addOption(new Option('--foo').hideHelp())
.action(options => {
    if(options.F || options.foo){}
});

That said, I would argue that if option() only handles 2 flags, then it should treat this as invalid, even though it means ruining this :sweat_smile:

For an extra flag, you could perhaps add a hidden option

So you wouldn't want to implement case insensitivity either ? If no, why ?

Thanks.

cc. @mitsukuri

shadowspawn commented 3 months ago

Why not?

Basically, I don't think it is useful enough or commonly used enough to add to Commander.

I leave enhancement requests open for six months to see if they get upvotes or further comments. So there is a chance for other people to show interest with upvotes or comments, and make a case for the feature.

Why do you think it should be added?

shadowspawn commented 3 months ago

For an extra flag, you could perhaps add a hidden option

I had this approach in mind.

const fooOption = new Option('-f, --foo', 'enable some foo');
const extraFooFlag = new Option('-F').hideHelp();
fooOption.flags = '-f, -F, --foo'; // to show extra flag in help and error messages
program
   .addOption(fooOption)
   .addOption(extraFooFlag)
   .on('option:F', () => program.setOptionValue('foo', true));

.option('-f, -F, --foo')
.addOption(new Option('--foo').hideHelp())

That said, I would argue that if option() only handles 2 flags, then it should treat this as invalid, even though it means ruining this 😅

Yes, I have been thinking about adding an error for unsupported flags! 😬 Related, another unsupported form: #2211

shadowspawn commented 1 month ago

An answer was provided, and no further activity in a month.

I have opened an issue to make more than 2 flags an error: #2235

Feel free to open a new issue if it comes up again, with new information and renewed interest.