How to create nested commands?
LexSong opened this issue · 4 comments
Take conda
for example. We have commands like this:
conda create
conda list
conda env create
conda env list
conda env export
or git
:
git init
git commit
git stack push
git stack pop
git remote add
git remote show
I think one way to handle this is to create subcommand class and explicitly pass args
to it's parse
function:
from cliar import Cliar
class StackCommand(Cliar):
def push(self, ...):
...
def pop(self, ...):
...
class MainCommand(Cliar):
def __init__(self):
self.stack_command = StackCommand()
def stack(self, args):
self.stack_command.parse(args)
Currently, the Cliar
class impliedly take args
from the command line.
However, I think taking args from another command may be useful to build complex CLI.
Thanks for opening the issue. The problem of multilevel subcommands has been bugging me since the very start, but I haven't come up with a clever solution so far. I'll investigate closer into your proposal, thanks!
How about something like the following?
class Env(Cliar):
def create(self):
...
def list(self):
...
def export(self):
...
class Conda(Cliar):
env: Env
def create(self):
...
def list(self):
...
Cliar's metaclass will read the class definition of Conda
. It will see that it has a class variable annotated as Env
, and that Env
is itself a subclass of Cliar. The metaclass will then add a function to the class Conda
that will do the work of directing any nested command like conda env create
to an object of the Env
class instead.
Of course, the nesting could be made more explicit by using descriptors.
class Conda(Cliar):
env = Env()
...
For this, the Cliar class should itself support the descriptor protocol.
OK, I got it :-) I've implemented this feature in https://github.com/moigagoo/cliar/tree/feature/nested_commands
Have to fix the tests and add a new test.
The syntax will be as follows:
class Env(Cliar):
def create(self):
...
def list(self):
...
def export(self):
...
class Conda(Cliar):
env = Env
def create(self):
...
def list(self):
...
Added in version 1.3.0: https://moigagoo.github.io/cliar/tutorial/#nested-commands