[Freeipa-devel] [PATCH] 372 Added attribute to specify command's CLI name.
Endi Sukma Dewata
edewata at redhat.com
Mon Aug 10 18:47:43 UTC 2015
On 8/10/2015 1:35 PM, Endi Sukma Dewata wrote:
> 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
New patch attached. Fixed patch title & description.
--
Endi S. Dewata
-------------- next part --------------
>From 87e574bfd8fad47320e1dc77d27ec70ebdea7754 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Fri, 7 Aug 2015 05:00:14 +0200
Subject: [PATCH] Added attribute to change command's CLI name.
A new attribute has been added to the HasParams class to allow a
command to change the CLI name if necessary. By default the CLI
name is the same as the command's 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
More information about the Freeipa-devel
mailing list