Closed dkinzer closed 5 years ago
Currently, GLI very much wants all arguments at the end after all commands and options have been parsed. git clone hello/world --branch=mybranch --bare ---quiet
would treat hello/word
as a command (which it wouldn't find and generate an error).
It does make it unclear how GLI would know what is a command and what is an argument. Because it's possible to make nested commands, you could create a somwhat confusing situation, for example suppose that you had a command list
that had two subcommands new
and archived
:
> todo list new # list only new tasks
> todo list archive # list only archived tasks
> todo list new -l # long-form listing
> todo list archive --fields=id,name # customize fields
Suppose you wanted todo list
to list all tasks, which is currently possible to implement in GLI. Now suppose further you wanted it to take an argument, like the location of the task list:
> todo list ~/tasks
If you did todo list ~/tasks -l
GLI would not know if you were giving list
a subcommand (which list
supports) or giving it an argument. This is a problem when you fat-finger a subcommand, e.g. todo list nwe
.
So, to make all this work with the existing nested commands and all the features therein, you would need to make some decisions (and possibly internal options) on what to do with an "unknown" command, i.e. pass it as an arg, or something else.
@davetron5000 thank you for getting back to me. I appreciate the work that you've put into this project and your consideration.
It does make it unclear how GLI would know what is a command and what is an argument
That's an interesting point; just to be clear, you are saying that because GLI cannot distinguish a non command token from a command token then it assumes the non-command token is a command, and then throws and error when it's not (understandably)?
However, isn't it reasonable for the GLI parser to assume that any token that is not the same as one of it's sub commands (it has knowledge of all it's subcommands) must be an argument to the last previously defined command instead of attempting to treat it as a subcommand?
In the example you show above, todo list ~/tasks -l
, it seems to me that if list is indeed a known subcommand for todo
than it's perfectly reasonable for the parser to assume that list
is a command and not an argument.
In the example you show above, todo list ~/tasks -l, it seems to me that if list is indeed a known subcommand for todo than it's perfectly reasonable for the parser to assume that list is a command and not an argument.
Yeah, but if it worked this way, it would mean that typos for intended subcommands would be treated as arguments and not errors, and this could be surprising for users of the cli app.
But, I could imagine some sort of configuration option per app or even per command that could enable this behavior.
I think what's tricky is that the more flexibility that has been added that harder it is to add even more :)
Yeah, but if it worked this way, it would mean that typos for intended subcommands would be treated as arguments
Yes, I think that would be the case with how things are set up. Even with the current setup I believe there are scenarios where a typo in the subcommand name would be taken as an argument.
I believe however that this is an artifact of the way the parser works. Because the parser works from left to right. I think if the parser were to work from right to left this would catch all these types of errors regardless of whether the options come after or before the arguments.
Such a parser would probably not be useful for an autocompletion feature so maybe that's not a good option either.
I think what's tricky is that the more flexibility that has been added that harder it is to add even more :)
Yeah, I know what you mean. Thanks for considering it, though. If you are amenable I might give the reverse parser or the options idea a crack at some point.
As for my immediate problem, I've decided to go with all options instead of arguments. I was uncomfortable with the idea at first but then I noticed the gpg
command uses only options. (no arguments)
According to https://github.com/davetron5000/gli/issues/18#issuecomment-1451598 it might be possible to allow for options after the argument. For example with
git
I can do the following:The synopsis here is more like
It seems like I would not be able to reproduce that with Gli because Gli (as far as I can tell) forces the following synopsis:
Thus the example
git
command implemented with Gli would be have to beWhich seems unnatural.
Is there a way to implement a command so that options can be passed after arguments and allow the synopsis to be as follows?
Thanks.