mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add auto formatting for sphinx directives
This commit is contained in:
parent
aeb87a60fb
commit
510cd92a2e
1 changed files with 104 additions and 74 deletions
|
@ -45,25 +45,16 @@ def check(ctx, files, check_proper_formatting=False):
|
|||
errors = 0
|
||||
exitcode = 0
|
||||
for path in _files:
|
||||
module = ast.parse(path.read_text(), filename=str(path))
|
||||
module_docstring = ast.get_docstring(module)
|
||||
if module_docstring:
|
||||
error = _check_valid_versions_on_docstrings(module_docstring)
|
||||
if error:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The module '{}' does not provide a proper `{}` version: {!r} is not valid.",
|
||||
path.relative_to(CODE_DIR),
|
||||
*error,
|
||||
)
|
||||
|
||||
for funcdef in [
|
||||
node for node in module.body if isinstance(node, ast.FunctionDef)
|
||||
]:
|
||||
docstring = ast.get_docstring(funcdef)
|
||||
if docstring:
|
||||
error = _check_valid_versions_on_docstrings(docstring)
|
||||
contents = path.read_text()
|
||||
initial_contents = contents
|
||||
try:
|
||||
module = ast.parse(path.read_text(), filename=str(path))
|
||||
module_docstring = ast.get_docstring(module, clean=False)
|
||||
if module_docstring:
|
||||
new_module_docstring = _fix_directives_formatting(module_docstring)
|
||||
if module_docstring != new_module_docstring:
|
||||
contents = contents.replace(module_docstring, new_module_docstring)
|
||||
error = _check_valid_versions_on_docstrings(module_docstring)
|
||||
if error:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
|
@ -73,66 +64,87 @@ def check(ctx, files, check_proper_formatting=False):
|
|||
*error,
|
||||
)
|
||||
|
||||
if not str(path).startswith(SALT_INTERNAL_LOADERS_PATHS):
|
||||
# No further docstrings checks are needed
|
||||
continue
|
||||
for funcdef in [
|
||||
node for node in module.body if isinstance(node, ast.FunctionDef)
|
||||
]:
|
||||
docstring = ast.get_docstring(funcdef, clean=False)
|
||||
if docstring:
|
||||
new_docstring = _fix_directives_formatting(docstring)
|
||||
if docstring != new_docstring:
|
||||
contents = contents.replace(docstring, new_docstring)
|
||||
error = _check_valid_versions_on_docstrings(new_docstring)
|
||||
if error:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The module '{}' does not provide a proper `{}` version: {!r} is not valid.",
|
||||
path.relative_to(CODE_DIR),
|
||||
*error,
|
||||
)
|
||||
|
||||
# We're dealing with a salt loader module
|
||||
if funcdef.name.startswith("_"):
|
||||
# We're not interested in internal functions
|
||||
continue
|
||||
|
||||
if not docstring:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a docstring",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
|
||||
try:
|
||||
relpath = path.relative_to(SALT_MODULES_PATH)
|
||||
if str(relpath.parent) != ".":
|
||||
# We don't want to check nested packages
|
||||
if not str(path).startswith(SALT_INTERNAL_LOADERS_PATHS):
|
||||
# No further docstrings checks are needed
|
||||
continue
|
||||
# But this is a module under salt/modules, let's check
|
||||
# the CLI examples
|
||||
except ValueError:
|
||||
# We're not checking CLI examples in any other salt loader modules
|
||||
continue
|
||||
|
||||
if _check_cli_example_present(docstring) is False:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a 'CLI Example:' in it's docstring",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
# We're dealing with a salt loader module
|
||||
if funcdef.name.startswith("_"):
|
||||
# We're not interested in internal functions
|
||||
continue
|
||||
|
||||
if check_proper_formatting is False:
|
||||
continue
|
||||
if not docstring:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a docstring",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
|
||||
# By now we now this function has a docstring and it has a CLI Example section
|
||||
# Let's now check if it's properly formatted
|
||||
if _check_cli_example_proper_formatting(docstring) is False:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a proper 'CLI Example:' section in "
|
||||
"it's docstring. The proper format is:\n"
|
||||
"CLI Example:\n"
|
||||
"\n"
|
||||
".. code-block:: bash\n"
|
||||
"\n"
|
||||
" salt '*' <insert example here>\n",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
try:
|
||||
relpath = path.relative_to(SALT_MODULES_PATH)
|
||||
if str(relpath.parent) != ".":
|
||||
# We don't want to check nested packages
|
||||
continue
|
||||
# But this is a module under salt/modules, let's check
|
||||
# the CLI examples
|
||||
except ValueError:
|
||||
# We're not checking CLI examples in any other salt loader modules
|
||||
continue
|
||||
|
||||
if _check_cli_example_present(docstring) is False:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a 'CLI Example:' in it's docstring",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
|
||||
if check_proper_formatting is False:
|
||||
continue
|
||||
|
||||
# By now we now this function has a docstring and it has a CLI Example section
|
||||
# Let's now check if it's properly formatted
|
||||
if _check_cli_example_proper_formatting(docstring) is False:
|
||||
errors += 1
|
||||
exitcode = 1
|
||||
utils.error(
|
||||
"The function {!r} on '{}' does not have a proper 'CLI Example:' section in "
|
||||
"it's docstring. The proper format is:\n"
|
||||
"CLI Example:\n"
|
||||
"\n"
|
||||
".. code-block:: bash\n"
|
||||
"\n"
|
||||
" salt '*' <insert example here>\n",
|
||||
funcdef.name,
|
||||
path.relative_to(CODE_DIR),
|
||||
)
|
||||
continue
|
||||
finally:
|
||||
if contents != path.read_text():
|
||||
path.write_text(contents)
|
||||
|
||||
if exitcode:
|
||||
utils.error("Found {} errors", errors)
|
||||
|
@ -168,3 +180,21 @@ def _check_cli_example_proper_formatting(docstring):
|
|||
r"CLI Example(?:s)?:\n\n.. code-block:: bash\n\n salt (.*) '*'", re.MULTILINE
|
||||
)
|
||||
return good_cli_example_regex.search(docstring) is not None
|
||||
|
||||
|
||||
def _fix_directives_formatting(docstring):
|
||||
directive_regex = re.compile(
|
||||
r"^(?P<spc1>[ ]+)?((?P<dots>[.]{2,})(?P<spc2>[ ]+)?(?P<directive>([^ ]{1}).*))::(?P<remaining>.*)\n$"
|
||||
)
|
||||
output = []
|
||||
for line in docstring.splitlines(True):
|
||||
match = directive_regex.match(line)
|
||||
if match:
|
||||
line = "{}.. {}:: {}".format(
|
||||
match.group("spc1") or "",
|
||||
match.group("directive"),
|
||||
match.group("remaining").strip(),
|
||||
).rstrip()
|
||||
line += "\n"
|
||||
output.append(line)
|
||||
return "".join(output)
|
||||
|
|
Loading…
Add table
Reference in a new issue