summaryrefslogtreecommitdiffstats
path: root/ipalib/cli.py
diff options
context:
space:
mode:
authorJan Zeleny <jzeleny@redhat.com>2010-12-20 15:42:04 +0100
committerRob Crittenden <rcritten@redhat.com>2011-01-07 09:42:38 -0500
commit6214af8a8d74066e6ba0c36dd0c4e57c395f4117 (patch)
treed9460dd8f9bafabc3dc688851f5de19f638068e5 /ipalib/cli.py
parentbfc338d81c088cca66b4060505ac5742d4c19911 (diff)
downloadfreeipa-6214af8a8d74066e6ba0c36dd0c4e57c395f4117.tar.gz
freeipa-6214af8a8d74066e6ba0c36dd0c4e57c395f4117.tar.xz
freeipa-6214af8a8d74066e6ba0c36dd0c4e57c395f4117.zip
Changed concept of ipa help
The concept is now following: topic: either a module or a group of modules containing registered commands. All these commands will usually handle common entity type (e.g. hbac rules) subtopic: each topic can have a number of subtopics. In this case topic is a group of modules and each module represents a subtopic. grouping modules to topics is possible by assigning a 2-tuple to module variable: topic = ('topic-name','topic description') The topic description has to be the same in all modules in the topic. These are examples of commands now available in IPA help: ipa help - display a list of all topics ipa help hbac - display help for hbac topic ipa help hbacrule - display help for a subtopic of hbac ipa help hbacrule-add - display help for a particular command https://fedorahosted.org/freeipa/ticket/410
Diffstat (limited to 'ipalib/cli.py')
-rw-r--r--ipalib/cli.py117
1 files changed, 97 insertions, 20 deletions
diff --git a/ipalib/cli.py b/ipalib/cli.py
index 2ac3926f3..436607f27 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -619,8 +619,26 @@ class help(frontend.Local):
end = r.find('.', start)
return r[start:end]
+ def _get_module_topic(self, module_name):
+ if not sys.modules[module_name]:
+ __import__(module_name)
+ module = sys.modules[module_name]
+
+ dir_list = dir(module)
+ if 'topic' in dir_list:
+ topic = module.topic
+ else:
+ topic = (self._get_command_module(module_name), None)
+
+ return topic
+
+ def _count_topic_mcl(self, topic_name, mod_name):
+ mcl = max((self._topics[topic_name][1], len(mod_name)))
+ self._topics[topic_name][1] = mcl
+
def finalize(self):
- # {plugin_module: [mcl, commands]}
+ # {topic: ["description", mcl, {"subtopic": ["description", mcl, [commands]]}]}
+ # {topic: ["description", mcl, [commands]]}
self._topics = {}
# [builtin_commands]
self._builtins = []
@@ -629,12 +647,35 @@ class help(frontend.Local):
for c in self.Command():
if c.INTERNAL:
continue
- topic = self._get_command_module(c.module)
- if topic:
- self._topics.setdefault(topic, [0]).append(c)
- # compute maximum length of command in topic
- mcl = max((self._topics[topic][0], len(c.name)))
- self._topics[topic][0] = mcl
+
+ topic = self._get_module_topic(c.module)
+ topic_name = topic[0]
+
+ if topic_name:
+ if topic[1] is None: # a module without grouping
+ if topic_name in self._topics:
+ self._topics[topic_name][2].append(c)
+ else:
+ m = '%s.%s' % (self._PLUGIN_BASE_MODULE, topic_name)
+ doc = (sys.modules[m].__doc__ or '').strip().split('\n', 1)[0]
+ self._topics[topic_name] = [doc, 0, [c]]
+ mcl = max((self._topics[topic_name][1], len(c.name)))
+ self._topics[topic_name][1] = mcl
+ else: # a module grouped in a topic
+ doc = (sys.modules[c.module].__doc__ or '').strip().split('\n', 1)[0]
+ mod_name = c.module.rsplit('.',1)[1]
+ if topic_name in self._topics:
+ if mod_name in self._topics[topic_name][2]:
+ self._topics[topic_name][2][mod_name][2].append(c)
+ else:
+ self._topics[topic_name][2][mod_name] = [doc, 0, [c]]
+ self._count_topic_mcl(topic_name, mod_name)
+ # count mcl for for the subtopic
+ mcl = max((self._topics[topic_name][2][mod_name][1], len(c.name)))
+ self._topics[topic_name][2][mod_name][1] = mcl
+ else:
+ self._topics[topic_name] = [topic[1], 0, {mod_name: [doc, 0, [c]]}]
+ self._count_topic_mcl(topic_name, mod_name)
else:
self._builtins.append(c)
@@ -647,6 +688,7 @@ class help(frontend.Local):
def run(self, key):
name = from_cli(key)
+ mod_name = '%s.%s' % (self._PLUGIN_BASE_MODULE, name)
if key is None or name == "topics":
self.print_topics()
return
@@ -656,6 +698,8 @@ class help(frontend.Local):
cmd = self.Command[name]
print 'Purpose: %s' % cmd.doc
self.Backend.cli.build_parser(cmd).print_help()
+ elif mod_name in sys.modules:
+ self.print_commands(name)
elif name == "commands":
mcl = max(len(s) for s in (self.Command))
for cname in self.Command:
@@ -673,28 +717,61 @@ class help(frontend.Local):
print ''
print 'Built-in commands:'
for c in self._builtins:
+ print 'Help subtopics:'
print ' %s %s' % (to_cli(c.name).ljust(self._mtl), c.summary)
print ''
print 'Help topics:'
for t in topics:
- m = '%s.%s' % (self._PLUGIN_BASE_MODULE, t)
- doc = (sys.modules[m].__doc__ or '').strip().split('\n', 1)[0]
- print ' %s %s' % (to_cli(t).ljust(self._mtl), doc)
+ topic = self._topics[t]
+ print ' %s %s' % (to_cli(t).ljust(self._mtl), topic[0])
+
+ if False:
+ topic_commands = self._topics[t][2]
+ mod_list = [self._get_command_module(c.module) for c in topic_commands]
+ mod_list = list(set(mod_list))
+
+ for mod in mod_list:
+ m = '%s.%s' % (self._PLUGIN_BASE_MODULE, mod)
+ if 'topic' in dir(sys.modules[m]):
+ doc = sys.modules[m].topic[1]
+ else:
+ doc = (sys.modules[m].__doc__ or '').strip().split('\n', 1)[0]
+ print ' %s %s' % (to_cli(t).ljust(self._mtl), doc)
print ''
print 'Try `ipa --help` for a list of global options.'
def print_commands(self, topic):
- mcl = self._topics[topic][0]
- commands = self._topics[topic][1:]
- m = '%s.%s' % (self._PLUGIN_BASE_MODULE, topic)
- doc = (sys.modules[m].__doc__ or '').strip()
+ if topic in self._topics and type(self._topics[topic][2]) is dict:
+ # we want to display topic which has subtopics
+ for subtopic in self._topics[topic][2]:
+ doc = self._topics[topic][2][subtopic][0]
+ mcl = self._topics[topic][1]
+ print ' %s %s' % (to_cli(subtopic).ljust(mcl), doc)
+ else:
+ # we want to display subtopic or a topic which has no subtopics
+ if topic in self._topics:
+ mcl = self._topics[topic][1]
+ commands = self._topics[topic][2]
+ else:
+ for t in self._topics:
+ if type(self._topics[t][2]) is not dict:
+ continue
+ if topic not in self._topics[t][2]:
+ continue
+ mcl = self._topics[t][2][topic][1]
+ commands = self._topics[t][2][topic][2]
+ break
+
+ m = '%s.%s' % (self._PLUGIN_BASE_MODULE, topic)
+ doc = (sys.modules[m].__doc__ or '').strip()
- print doc
- print ''
- if len(commands) > 1:
- print 'Topic commands:'
- for c in commands:
- print ' %s %s' % (to_cli(c.name).ljust(mcl), c.summary)
+ print doc
+ print ''
+ if len(commands) > 1:
+ print 'Topic commands:'
+ for c in commands:
+ print ' %s %s' % (to_cli(c.name).ljust(mcl), c.summary)
+ print "\n"
class console(frontend.Command):