-
Notifications
You must be signed in to change notification settings - Fork 112
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
Consider adding support for nested commands or subcommands #71
Comments
@kmvanbrunt
|
Now that we are using argparse for command argument parsing, doors have been open for this. Users can manually do it using argparse. But maybe we could come up with some sort of clever deocrator-based approach akin to how |
If we can't think of a good way of adding explicit support for nested commands (i.e. subcommands), then perhaps it would be sufficient to simply document by example how to use argparse to do this. |
Since this is possible using argparse, I'll add some documentation and an example or two showing how to do it with argparse. That can be our first step, and then we can reassess whether we should add additional support later. |
I've come up with a system that allows you to nest Cmd classes within each other. The top level (root) command then handles passing the subcommands down to it's subordinates. You can also "change directory" so that you are at the subcommand's level and therefore do not need to specify the subcommand anymore. I tried to come up with a decorator like approach but found it to be too complicated. I also liked the ability to separate the subcommands into their own class, it bodes well for code organizing. I'm not sure how this works with argparse, I don't have much experience with it. Edit: Tests have been completed successfully. I'm now going to focus on adding additional tests for this feature. |
@lobocv
|
@tleonhardt Happy to meet you too! I would have preferred to make a separate SubCommand class (and maybe we can still go that route). My reasoning for having separate classes for each subcommand and then layering them were:
I'm not too familiar with the unit test framework being used in this project so that may take me a little while to figure out. My preliminary tests seem to work and not broken anything! Please feel free to branch off my fork and play around. I'll add an example here shortly. I've added a example of nesting commands in examples/subcommands.py (on my fork). Please have a look |
@lobocv Honestly, the vast majority of our tests are integration tests, not unit tests. So please don't take what we have as an example of how to write good unit tests though ;-) |
@lobocv As it turns out what you are doing is totally, radically different from what I have been envisioning when I have talked about a feature that adds support for subcommands. What I'm talking about is akin to a command such as "git" where that one command has many subcommands - i.e. "git clone", "git status", "git commit", etc. If you "git -h" you will get very different help information than if you do "git clone -h". So effectively it is one command with various subcommands, where each subcommand takes different options, but all are invokable from the same prompt. Except in the context of What you have done is more akin to architecting a way to turn a What you have done is pretty cool and I like it, but I'm not sure I can see a clean way to merge it into the mainstream Even if we didn't merge it into the main baseline, maybe we could merge in an example or something. I do think it is a nice example of how to do nested @kotfu and/or @kmvanbrunt if either of you have a chance to look at his code, I'd like to hear your thoughts. |
@tleonhardt Thanks for having a look at my work. I had a feeling that my connotation of "subcommand" was slightly different. From now on I will use "submenu" instead of "subcommand". For my job I needed the feature I had made and I thought it would be helpful to contribute it back to the project. I understand the changes are quite significant and can have an adverse affect on people if we merged it. I'm not sure what the best approach would be now. If the changing of the prompt is a concern, perhaps we can find a solution to that. Currently I alter the prompt to show the "scope" at which the CLI resides. Perhaps, if the prompt is manually changed it, can override this feature. The library seems to behave the same if you don't use nested Cmd's so perhaps it may not be a problem for people not using this feature. I'd love to hear everyone's thoughts. Edit: There may actually be a better way to do this that would not involve altering the cmd2.Cmd class. Instead we can use a decorator that can override the root level Cmd to add do_* commands which perform the redirecting into submenus. This way we shouldn't get any unintended affects by altering the core code and any problems should reside for the most part in the overriding decorator. Perhaps you will be more comfortable with that approach. |
@lobocv |
PR #257 contains an example of how to use argparse sub-commands as well as a tweak to If anyone has any comments or suggestions for improvement, I'd appreciate hearing them. |
@lobocv Just an FYI, you can look at the subcommands.py example that recently got merged into master to see what we were talking about in terms of support for sub-commands. |
Many REPL frameworks have support for multi-level commands, where the command has sub-commands.
While this can be done with cmd2, there isn't any built-in support to make it easy.
Consider adding some built-in support to make it easy to have nested commands or subcommands.
The text was updated successfully, but these errors were encountered: