A new attribute has been added to the HasParams class to allow a command to specify a different CLI name if necessary. By default the command's CLI name is the same as the class name.
https://fedorahosted.org/freeipa/ticket/5189 -- Endi S. Dewata
From 6808e44b97148db8700e47d1d436dd0a30a0c9f9 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" <edew...@redhat.com> Date: Fri, 7 Aug 2015 05:00:14 +0200 Subject: [PATCH] Added attribute to specify command's CLI name. A new attribute has been added to the HasParams class to allow a command to specify a different CLI name if necessary. By default the command's CLI name is the same as the class name. https://fedorahosted.org/freeipa/ticket/5189 --- ipalib/backend.py | 15 ++++++++++++-- ipalib/cli.py | 59 ++++++++++++++++++++++++++++++------------------------ ipalib/frontend.py | 19 ++++++++++++++++++ 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/ipalib/backend.py b/ipalib/backend.py index d510bc73396cd8b219836d28083e3165f226d466..48a4445c34a861d65e80f1fdaf711cbd0f643ae2 100644 --- a/ipalib/backend.py +++ b/ipalib/backend.py @@ -121,12 +121,23 @@ class Executioner(Backend): def destroy_context(self): destroy_context() + def find_command(self, cli_name): + # TODO: replace loop with a dict to map CLI names to commands + for name in self.Command: + cmd = self.Command[name] + if cmd.NO_CLI: + continue + if cmd.cli_name() == cli_name: + return cmd + return None + def execute(self, _name, *args, **options): error = None try: - if _name not in self.Command: + cmd = self.find_command(_name) + if not cmd: raise CommandError(name=_name) - result = self.Command[_name](*args, **options) + result = cmd(*args, **options) except PublicError, e: error = e except StandardError, e: diff --git a/ipalib/cli.py b/ipalib/cli.py index 4104e6482e4e713d701c6c1a4313ab6ecc899057..0fa00d3a6e32fc6095ca3b76270355cf9cb3dd2d 100644 --- a/ipalib/cli.py +++ b/ipalib/cli.py @@ -771,32 +771,40 @@ class help(frontend.Local): if outfile is None: outfile = sys.stdout writer = self._writer(outfile) - name = from_cli(key) - mod_name = '%s.%s' % (self._PLUGIN_BASE_MODULE, name) + if key is None: self.api.parser.print_help(outfile) return - if name == "topics": + + if key == "topics": self.print_topics(outfile) return - if name in self._topics: - self.print_commands(name, outfile) - elif name in self.Command: - cmd = self.Command[name] - if cmd.NO_CLI: - raise HelpError(topic=name) - self.Backend.cli.build_parser(cmd).print_help(outfile) - elif mod_name in sys.modules: - self.print_commands(name, outfile) - elif name == "commands": + + if key in self._topics: + self.print_commands(key, outfile) + return + + if key == "commands": mcl = max(len(s) for s in (self.Command)) for cname in self.Command: cmd = self.Command[cname] if cmd.NO_CLI: continue - writer('%s %s' % (to_cli(cmd.name).ljust(mcl), cmd.summary)) - else: - raise HelpError(topic=name) + writer('%s %s' % (cmd.cli_name().ljust(mcl), cmd.summary)) + return + + cmd = self.find_command(key) + if cmd: + self.Backend.cli.build_parser(cmd).print_help(outfile) + return + + name = from_cli(key) + mod_name = '%s.%s' % (self._PLUGIN_BASE_MODULE, name) + if mod_name in sys.modules: + self.print_commands(name, outfile) + return + + raise HelpError(topic=key) def _writer(self, outfile): def writer(string=''): @@ -848,7 +856,7 @@ class help(frontend.Local): writer(_('Topic commands:')) for c in commands: writer( - ' %s %s' % (to_cli(c.name).ljust(mcl), c.summary)) + ' %s %s' % (c.cli_name().ljust(mcl), c.summary)) writer() writer(_('To get command help, use:')) writer(_(' ipa <command> --help')) @@ -866,10 +874,10 @@ class show_mappings(frontend.Command): has_output = tuple() def run(self, command_name, **options): - command_name = from_cli(command_name) - if command_name not in self.Command: + cmd = self.find_command(command_name) + if not cmd: raise CommandError(name=command_name) - params = self.Command[command_name].options + params = cmd.options out = [('Parameter','LDAP attribute'), ('=========','==============')] mcl = len(out[0][0]) @@ -1061,15 +1069,14 @@ class cli(backend.Executioner): print >>sys.stderr, 'Error: Command not specified' exit(2) (key, argv) = (argv[0], argv[1:]) - name = from_cli(key) - if name not in self.Command and len(argv) == 0: + cmd = self.find_command(key) + if not cmd and len(argv) == 0: try: self.Command.help(unicode(key), outfile=sys.stderr) except HelpError: pass - if name not in self.Command or self.Command[name].NO_CLI: + if not cmd: raise CommandError(name=key) - cmd = self.Command[name] return cmd def process_keyword_arguments(self, cmd, kw): @@ -1090,7 +1097,7 @@ class cli(backend.Executioner): cmd = self.get_command(argv) if cmd is None: return - name = cmd.name + name = cmd.cli_name() kw = self.parse(cmd, argv[1:]) if not isinstance(cmd, frontend.Local): self.create_context() @@ -1207,7 +1214,7 @@ class cli(backend.Executioner): return '[%s]' % name def usage_iter(self, cmd): - yield 'Usage: %%prog [global-options] %s' % to_cli(cmd.name) + yield 'Usage: %%prog [global-options] %s' % cmd.cli_name() for arg in cmd.args(): name = self.__get_arg_name(arg) if name is None: diff --git a/ipalib/frontend.py b/ipalib/frontend.py index 2ca3aaea82ea63702052eedbd7e4081f239cbaed..47cf318dc90e82f71b34ab4790d12bedbc9ed2ec 100644 --- a/ipalib/frontend.py +++ b/ipalib/frontend.py @@ -225,6 +225,15 @@ class HasParam(Plugin): # HasParam is the base class for most frontend plugins, that make it to users # This flag indicates that the command should not be available in the cli NO_CLI = False + CLI_NAME = None + + @classmethod + def cli_name(cls): + if cls.CLI_NAME: + return cls.CLI_NAME + + # TODO: replace with to_cli(cls.__name__) + return cls.__name__.replace('_', '-') def _get_param_iterable(self, name, verb='takes'): """ @@ -457,6 +466,16 @@ class Command(HasParam): self.validate_output(ret, options['version']) return ret + def find_command(self, cli_name): + # TODO: replace loop with a dict to map CLI names to commands + for name in self.Command: + cmd = self.Command[name] + if cmd.NO_CLI: + continue + if cmd.cli_name() == cli_name: + return cmd + return None + def soft_validate(self, values): errors = dict() for p in self.params(): -- 2.4.3
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code