-
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
Args (an alternative to Flags) #1074
Comments
I think this idea will need a few iterations - but it's off to a good start! I think we should really consider something like this 👍 |
Hey, I think this is a good idea, a few thoughts from my side:
|
Having done some more preliminary investigation by doing a mock implementation I have found the following to be necessary:
|
I'm marking this as |
Nice proposal! Wouldn't naming the interface Also, wouldn't it be possible to implement type ArgumentGroup interface {
Name() string
Min() uint
Max() uint
} And as a bonus we wouldn't have to deal with the corner-case of Implementing something like app := &cli.App{
Name: "cp",
Arguments: []cli.ArgumentGroup{
cli.StringArguments{
Name: "paths",
Min: 2,
},
},
} (assuming But I wonder a bit what the main use-case for multiple argument groups would be. app := &cli.App{
Name: "cmd",
Arguments: []cli.ArgumentGroup{
cli.OptionalStringArgument{
Name: "foo",
},
cli.OptionalStringArgument{
Name: "bar",
},
},
} Where But OTOH, the same could be accomplished with a single argument group and simple slice logic. I'm not sure the increase in complexity is worth it, just to get a more comfortable access pattern for the individual arguments. 🤔 |
We could also allow for some sort of regular expression based system where the |
Current idea formulation:Arguments have at least the following:
Using this idea:Arguments will be provided in some manner. The ordering doesn't matter at all as all arguments will be "placed" (like flags but I think it should be required). With the arguments, a "placement string" must also be supplied. The syntax is a subset of full regular expressions.
The following is then done in order:
Example:
|
This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else. |
I'm still super interested in seeing this happen ^^ |
This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant. |
I would really like to see this too |
This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else. |
Closing this as it has become stale. |
👀 |
This issue or PR has been bumped and is no longer marked as stale! Feel free to bump it again in the future, if it's still relevant. |
As far as I remember, we would love to see this but it needs more design work 🙏🏼 |
This is a good feature to have. Theoretically this feature could be implemented in the Before function of the command with a standard set of validators, regex and filepath validator, so if the command is expecting arguments like [param1] [param2] [file1] .... It should work just fine. This along with a ExpectedMinNumArgs field in the command would solve the majority of the use cases for most people. |
Here's my design take on full end to end flow of new Args feature
|
My understanding is that we would still love to see this happen, we just need someone to volunteer to take on the work of designing and building that feature 🙏🏼 |
As I mentioned in #1237,I have implement this feature at repo cmdline,but it's a breeak implemention by extends from standard package flag. I'm trying to start this work base on cli v2 at this branch. |
Are there any updates on the progress of this feature? We eagerly await its arrival! |
It took 3 and a half years to implement the feature and it's still isn't finished or seems to be close to it. I don't know what the design of universal interface is but I think I know how to find the solution. Not sure whether it deserves own issue so I will post it here. SolutionThe solution is to turn the urfave/cli into nested arg parser and to let users bring their own parsers. MotivationThe problem is that there is too much cases of how to implement arguments parsing because developers always can find new better way how to help user solve their problems. For example some of the programs which have non-trivial logic: # [ - uses args as a language expression to return true or false
[ "a" == "b" ]
# expr - use args as a math formula to return result of calculation
expr 1 + 2
# bash uses separator to split own arguments from arguments of running script
bash -c 'echo $1' -- Hello! This means that the solution development could be very long and probably unsuccessful. There is too much unknown options. DesignI think it reasonable to let users bring their own parsers and after some time of real usage to choose the best to pack into the package itself or to use for new design. It could be achieved by creating new interface like type ArgParser interface {
// Parses args and returns a custom map filled with parsed values or an error
Parse(args []string) (cli.ArgsMap, error)
// Returns a list of triplets: name, usage, short description
GetUsage() [][]string
// Prints help to output stream
Help(args []string, w *io.Writer) error
// Returns completion options
Complete(args []string) ([]string, error)
} Pros
Cons
|
Checklist
What problem does this solve?
Undocumented arguments can be a burden and forces developers to generate write their own
ArgsUsage
Solution description
Add a new field to
App
andCommand
calledArgs
of type[]ArgSpec
which is an interface likeFlag
. There would many structs that implement this interface, like those for parsing flags.Along with this there are several other rules that will result in a panic (always no matter what the provided args to be parsed are)
Max() == 0
arg per fieldArgs never mean anything for sub-comands.
Args will be accessed in the same manner as
Flags
currently, they are parsed after flags so will override them (that is how one can have a EnvVar be the default to an arg)Implementation
If there are any
[]ArgSpec
then all provided args must be used, otherwise a error is printed as if a required flag was not supplied.This also means that the
Arg(n)
andArgs()
won't return anything after parsing args.Describe alternatives you've considered
The text was updated successfully, but these errors were encountered: