from kamaki.cli.utils import print_dict, split_input, print_items
from kamaki.cli.history import History
from kamaki.cli.errors import CLIError
+from kamaki.clients import ClientError
def _init_shell(exe_string, parser):
# exec command or change context
if subcmd.is_command: # exec command
cls = subcmd.get_class()
- instance = cls(dict(cmd_parser.arguments))
+ if subcmd.path == 'history_recall':
+ instance = cls(dict(cmd_parser.arguments), self.cmd_tree)
+ else:
+ instance = cls(dict(cmd_parser.arguments))
cmd_parser.update_arguments(instance.arguments)
instance.arguments.pop('config')
#cmd_parser = ArgumentParseManager(subcmd.path,
for name, arg in instance.arguments.items():
arg.value = getattr(cmd_parser.parsed, name, arg.default)
+
try:
_exec_cmd(instance,
cmd_parser.unparsed,
cmd_parser.parser.print_help)
- except CLIError as err:
+ except (ClientError, CLIError) as err:
_print_error_message(err)
elif ('-h' in cmd_args or '--help' in cmd_args) \
or len(cmd_args): # print options
if description is not None:
cmd.help = description
+ def find_best_match(self, terms):
+ """Find a command that best matches a given list of terms
+
+ :param terms: (list of str) match them against paths in cmd_tree
+
+ :returns: (Command, list) the matching command, the remaining terms
+ """
+ path = []
+ for term in terms:
+ check_path = path + [term]
+ if '_'.join(check_path) not in self._all_commands:
+ break
+ path = check_path
+ if path:
+ return (self._all_commands['_'.join(path)], terms[len(path):])
+ return (None, terms)
+
def add_tree(self, new_tree):
tname = new_tree.name
tdesc = new_tree.description
from kamaki.cli.command_tree import CommandTree
from kamaki.cli.argument import IntArgument, ValueArgument
+from kamaki.cli.argument import ArgumentParseManager
from kamaki.cli.history import History
from kamaki.cli import command
from kamaki.cli.commands import _command_init
+from kamaki.cli import _exec_cmd, _print_error_message
+from kamaki.cli.errors import CLIError
+from kamaki.cli.utils import split_input
+from kamaki.clients import ClientError
history_cmds = CommandTree('history', 'Command history')
super(self.__class__, self).__init__(arguments)
self._cmd_tree = cmd_tree
+ def _run_from_line(self, line):
+ terms = split_input(line)
+ cmd, args = self._cmd_tree.find_best_match(terms)
+ if not cmd.is_command:
+ return
+ try:
+ instance = cmd.get_class()(self.arguments)
+ instance.config = self.config
+ prs = ArgumentParseManager(cmd.path.split(),
+ dict(instance.arguments))
+ prs.syntax = '%s %s' % (cmd.path.replace('_', ' '),
+ cmd.get_class().syntax)
+ prs.parse(args)
+ _exec_cmd(instance, prs.unparsed, prs.parser.print_help)
+ except (CLIError, ClientError) as err:
+ _print_error_message(err)
+ except Exception as e:
+ print('Execution of [ %s ] failed' % line)
+ print('\t%s' % e)
+
def main(self, commandid):
super(self.__class__, self).main()
r = self.history.retrieve(commandid)
+ print(r[:-1])
if self._cmd_tree:
- raise NotImplemented('Sorry, recall is not implemented yet')
- else:
- print(r)
+ r = r[len('kamaki '):-1] if r.startswith('kamaki ') else r[:-1]
+ self._run_from_line(r)