|
|
|
# coding: utf-8
|
|
|
|
# Copyright: (c) 2019, Ansible Project
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
|
|
# Make coding more python3-ish
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import os.path
|
|
|
|
import pathlib
|
|
|
|
import sys
|
|
|
|
|
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
|
|
|
from ansible.module_utils._text import to_bytes
|
|
|
|
|
|
|
|
# Pylint doesn't understand Python3 namespace modules.
|
|
|
|
from ..change_detection import update_file_if_different # pylint: disable=relative-beyond-top-level
|
|
|
|
from ..commands import Command # pylint: disable=relative-beyond-top-level
|
|
|
|
|
|
|
|
|
|
|
|
DEFAULT_TEMPLATE_FILE = pathlib.Path(__file__).parents[4] / 'docs/templates/man.j2'
|
|
|
|
|
|
|
|
|
|
|
|
# from https://www.python.org/dev/peps/pep-0257/
|
|
|
|
def trim_docstring(docstring):
|
|
|
|
if not docstring:
|
|
|
|
return ''
|
|
|
|
# Convert tabs to spaces (following the normal Python rules)
|
|
|
|
# and split into a list of lines:
|
|
|
|
lines = docstring.expandtabs().splitlines()
|
|
|
|
# Determine minimum indentation (first line doesn't count):
|
Fix build on Python 3.x by using sys.maxsize. (#30424)
As outlined in https://docs.python.org/3.1/whatsnew/3.0.html#integers,
sys.maxint doesn't exist anymore in Python 3.x because there is no maximum
value for integers in Python 3.x. sys.maxsize is present in all
versions of Python that are currently supported by Ansible, so use that
instead as an arbitrarily large index value.
Fixes the following build error when building with Python 3.x:
make -j1 docs
mkdir -p ./docs/man/man1/ ; \
PYTHONPATH=./lib docs/bin/generate_man.py --template-file=docs/templates/man.j2 --output-dir=docs/man/man1/ --output-format man lib/ansible/cli/*.py
Traceback (most recent call last):
File "docs/bin/generate_man.py", line 253, in <module>
allvars[cli_name] = opts_docs(cli_class_name, cli_name)
File "docs/bin/generate_man.py", line 119, in opts_docs
'long_desc': trim_docstring(cli.__doc__),
File "docs/bin/generate_man.py", line 34, in trim_docstring
indent = sys.maxint
AttributeError: module 'sys' has no attribute 'maxint'
make: *** [Makefile:347: generate_asciidoc] Error 1
7 years ago
|
|
|
indent = sys.maxsize
|
|
|
|
for line in lines[1:]:
|
|
|
|
stripped = line.lstrip()
|
|
|
|
if stripped:
|
|
|
|
indent = min(indent, len(line) - len(stripped))
|
|
|
|
# Remove indentation (first line is special):
|
|
|
|
trimmed = [lines[0].strip()]
|
Fix build on Python 3.x by using sys.maxsize. (#30424)
As outlined in https://docs.python.org/3.1/whatsnew/3.0.html#integers,
sys.maxint doesn't exist anymore in Python 3.x because there is no maximum
value for integers in Python 3.x. sys.maxsize is present in all
versions of Python that are currently supported by Ansible, so use that
instead as an arbitrarily large index value.
Fixes the following build error when building with Python 3.x:
make -j1 docs
mkdir -p ./docs/man/man1/ ; \
PYTHONPATH=./lib docs/bin/generate_man.py --template-file=docs/templates/man.j2 --output-dir=docs/man/man1/ --output-format man lib/ansible/cli/*.py
Traceback (most recent call last):
File "docs/bin/generate_man.py", line 253, in <module>
allvars[cli_name] = opts_docs(cli_class_name, cli_name)
File "docs/bin/generate_man.py", line 119, in opts_docs
'long_desc': trim_docstring(cli.__doc__),
File "docs/bin/generate_man.py", line 34, in trim_docstring
indent = sys.maxint
AttributeError: module 'sys' has no attribute 'maxint'
make: *** [Makefile:347: generate_asciidoc] Error 1
7 years ago
|
|
|
if indent < sys.maxsize:
|
|
|
|
for line in lines[1:]:
|
|
|
|
trimmed.append(line[indent:].rstrip())
|
|
|
|
# Strip off trailing and leading blank lines:
|
|
|
|
while trimmed and not trimmed[-1]:
|
|
|
|
trimmed.pop()
|
|
|
|
while trimmed and not trimmed[0]:
|
|
|
|
trimmed.pop(0)
|
|
|
|
# Return a single string:
|
|
|
|
return '\n'.join(trimmed)
|
|
|
|
|
|
|
|
|
|
|
|
def get_options(optlist):
|
|
|
|
''' get actual options '''
|
|
|
|
|
|
|
|
opts = []
|
|
|
|
for opt in optlist:
|
|
|
|
res = {
|
|
|
|
'desc': opt.help,
|
|
|
|
'options': opt.option_strings
|
|
|
|
}
|
|
|
|
if isinstance(opt, argparse._StoreAction):
|
|
|
|
res['arg'] = opt.dest.upper()
|
|
|
|
elif not res['options']:
|
|
|
|
continue
|
|
|
|
opts.append(res)
|
|
|
|
|
|
|
|
return opts
|
|
|
|
|
|
|
|
|
|
|
|
def dedupe_groups(parser):
|
|
|
|
action_groups = []
|
|
|
|
for action_group in parser._action_groups:
|
|
|
|
found = False
|
|
|
|
for a in action_groups:
|
|
|
|
if a._actions == action_group._actions:
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
if not found:
|
|
|
|
action_groups.append(action_group)
|
|
|
|
return action_groups
|
|
|
|
|
|
|
|
|
|
|
|
def get_option_groups(option_parser):
|
|
|
|
groups = []
|
|
|
|
for action_group in dedupe_groups(option_parser)[1:]:
|
|
|
|
group_info = {}
|
|
|
|
group_info['desc'] = action_group.description
|
|
|
|
group_info['options'] = action_group._actions
|
|
|
|
group_info['group_obj'] = action_group
|
|
|
|
groups.append(group_info)
|
|
|
|
return groups
|
|
|
|
|
|
|
|
|
|
|
|
def opt_doc_list(parser):
|
|
|
|
''' iterate over options lists '''
|
|
|
|
|
|
|
|
results = []
|
|
|
|
for option_group in dedupe_groups(parser)[1:]:
|
|
|
|
results.extend(get_options(option_group._actions))
|
|
|
|
|
|
|
|
results.extend(get_options(parser._actions))
|
|
|
|
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
# def opts_docs(cli, name):
|
|
|
|
def opts_docs(cli_class_name, cli_module_name):
|
|
|
|
''' generate doc structure from options '''
|
|
|
|
|
|
|
|
cli_name = 'ansible-%s' % cli_module_name
|
|
|
|
if cli_module_name == 'adhoc':
|
|
|
|
cli_name = 'ansible'
|
|
|
|
|
|
|
|
# WIth no action/subcommand
|
|
|
|
# shared opts set
|
|
|
|
# instantiate each cli and ask its options
|
|
|
|
cli_klass = getattr(__import__("ansible.cli.%s" % cli_module_name,
|
|
|
|
fromlist=[cli_class_name]), cli_class_name)
|
|
|
|
cli = cli_klass([cli_name])
|
|
|
|
|
|
|
|
# parse the common options
|
|
|
|
try:
|
|
|
|
cli.init_parser()
|
|
|
|
except Exception:
|
|
|
|
pass
|
|
|
|
|
|
|
|
# base/common cli info
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
cli_options = opt_doc_list(cli.parser)
|
|
|
|
docs = {
|
|
|
|
'cli': cli_module_name,
|
|
|
|
'cli_name': cli_name,
|
|
|
|
'usage': cli.parser.format_usage(),
|
|
|
|
'short_desc': cli.parser.description,
|
|
|
|
'long_desc': trim_docstring(cli.__doc__),
|
|
|
|
'actions': {},
|
|
|
|
'content_depth': 2,
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
'options': cli_options,
|
|
|
|
'arguments': getattr(cli, 'ARGUMENTS', None),
|
|
|
|
}
|
|
|
|
option_info = {'option_names': [],
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
'options': cli_options,
|
|
|
|
'groups': []}
|
|
|
|
|
|
|
|
groups_info = get_option_groups(cli.parser)
|
|
|
|
shared_opt_names = []
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
for opt in cli_options:
|
|
|
|
shared_opt_names.extend(opt.get('options', []))
|
|
|
|
|
|
|
|
option_info['option_names'] = shared_opt_names
|
|
|
|
|
|
|
|
option_info['groups'].extend(groups_info)
|
|
|
|
|
|
|
|
docs.update(option_info)
|
|
|
|
|
|
|
|
# now for each action/subcommand
|
|
|
|
# force populate parser with per action options
|
|
|
|
|
|
|
|
def get_actions(parser, docs):
|
|
|
|
# use class attrs not the attrs on a instance (not that it matters here...)
|
|
|
|
try:
|
|
|
|
subparser = parser._subparsers._group_actions[0].choices
|
|
|
|
except AttributeError:
|
|
|
|
subparser = {}
|
|
|
|
|
|
|
|
depth = 0
|
|
|
|
|
|
|
|
for action, parser in subparser.items():
|
|
|
|
action_info = {'option_names': [],
|
|
|
|
'options': [],
|
|
|
|
'actions': {}}
|
|
|
|
# docs['actions'][action] = {}
|
|
|
|
# docs['actions'][action]['name'] = action
|
|
|
|
action_info['name'] = action
|
|
|
|
action_info['desc'] = trim_docstring(getattr(cli, 'execute_%s' % action).__doc__)
|
|
|
|
|
|
|
|
# docs['actions'][action]['desc'] = getattr(cli, 'execute_%s' % action).__doc__.strip()
|
|
|
|
action_doc_list = opt_doc_list(parser)
|
|
|
|
|
|
|
|
uncommon_options = []
|
|
|
|
for action_doc in action_doc_list:
|
|
|
|
# uncommon_options = []
|
|
|
|
|
|
|
|
option_aliases = action_doc.get('options', [])
|
|
|
|
for option_alias in option_aliases:
|
|
|
|
|
|
|
|
if option_alias in shared_opt_names:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# TODO: use set
|
|
|
|
if option_alias not in action_info['option_names']:
|
|
|
|
action_info['option_names'].append(option_alias)
|
|
|
|
|
|
|
|
if action_doc in action_info['options']:
|
|
|
|
continue
|
|
|
|
|
|
|
|
uncommon_options.append(action_doc)
|
|
|
|
|
|
|
|
action_info['options'] = uncommon_options
|
|
|
|
|
|
|
|
depth = 1 + get_actions(parser, action_info)
|
|
|
|
|
|
|
|
docs['actions'][action] = action_info
|
|
|
|
|
|
|
|
return depth
|
|
|
|
|
|
|
|
action_depth = get_actions(cli.parser, docs)
|
|
|
|
docs['content_depth'] = action_depth + 1
|
|
|
|
|
|
|
|
return docs
|
|
|
|
|
|
|
|
|
|
|
|
class GenerateMan(Command):
|
|
|
|
name = 'generate-man'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def init_parser(cls, add_parser):
|
|
|
|
parser = add_parser(name=cls.name,
|
|
|
|
description='Generate cli documentation from cli docstrings')
|
|
|
|
|
|
|
|
parser.add_argument("-t", "--template-file", action="store", dest="template_file",
|
|
|
|
default=DEFAULT_TEMPLATE_FILE, help="path to jinja2 template")
|
|
|
|
parser.add_argument("-o", "--output-dir", action="store", dest="output_dir",
|
|
|
|
default='/tmp/', help="Output directory for rst files")
|
|
|
|
parser.add_argument("-f", "--output-format", action="store", dest="output_format",
|
|
|
|
default='man',
|
|
|
|
help="Output format for docs (the default 'man' or 'rst')")
|
|
|
|
parser.add_argument('cli_modules', help='CLI module name(s)', metavar='MODULE_NAME', nargs='*')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def main(args):
|
|
|
|
template_file = args.template_file
|
|
|
|
template_path = os.path.expanduser(template_file)
|
|
|
|
template_dir = os.path.abspath(os.path.dirname(template_path))
|
|
|
|
template_basename = os.path.basename(template_file)
|
|
|
|
|
|
|
|
output_dir = os.path.abspath(args.output_dir)
|
|
|
|
output_format = args.output_format
|
|
|
|
|
|
|
|
cli_modules = args.cli_modules
|
|
|
|
|
|
|
|
# various cli parsing things checks sys.argv if the 'args' that are passed in are []
|
|
|
|
# so just remove any args so the cli modules dont try to parse them resulting in warnings
|
|
|
|
sys.argv = [sys.argv[0]]
|
|
|
|
|
|
|
|
allvars = {}
|
|
|
|
output = {}
|
|
|
|
cli_list = []
|
|
|
|
cli_bin_name_list = []
|
|
|
|
|
|
|
|
# for binary in os.listdir('../../lib/ansible/cli'):
|
|
|
|
for cli_module_name in cli_modules:
|
|
|
|
binary = os.path.basename(os.path.expanduser(cli_module_name))
|
|
|
|
|
|
|
|
if not binary.endswith('.py'):
|
|
|
|
continue
|
|
|
|
elif binary == '__init__.py':
|
|
|
|
continue
|
|
|
|
|
|
|
|
cli_name = os.path.splitext(binary)[0]
|
|
|
|
|
|
|
|
if cli_name == 'adhoc':
|
|
|
|
cli_class_name = 'AdHocCLI'
|
|
|
|
# myclass = 'AdHocCLI'
|
|
|
|
output[cli_name] = 'ansible.1.rst.in'
|
|
|
|
cli_bin_name = 'ansible'
|
|
|
|
else:
|
|
|
|
# myclass = "%sCLI" % libname.capitalize()
|
|
|
|
cli_class_name = "%sCLI" % cli_name.capitalize()
|
|
|
|
output[cli_name] = 'ansible-%s.1.rst.in' % cli_name
|
|
|
|
cli_bin_name = 'ansible-%s' % cli_name
|
|
|
|
|
|
|
|
# FIXME:
|
|
|
|
allvars[cli_name] = opts_docs(cli_class_name, cli_name)
|
|
|
|
cli_bin_name_list.append(cli_bin_name)
|
|
|
|
|
|
|
|
cli_list = allvars.keys()
|
|
|
|
|
|
|
|
doc_name_formats = {'man': '%s.1.rst.in',
|
|
|
|
'rst': '%s.rst'}
|
|
|
|
|
|
|
|
for cli_name in cli_list:
|
|
|
|
|
|
|
|
# template it!
|
|
|
|
env = Environment(loader=FileSystemLoader(template_dir))
|
|
|
|
template = env.get_template(template_basename)
|
|
|
|
|
|
|
|
# add rest to vars
|
|
|
|
tvars = allvars[cli_name]
|
|
|
|
tvars['cli_bin_name_list'] = cli_bin_name_list
|
|
|
|
tvars['cli'] = cli_name
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
if '-i' in tvars['option_names']:
|
|
|
|
tvars['inventory'] = True
|
|
|
|
print('uses inventory')
|
Fix misrendered sections in manpage generation
This change fixes bugs in the manpage generator that existed since it
was first added.
It exposes CLI `ARGUMENTS` value to manpage templates.
Before this change, the code contained a typo, causing the `for`-loop
iterate over individual characters of the `'ARGUMENTS'` string rather
than iterating over a tuple. A missing comma was at fault.
The updated code gets rid of the `for`-loop and conditionals since it
seems to have been a premature complexity increase and no other things
than `'ARGUMENTS'` were ever added into the broken iterable.
The functional change is that `arguments` is now always present in the
Jinja2 context, unlike being missing sometimes because of the previous
design (not that it was ever present, because of the bug! sigh...)
The Jinja2 templates perform an `{% if arguments %}` check, letting
the template engine silently ignore the missing variable. The clause
was always falsy, meaning that the arguments section was not included
in the manpages for at least the last 6 years. With this fix, it will
be.
This patch also deduplicates calling `opt_doc_list` @ generate_man.
It was called late in the execution, more times than necessary. This
patch makes sure it happens once by putting it at the top of the scope.
It fixes rendering library and inventory in manpages.
The corresponding Jinja2 templates have blocks wrapped with
conditionals like `{% if inventory %}` and `{% if library %}` but said
variables were never injected into the context, nor were they even
deduced on the Python side of the generator. This means that the
conditional clauses were always falsy, never showing the portions of
the manpages.
The Python script has hints for how the `inventory` variable was to be
calculated, which is confirmed through the Git paleontology efforts.
The block of code that references to the `inventory` bit was
incorrectly checking a variable with a list of nested objects for the
presence of a string which was never going to work.
This patch fixes this check by verifying the CLI flag against the
correct variable containing a list of options and exposes it to the
Jinja2 templates.
It also exposes the `library` variable in a similar way.
The block displaying other binaries in Sphinx CLI docs has been
synchronized with the manpage template.
Previously, the current binary was displayed also. This patch gets rid
of the unwanted trailing comma there too.
Finally, the CLI executables list in the manpage template now reuses
the same variable as the RST template that doesn't need any
post-processing in Jinja2.
Before, it was already used in the RST template so this patch aligns
both templates to use the same logic as they got out-of-sync over time.
PR #80450.
2 years ago
|
|
|
if '-M' in tvars['option_names']:
|
|
|
|
tvars['library'] = True
|
|
|
|
print('uses library')
|
|
|
|
|
|
|
|
manpage = template.render(tvars)
|
|
|
|
filename = os.path.join(output_dir, doc_name_formats[output_format] % tvars['cli_name'])
|
|
|
|
update_file_if_different(filename, to_bytes(manpage))
|