From d596b7348be97bd16f12f92d407ef5e2883a8445 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 10 May 2010 15:27:12 -0400 Subject: [PATCH] Use ._cl_name and ._cl_aliases instead of overwriting .name and .aliases. We don't change the keys hardcoded into the Command._run methods, so we need to keep the original names. Hmm, I'll have to adjust Command.help and Argument.help to use the external names... --- hooke/ui/commandline.py | 52 ++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/hooke/ui/commandline.py b/hooke/ui/commandline.py index 9d1806e..ddf48c9 100644 --- a/hooke/ui/commandline.py +++ b/hooke/ui/commandline.py @@ -8,7 +8,6 @@ import readline # including readline makes cmd.Cmd.cmdloop() smarter import shlex from ..command import CommandExit, Command, Argument -from ..compat.odict import odict from ..ui import UserInterface, CommandMessage @@ -19,19 +18,19 @@ class CommandLineParser (optparse.OptionParser): :class:`hooke.command.Command`. """ def __init__(self, command): - optparse.OptionParser.__init__(self, prog=command.name) + optparse.OptionParser.__init__(self, prog=command._cl_name) self.command = command - self.command_opts = odict() - self.command_args = odict() + self.command_opts = [] + self.command_args = [] for a in command.arguments: if a.name == 'help': continue # 'help' is a default OptionParser option - name = a.name.replace('_', '-') if a.optional == True: - self.add_option('--%s' % name, dest=a.name, default=a.default) - self.command_opts[name] = a + self.add_option( + '--%s' % a._cl_name, dest=a._cl_name, default=a.default) + self.command_opts.append(a) else: - self.command_args[name] = a + self.command_args.append(a) def exit(self, status=0, msg=None): """Override :meth:`optparse.OptionParser.exit` which calls @@ -64,7 +63,7 @@ class DoCommand (CommandMethod): try: args = self._parse_args(self.command, args) except optparse.OptParseError, e: - self.cmd.stdout.write(str(e)) + self.cmd.stdout.write(str(e).lstrip()+'\n') self.cmd.stdout.write('Failure\n') return self.cmd.inqueue.put(CommandMessage(self.command, args)) @@ -79,11 +78,15 @@ class DoCommand (CommandMethod): def _parse_args(self, command, args): argv = shlex.split(args, comments=True, posix=True) options,args = self.parser.parse_args(argv) + if len(args) != len(self.parser.command_args): + raise optparse.OptParseError('%d arguments given, but %s takes %d' + % (len(args), command._cl_name, + len(self.parser.command_args))) params = {} - for name,argument in self.parser.command_opts.items(): - params[name] = getattr(options, name) - for name,argument in self.parser.command_args.items(): - params[name] = value + for argument in self.parser.command_opts: + params[argument.name] = getattr(options, argument._cl_name) + for i,argument in enumerate(self.parser.command_args): + params[argument.name] = args[i] return params class HelpCommand (CommandMethod): @@ -106,8 +109,8 @@ class HelpCommand (CommandMethod): options_string = '' else: options_string = '[options]' - arg_string = ' '.join([name for name,arg - in self.parser.command_args.items()]) + arg_string = ' '.join( + [arg._cl_name for arg in self.parser.command_args]) return ' '.join([x for x in [self.command.name, options_string, arg_string] @@ -134,10 +137,8 @@ class HookeCmd (cmd.Cmd): def _add_command_methods(self): for command in self.commands: - command.name = self._safe_name(command.name) - command.aliases = [self._safe_name(n) for n in command.aliases] - for name in [command.name] + command.aliases: - name = self._safe_name(name) + self._setup_command(command) + for name in [command._cl_name] + command._cl_aliases: setattr(self.__class__, 'do_%s' % name, DoCommand(self, command)) setattr(self.__class__, 'help_%s' % name, @@ -148,6 +149,7 @@ class HookeCmd (cmd.Cmd): exit_command = Command( name='exit', aliases=['quit', 'EOF'], help='Exit Hooke cleanly.') + self._setup_command(exit_command) exit_command.arguments = [] # remove help argument for name in [exit_command.name] + exit_command.aliases: setattr(self.__class__, 'do_%s' % name, @@ -168,9 +170,21 @@ undocumented commands. Argument(name='command', type='string', optional=True, help='The name of the command you want help with.') ] + self._setup_command(help_command) setattr(self.__class__, 'help_help', HelpCommand(self, help_command)) + def _setup_command(self, command): + """Attach some UI specific data to `command`. After this + point, the :attr:`commands` are read only. + """ + command._cl_name = self._safe_name(command.name) + command._cl_aliases = [self._safe_name(n) for n in command.aliases] + for argument in command.arguments: + argument._cl_name = self._safe_name(argument.name) + argument._cl_aliases = [self._safe_name(n) + for n in argument.aliases] + class CommandLine (UserInterface): """Command line interface. Simple and powerful. -- 2.26.2