From 4393940a412d9a113ad58f5d1c9b88dba08bd094 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Thu, 12 Sep 2019 02:08:52 +0200 Subject: [PATCH] Docs formatting: recursively preprocess suboptions (#61900) * Simplify code, move option massaging code into own function. * Process suboptions recursively. --- .../command_plugins/plugin_formatter.py | 74 +++++++++++-------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py b/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py index 1d2ed459f8..446e6d281d 100644 --- a/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py +++ b/hacking/build_library/build_ansible/command_plugins/plugin_formatter.py @@ -346,6 +346,47 @@ def too_old(added): return added_float < TOO_OLD_TO_BE_NOTABLE +def process_options(module, options): + option_names = [] + + if options: + for (k, v) in iteritems(options): + # Error out if there's no description + if 'description' not in v: + raise AnsibleError("Missing required description for parameter '%s' in '%s' " % (k, module)) + + # Make sure description is a list of lines for later formatting + if isinstance(v['description'], string_types): + v['description'] = [v['description']] + elif not isinstance(v['description'], (list, tuple)): + raise AnsibleError("Invalid type for options['%s']['description']." + " Must be string or list of strings. Got %s" % + (k, type(v['description']))) + + # Error out if required isn't a boolean (people have been putting + # information on when something is required in here. Those need + # to go in the description instead). + required_value = v.get('required', False) + if not isinstance(required_value, bool): + raise AnsibleError("Invalid required value '%s' for parameter '%s' in '%s' (must be truthy)" % (required_value, k, module)) + + # Strip old version_added information for options + if 'version_added' in v and too_old(v['version_added']): + del v['version_added'] + + if 'suboptions' in v and v['suboptions']: + if isinstance(v['suboptions'], dict): + process_options(module, v['suboptions']) + elif isinstance(v['suboptions'][0], dict): + process_options(module, v['suboptions'][0]) + + option_names.append(k) + + option_names.sort() + + return option_names + + def process_plugins(module_map, templates, outputname, output_dir, ansible_version, plugin_type): for module_index, module in enumerate(module_map): @@ -417,38 +458,7 @@ def process_plugins(module_map, templates, outputname, output_dir, ansible_versi if too_old(added): del doc['version_added'] - option_names = [] - - if 'options' in doc and doc['options']: - for (k, v) in iteritems(doc['options']): - # Error out if there's no description - if 'description' not in doc['options'][k]: - raise AnsibleError("Missing required description for parameter '%s' in '%s' " % (k, module)) - - # Make sure description is a list of lines for later formatting - if isinstance(doc['options'][k]['description'], string_types): - doc['options'][k]['description'] = [doc['options'][k]['description']] - elif not isinstance(doc['options'][k]['description'], (list, tuple)): - raise AnsibleError("Invalid type for options['%s']['description']." - " Must be string or list of strings. Got %s" % - (k, type(doc['options'][k]['description']))) - - # Error out if required isn't a boolean (people have been putting - # information on when something is required in here. Those need - # to go in the description instead). - required_value = doc['options'][k].get('required', False) - if not isinstance(required_value, bool): - raise AnsibleError("Invalid required value '%s' for parameter '%s' in '%s' (must be truthy)" % (required_value, k, module)) - - # Strip old version_added information for options - if 'version_added' in doc['options'][k] and too_old(doc['options'][k]['version_added']): - del doc['options'][k]['version_added'] - - option_names.append(k) - - option_names.sort() - - doc['option_keys'] = option_names + doc['option_keys'] = process_options(module, doc.get('options')) doc['filename'] = fname doc['source'] = module_map[module]['source'] doc['docuri'] = doc['module'].replace('_', '-')