nemec / clipr

Command Line Interface ParseR for .Net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Partial / Sub-Parser

3nth opened this issue · comments

I'd like to build a command line application where all the arguments aren't necessarily known by the main parser. The idea being to allow for extensions which may define their own arguments. Something akin to argparse's subparser functionality.

One approach would be a parser option to ignore unknown arguments. Parse everything per usual, but when the destination object doesn't have an argument defined just ignore it instead of throwing an error. Then I just pass args to the extension and it can do the same to pull it's own arguments.

commented

By subparser you mean things like svn checkout rather than having an extension define a new -p on the existing command, correct? If so, that's accomplished by using Verbs. Each Verb is what argparse calls a subparser.

Of course, the issue now is that with Attribute configuration you need to know which verbs are available at compile time (since they're properties on the main object). For something configurable at runtime you may want to try out the Fluent Config, which would allow you to do some reflection and add HasVerb()s in a loop. Keep in mind, though, that the API is still very much in alpha -- at least as far as ease-of-use goes. Functionality-wise, it has most if not all of the same features as the Attribute config.

I looked into verbs, but not quite what I need. Wouldn't necessarily know anything about the options.

The plugins aren't subcommands/verbs, but rather input/output handlers. So general command is run.exe IN OUT --input-option --output-option. The main program handles the positional arguments, figures out what handlers to load, then hands off to the handlers which would have their own options.

I've forked and made a few changes which implement what I was thinking. Can submit pull request if you want to look/discuss/consider. Tests passed and it's doing what I need it to do. I've hardly spent enough time understanding clipr in depth to think it through.

I ❤️ what I've seen so far, argparse is a great parser.

commented

Thanks for the pull request, I think I understand what you're trying to do. Will any of your handlers contain named arguments with values (like --input-option=VALUE)?

If so, you could possibly run into this scenario:

run.exe --input-option VALUE IN OUT

Because you only have two positional args, they'll be VALUE and IN because the --input-option arg was ignored and its value was matched to the first positional arg. Since that behavior may be kind of confusing, I'm not sure I want to merge the request as-is.

Do you only need the scenario where the handlers consume short/long named arguments with no additional values (positional would not be ignored)? Right now there's a bit of a hidden feature called "triggers" that act as value-less named arguments that execute code rather than parse anything. At the moment they're only used to trigger the Help and Version displays and although they're only able to specify explicit keywords to trigger on, I could add something like an UnknownArgumentTrigger that would handle all unmatched argument keywords. You could subclass it and change the behavior to "ignore". Something like:

public class NopTrigger : UnknownArgumentTrigger
{
    public bool OnUnknownArgument(string longName)
    {
        return true;  // Mark as handled, do nothing.
    }
}

Thoughts?

Doh! Some do and then the ordering matters as you point out. Definitely not ideal.

It is possible to discover all options during startup. Then somehow composite the options for a single parse. Or hand multiple options classes into parse.

Will put some more thought into this and evaluate using triggers.

Was re-reading doc and noticed the Dictionary Backend. Using that I'm able to configure all possible options for all handlers at startup.

commented

I'm glad the Dictionary backend works for you. Are you having any other issues with integrating your subparsers into clipr?