mirror of
ssh://git.janware.com/srv/git/janware/proj/jw-python
synced 2026-01-15 01:52:56 +01:00
jwutils.Cmd: Add method add_subcommands()
Add method jwutils.Cmd.add_subcommands(). cmd.add_subcommands(C) will parse and invoke C as a subcommand of cmd, if C is of type jwutils.cmd. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
ad67dd3832
commit
c5b964a5bb
2 changed files with 41 additions and 3 deletions
|
|
@ -1,9 +1,14 @@
|
|||
import abc
|
||||
import argparse
|
||||
|
||||
from jwutils import log
|
||||
|
||||
# compatible with Python 2 *and* 3
|
||||
ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})
|
||||
|
||||
# full blown example of one level of nested subcommands
|
||||
# git -C project remote -v show -n myremote
|
||||
|
||||
class Cmd(ABC): # export
|
||||
|
||||
@abc.abstractmethod
|
||||
|
|
@ -13,6 +18,9 @@ class Cmd(ABC): # export
|
|||
def __init__(self, name, help):
|
||||
self.name = name
|
||||
self.help = help
|
||||
self.parent = None
|
||||
self.children = []
|
||||
self.child_classes = []
|
||||
|
||||
async def _run(self, args):
|
||||
pass
|
||||
|
|
@ -23,3 +31,12 @@ class Cmd(ABC): # export
|
|||
r.set_defaults(func=self.run)
|
||||
return r
|
||||
|
||||
def add_subcommands(self, cmd):
|
||||
if isinstance(cmd, list):
|
||||
for c in cmd:
|
||||
self.add_subcommands(c)
|
||||
return
|
||||
self.child_classes.append(cmd)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -6,15 +6,27 @@ import inspect
|
|||
import re
|
||||
import pickle
|
||||
import asyncio
|
||||
|
||||
import jwutils
|
||||
from jwutils import log
|
||||
|
||||
class Cmds: # export
|
||||
|
||||
def __add_cmd_to_parser(self, cmd, parsers):
|
||||
parser = cmd.add_parser(parsers)
|
||||
cmd.add_arguments(parser)
|
||||
if len(cmd.child_classes) > len(cmd.children):
|
||||
for c in cmd.child_classes:
|
||||
cmd.children.append(c())
|
||||
for sub_cmd in cmd.children:
|
||||
subparsers = parser.add_subparsers(title='Available commands of ' + cmd.name, metavar='')
|
||||
self.__add_cmd_to_parser(sub_cmd, subparsers)
|
||||
|
||||
def __init__(self, description = '', filter = '^Cmd.*', modules=None, eloop=None):
|
||||
self.__description = description
|
||||
self.__filter = filter
|
||||
self.__modules = modules
|
||||
self.__cmds = []
|
||||
default_log_level = log.NOTICE
|
||||
default_log_flags = 'stderr,position,prio,color'
|
||||
# poor man's parsing in the absence of a complete command-line definition
|
||||
|
|
@ -40,9 +52,9 @@ class Cmds: # export
|
|||
if eloop is None:
|
||||
self.eloop = asyncio.get_event_loop()
|
||||
self.__own_eloop = True
|
||||
subparsers = self.__parser.add_subparsers(title='Available commands', metavar='')
|
||||
if self.__modules == None:
|
||||
self.__modules = [ '__main__' ]
|
||||
subcmds = set()
|
||||
for m in self.__modules:
|
||||
if m != '__main__':
|
||||
importlib.import_module(m)
|
||||
|
|
@ -54,7 +66,16 @@ class Cmds: # export
|
|||
log.slog(log.DEBUG, 'instantiating command "{}"'.format(c))
|
||||
cmd = c()
|
||||
cmd.cmds = self
|
||||
cmd.add_parser(subparsers)
|
||||
#cmd.add_parser(subparsers)
|
||||
self.__cmds.append(cmd)
|
||||
for child in cmd.child_classes:
|
||||
subcmds.add(child)
|
||||
subcmds.update(cmd.child_classes)
|
||||
|
||||
cmds = [cmd for cmd in self.__cmds if type(cmd) not in subcmds]
|
||||
subparsers = self.__parser.add_subparsers(title='Available commands', metavar='')
|
||||
for cmd in cmds:
|
||||
self.__add_cmd_to_parser(cmd, subparsers)
|
||||
|
||||
async def __run(self):
|
||||
args = self.__parser.parse_args()
|
||||
|
|
@ -69,7 +90,7 @@ class Cmds: # export
|
|||
self.eloop = None
|
||||
self.__own_eloop = False
|
||||
|
||||
def parser():
|
||||
def parser(self):
|
||||
return self.__parser
|
||||
|
||||
def run(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue