Skip to content
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

Option to allow unknown arguments #493

Closed
danpalmer opened this issue Sep 19, 2022 · 2 comments
Closed

Option to allow unknown arguments #493

danpalmer opened this issue Sep 19, 2022 · 2 comments

Comments

@danpalmer
Copy link

I've had a look for this in the docs and code and not found anything. If this is already support, apologies, let me know what I should be searching for. I'm happy to contribute more docs for it to make it less likely that others come asking in the future.

I'd like to be able to ignore unknown arguments. For example, given the following definition, I'd like to be able to run cmd --bar and have it work, ignoring the --bar.

struct Example: ParsableCommand {
    @Option var foo: Bool
}

Design options

How is this behaviour enabled? I strongly feel it shouldn't be the default as it's somewhat dangerous and minimises the benefits of swift-argument-parser.

CommandConfiguration

The simplest option feels like a boolean property on CommandConfiguration, likely passed to the constructor, with a name like ignoreUnknownArguments or ignoreUndefinedArguments (is "unknown" or "undefined" the better terminology to use for this feature?).

@UnknownArguments

Another option, perhaps more flexible, is to define a new decorator that can be applied like this:

@UnknownArguments var unknown: [String]

The behaviour of this would be to collect anything that swift-argument-parser would otherwise consider unknown, nullifying the validation that there are no known arguments, but also giving the developer the chance to act on them with their own logic.

A further version of this would be @UnknownArguments(requireAllow: true) (with some better naming). The behaviour of this would be to allow unknown arguments, but only if acknowledged and allowed by another argument, for example...

cmd --foo --allow-unknown=--foo

In the above case, if --foo parses successfully, everything works as normal. However if it doesn't it's added to the list of unknown arguments and no validation error is raised. Any arguments that are unknown but not given with --allow-unknown would cause validation errors as normal.

I expect that the --allow-unknown argument would itself be validated as normal, as if it had been manually created by the developer, i.e. if there is no @UnknownArguments it would raise a validation error.

Why?

There are 2 primary use-cases for this that I can see:

  1. Writing binaries for environments not under your control. Perhaps the binary is going to be run with options/arguments that you are not in control of, but you don't care about what they are. Using swift-argument-parser is still useful, but writing effectively a schema for things you don't care about that will be validated makes the code more brittle.
  2. Progressive rollouts of arguments. It's common in server environments to use arguments to control the behaviour of a server. Being able to add the supporting code and the arguments separately from each other makes deployments more flexible.

Again, apologies if this is available, I haven't been able to find it. I expect that one could implement all of this on top of swift-argument-parser's infrastructure, but it would likely be more manual, less elegant, and may sacrifice more validation to work fully.

I'm happy to provide more detail on the above ideas for implementation, or on the use-cases. My preferred option would be the second one as I think it's more flexible, and I've got experience using systems with the --allow-unknown sort of flag and the ergonomics are nice to have.

@kinoroy
Copy link

kinoroy commented Oct 7, 2022

Looks like this functionality was just merged to master: #496 🎉

@danpalmer
Copy link
Author

Oh wow, this is great. Thanks for letting me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants