From d516fa012a8c66c9109a4ff6d07fba2b423b78d7 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Tue, 10 Sep 2019 14:00:39 -0700 Subject: [PATCH 2/2] More cleanups of the ansible-doc code * Standardize key names on "examples" and "return" as used in the public json output rather than sometimes using "plainexamples" and "returndocs" * Split creating new data from formatting the doc data. * Output the same data to both text and json output * Treat documentation extracted from the plugin as read-only in the formatting functions --- lib/ansible/cli/doc.py | 112 ++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/lib/ansible/cli/doc.py b/lib/ansible/cli/doc.py index d5baa8499b2..c49aa1ce793 100644 --- a/lib/ansible/cli/doc.py +++ b/lib/ansible/cli/doc.py @@ -51,7 +51,7 @@ class DocCLI(CLI): and it can create a short "snippet" which can be pasted into a playbook. ''' # default ignore list for detailed views - IGNORE = ('module', 'docuri', 'version_added', 'short_description', 'now_date', 'plainexamples', 'returndocs') + IGNORE = ('module', 'docuri', 'version_added', 'short_description', 'now_date', 'examples', 'return') def __init__(self, args): @@ -209,26 +209,33 @@ class DocCLI(CLI): # The doc section existed but was empty continue + try: + returndocs = yaml.safe_load(returndocs) + except Exception: + pass + + # generate extra data + if plugin_type == 'module': + # is there corresponding action plugin? + if plugin in action_loader: + doc['action'] = True + else: + doc['action'] = False + + doc['now_date'] = datetime.date.today().strftime('%Y-%m-%d') + if 'docuri' in doc: + doc['docuri'] = doc[plugin_type].replace('_', '-') + plugin_docs[plugin] = {'doc': doc, 'examples': plainexamples, 'return': returndocs, 'metadata': metadata} if do_json: - # Some changes to how json docs are formatted - for plugin, doc_data in plugin_docs.items(): - try: - doc_data['return'] = yaml.load(doc_data['return']) - except Exception: - pass - jdump(plugin_docs) - else: # Some changes to how plain text docs are formatted text = [] for plugin, doc_data in plugin_docs.items(): - textret = DocCLI.format_plugin_doc(plugin, plugin_type, - doc_data['doc'], doc_data['examples'], - doc_data['return'], doc_data['metadata']) + textret = DocCLI.format_plugin_doc(plugin, plugin_type, doc_data) if textret: text.append(textret) @@ -313,24 +320,7 @@ class DocCLI(CLI): return doc, plainexamples, returndocs, metadata @staticmethod - def format_plugin_doc(plugin, plugin_type, doc, plainexamples, returndocs, metadata): - # assign from other sections - doc['plainexamples'] = plainexamples - doc['returndocs'] = returndocs - doc['metadata'] = metadata - - # generate extra data - if plugin_type == 'module': - # is there corresponding action plugin? - if plugin in action_loader: - doc['action'] = True - else: - doc['action'] = False - - doc['now_date'] = datetime.date.today().strftime('%Y-%m-%d') - if 'docuri' in doc: - doc['docuri'] = doc[plugin_type].replace('_', '-') - + def format_plugin_doc(plugin, plugin_type, doc): if context.CLIARGS['show_snippet'] and plugin_type == 'module': text = DocCLI.get_snippet_text(doc) else: @@ -446,7 +436,8 @@ class DocCLI(CLI): return os.pathsep.join(ret) @staticmethod - def get_snippet_text(doc): + def get_snippet_text(plugin_data): + doc = plugin_data['doc'] # Convenient alias text = [] desc = DocCLI.tty_ify(doc['short_description']) @@ -580,20 +571,27 @@ class DocCLI(CLI): return text @staticmethod - def get_man_text(doc): + def get_man_text(plugin_data): + doc = plugin_data['doc'] # Convenient alias + # Add the plugin type to the IGNORE list as the plugin name gets placed into the doc + # under this key but we don't want to display it as generic information DocCLI.IGNORE = DocCLI.IGNORE + (context.CLIARGS['type'],) + processed = set(DocCLI.IGNORE) + opt_indent = " " text = [] pad = display.columns * 0.20 limit = max(display.columns - int(pad), 70) - text.append("> %s (%s)\n" % (doc.get(context.CLIARGS['type'], doc.get('plugin_type')).upper(), doc.pop('filename'))) + text.append("> %s (%s)\n" % (doc.get(context.CLIARGS['type'], doc.get('plugin_type')).upper(), doc['filename'])) + processed.add('filename') if isinstance(doc['description'], list): - desc = " ".join(doc.pop('description')) + desc = " ".join(doc['description']) else: - desc = doc.pop('description') + desc = doc['description'] + processed.add('description') text.append("%s\n" % textwrap.fill(DocCLI.tty_ify(desc), limit, initial_indent=opt_indent, subsequent_indent=opt_indent)) @@ -603,25 +601,28 @@ class DocCLI(CLI): if isinstance(doc['deprecated'], dict): if 'version' in doc['deprecated'] and 'removed_in' not in doc['deprecated']: doc['deprecated']['removed_in'] = doc['deprecated']['version'] - text.append("\tReason: %(why)s\n\tWill be removed in: Ansible %(removed_in)s\n\tAlternatives: %(alternative)s" % doc.pop('deprecated')) + text.append("\tReason: %(why)s\n\tWill be removed in: Ansible %(removed_in)s\n\tAlternatives: %(alternative)s" % doc['deprecated']) else: - text.append("%s" % doc.pop('deprecated')) + text.append("%s" % doc['deprecated']) text.append("\n") + processed.add('deprecated') try: - support_block = DocCLI.get_support_block(doc) + support_block = DocCLI.get_support_block(plugin_data) if support_block: text.extend(support_block) except Exception: pass # FIXME: not suported by plugins - if doc.pop('action', False): + if doc.get('action', False): text.append(" * note: %s\n" % "This module has a corresponding action plugin.") + processed.add('action') if 'options' in doc and doc['options']: text.append("OPTIONS (= is mandatory):\n") - DocCLI.add_fields(text, doc.pop('options'), limit, opt_indent) + DocCLI.add_fields(text, doc['options'], limit, opt_indent) text.append('') + processed.add('options') if 'notes' in doc and doc['notes'] and len(doc['notes']) > 0: text.append("NOTES:") @@ -630,7 +631,7 @@ class DocCLI(CLI): initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent)) text.append('') text.append('') - del doc['notes'] + processed.add('notes') if 'seealso' in doc and doc['seealso']: text.append("SEE ALSO:") @@ -659,45 +660,44 @@ class DocCLI(CLI): text.append('') text.append('') - del doc['seealso'] + processed.add('seealso') if 'requirements' in doc and doc['requirements'] is not None and len(doc['requirements']) > 0: - req = ", ".join(doc.pop('requirements')) + req = ", ".join(doc['requirements']) text.append("REQUIREMENTS:%s\n" % textwrap.fill(DocCLI.tty_ify(req), limit - 16, initial_indent=" ", subsequent_indent=opt_indent)) + processed.add('requirements') # Generic handler - for k in sorted(doc): - if k in DocCLI.IGNORE or not doc[k]: - continue + for k in sorted(key for key in doc if key not in processed and doc[key]): if isinstance(doc[k], string_types): text.append('%s: %s' % (k.upper(), textwrap.fill(DocCLI.tty_ify(doc[k]), limit - (len(k) + 2), subsequent_indent=opt_indent))) elif isinstance(doc[k], (list, tuple)): text.append('%s: %s' % (k.upper(), ', '.join(doc[k]))) else: text.append(DocCLI._dump_yaml({k.upper(): doc[k]}, opt_indent)) - del doc[k] text.append('') - if 'plainexamples' in doc and doc['plainexamples'] is not None: + if 'examples' in plugin_data and plugin_data['examples'] is not None: text.append("EXAMPLES:") text.append('') - if isinstance(doc['plainexamples'], string_types): - text.append(doc.pop('plainexamples').strip()) + if isinstance(plugin_data['examples'], string_types): + text.append(plugin_data.pop('examples').strip()) else: - text.append(yaml.dump(doc.pop('plainexamples'), indent=2, default_flow_style=False)) + text.append(yaml.dump(plugin_data['examples'], indent=2, default_flow_style=False)) text.append('') text.append('') - if 'returndocs' in doc and doc['returndocs'] is not None: + if 'return' in plugin_data and plugin_data['return'] is not None: text.append("RETURN VALUES:") - if isinstance(doc['returndocs'], string_types): - text.append(doc.pop('returndocs')) + if isinstance(plugin_data['return'], string_types): + text.append(plugin_data['return']) else: - text.append(yaml.dump(doc.pop('returndocs'), indent=2, default_flow_style=False)) + text.append(yaml.dump(plugin_data['return'], indent=2, default_flow_style=False)) + text.append('') try: - metadata_block = DocCLI.get_metadata_block(doc) + metadata_block = DocCLI.get_metadata_block(plugin_data) if metadata_block: text.extend(metadata_block) text.append('') -- 2.20.1