jwutils.Cmds: Cmd.add_subcommands() fails for multiple commands

jwutils.Cmd.add_subcommands() had two issues. First, it failed for
more than one command, and with that fixed, it only added the first
command of a list of commands passed as an argument. This commit
fixes both issues and leaves some logging and cleanup in place, which
was used during debugging.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2020-04-07 09:23:13 +02:00
commit 33d3b7a7b3
2 changed files with 28 additions and 22 deletions

View file

@ -8,7 +8,7 @@ import pickle
import asyncio import asyncio
import jwutils import jwutils
from jwutils import log from jwutils.log import *
class Cmds: # export class Cmds: # export
@ -24,8 +24,9 @@ class Cmds: # export
if len(cmd.child_classes) > len(cmd.children): if len(cmd.child_classes) > len(cmd.children):
for c in cmd.child_classes: for c in cmd.child_classes:
cmd.children.append(self.__instantiate(c)) cmd.children.append(self.__instantiate(c))
if len(cmd.children) > 0:
subparsers = parser.add_subparsers(title='Available subcommands of ' + cmd.name, metavar='')
for sub_cmd in cmd.children: 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) self.__add_cmd_to_parser(sub_cmd, subparsers)
def __init__(self, description = '', filter = '^Cmd.*', modules=None, eloop=None): def __init__(self, description = '', filter = '^Cmd.*', modules=None, eloop=None):
@ -33,8 +34,14 @@ class Cmds: # export
self.__filter = filter self.__filter = filter
self.__modules = modules self.__modules = modules
self.__cmds = [] self.__cmds = []
default_log_level = log.NOTICE self.eloop = eloop
default_log_flags = 'stderr,position,prio,color' self.__own_eloop = False
if eloop is None:
self.eloop = asyncio.get_event_loop()
self.__own_eloop = True
log_level = NOTICE
log_flags = 'stderr,position,prio,color'
# poor man's parsing in the absence of a complete command-line definition # poor man's parsing in the absence of a complete command-line definition
for i in range(1, len(sys.argv)): for i in range(1, len(sys.argv)):
if i >= len(sys.argv) - 1: if i >= len(sys.argv) - 1:
@ -42,34 +49,33 @@ class Cmds: # export
arg = sys.argv[i] arg = sys.argv[i]
if arg == '--log-level': if arg == '--log-level':
i += 1 i += 1
default_log_level = sys.argv[i] log_level = sys.argv[i]
continue continue
if arg == '--log-flags': if arg == '--log-flags':
default_log_flags = sys.argv[i] log_flags = sys.argv[i]
continue continue
log.set_flags(default_log_flags) set_flags(log_flags)
log.set_level(default_log_level) set_level(log_level)
self.__parser = argparse.ArgumentParser(usage=os.path.basename(sys.argv[0]) + ' [command] [options]', slog(DEBUG, "set log level to {}".format(log_level))
self.__parser = argparse.ArgumentParser(usage=os.path.basename(sys.argv[0]) + ' [options]',
formatter_class=argparse.ArgumentDefaultsHelpFormatter, description=self.__description) formatter_class=argparse.ArgumentDefaultsHelpFormatter, description=self.__description)
self.__parser.add_argument('--log-flags', help='Log flags', default=default_log_flags) self.__parser.add_argument('--log-flags', help='Log flags', default=log_flags)
self.__parser.add_argument('--log-level', help='Log level', default=default_log_level) self.__parser.add_argument('--log-level', help='Log level', default=log_level)
self.eloop = eloop
self.__own_eloop = False
if eloop is None:
self.eloop = asyncio.get_event_loop()
self.__own_eloop = True
if self.__modules == None: if self.__modules == None:
self.__modules = [ '__main__' ] self.__modules = [ '__main__' ]
subcmds = set() subcmds = set()
slog(DEBUG, '-- searching for commands')
for m in self.__modules: for m in self.__modules:
if m != '__main__': if m != '__main__':
importlib.import_module(m) importlib.import_module(m)
for name, c in inspect.getmembers(sys.modules[m], inspect.isclass): for name, c in inspect.getmembers(sys.modules[m], inspect.isclass):
if not re.match(self.__filter, name): if not re.match(self.__filter, name):
slog(DEBUG, 'o "{}.{}" has wrong name'.format(m, name))
continue continue
if inspect.isabstract(c): if inspect.isabstract(c):
slog(DEBUG, 'o "{}.{}" is abstract'.format(m, name))
continue continue
log.slog(log.DEBUG, 'instantiating command "{}"'.format(c)) slog(DEBUG, 'o "{}.{}" is fine, instantiating'.format(m, name))
cmd = self.__instantiate(c) cmd = self.__instantiate(c)
#cmd.add_parser(subparsers) #cmd.add_parser(subparsers)
self.__cmds.append(cmd) self.__cmds.append(cmd)
@ -84,8 +90,8 @@ class Cmds: # export
async def __run(self): async def __run(self):
args = self.__parser.parse_args() args = self.__parser.parse_args()
log.set_flags(args.log_flags) set_flags(args.log_flags)
log.set_level(args.log_level) set_level(args.log_level)
return await args.func(args) return await args.func(args)
def __del__(self): def __del__(self):