-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Pass Command
instance to argParsers
#1968
Comments
There was a previous request to add an option|argument as well: #1207 The additions of |
Happy to see I'm not the only one who thought of this. The circumstances have changed, sure, and now the use cases for this are much narrower, but there certainly still are some, especially for developers of third party tools who cannot know what |
Shouldn't the |
Anonymous functions are so common for these sorts of functions that I treat them as a first class use case. (And tend to forget Could you achieve access to Command currently by adding parent command to option in |
They are also common for action handlers, but in my CLI tool based on Commander, I always preferred regular
Unlike commands,
Not sure what you mean here. If we store the |
I wanted to try this out. const { Command, Option } = require('commander');
class MyOption extends Option {
#owner;
setOwner(cmd) {
this.#owner = cmd;
}
argParser(fn) {
this.parseArg = (arg, previous) => {
return fn(arg, previous, this.#owner);
};
return this;
}
}
class MyCommand extends Command {
createCommand(name) {
return new MyCommand(name);
}
createOption(flags, description) {
const option = new MyOption(flags, description);
option.setOwner(this);
return option;
}
}
function myParseInspect(arg, previous, cmd) {
console.log(`Parsing arg: ${arg}`);
console.log(`Called parse for an option on ${cmd.name()}`);
}
const program = new MyCommand('myProgram')
.option('-v, --value <VALUE>', 'enter description', myParseInspect);
program.parse(); % node index.js -v XXX
Parsing arg: XXX
Called parse for an option on myProgram |
@shadowspawn this works, but only for implicitly constructed options added with Also, I don't really want to expose the
I ended up implementing this idea for now, take a look at aweebit/recommander if you are interested. The code is a bit involved, but you could just Ctrl+F Would still love this issue to be acted on, though. |
This issue has not had any activity in a couple of months. It isn't likely to get acted on due to this report. Feel free to open a new issue if it comes up again, with new information and renewed interest. Thank you for your contributions. |
Since #1915 has been closed, I have been working on a third-party library that would offer similar functionality by means of subclassing.
The most promising approach seems to be to overwrite the
.parseArg
property ofOption
andArgument
instances whenever it receives a new value, so something like this:However, there is one problem when it comes to catching errors in promise chains.
I would like to handle such errors in the same manner errors in synchronous argParsers are currently handled, and that involves calling the
.error()
method on theCommand
instance if the error turns out to be anInvalidArgumentError
. However, that is not possible because neitherOption
norArgument
instances have access to this method.That is why I suggest to extend the argParser signature by a third parameter whose value will always be the
Command
instance in which the argParser was called.Another reaason why that could come in handy in my scenario is because it would make it possible to only treat promises specially when
.parseAsync()
has been called, e.g. by reading the_asyncParsing
property just like in #1915.Regular users could also benefit from this change since it would enable them to write reusable argParsers with custom error messages (which they might want to do if they are not satisfied with the default ones for whatever reason). Or they could retrieve the version number via
.version()
and include it in the error message. Or they could even choose to call.help()
instead of.error()
. There is a lot that could be done.The text was updated successfully, but these errors were encountered: