101 строка
3.3 KiB
Python
Executable File
101 строка
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import yaml
|
|
import argparse
|
|
import hashlib
|
|
|
|
|
|
# pydoc-markdown -I . -m module_name --render_toc > doc.md
|
|
|
|
|
|
def hash_file(filename):
|
|
"""
|
|
Calculate the md5 hash of a file. Used to check for stale files.
|
|
|
|
:param filename: The name of the file to check
|
|
:type str:
|
|
:return: A string containing the md5 hash of the file
|
|
:rtype: str
|
|
"""
|
|
if os.path.exists(filename):
|
|
hasher = hashlib.md5()
|
|
with open(filename, "rb") as file_to_hash:
|
|
buffer = file_to_hash.read()
|
|
hasher.update(buffer)
|
|
return hasher.hexdigest()
|
|
else:
|
|
return 0
|
|
|
|
|
|
def remove_trailing_whitespace(filename):
|
|
"""
|
|
Removes trailing whitespace from a file.
|
|
|
|
:param filename: The name of the file to process
|
|
:type str:
|
|
"""
|
|
num_changed = 0
|
|
# open the source file
|
|
with open(filename, "rb") as f:
|
|
source_file = f.read().decode()
|
|
# grab all the lines, removing the trailing whitespace
|
|
lines = [line.rstrip() for line in source_file.splitlines()]
|
|
|
|
# process lines to construct destination file
|
|
while lines and not lines[-1]:
|
|
lines.pop(-1)
|
|
lines.append("")
|
|
destination_file = "\n".join(lines)
|
|
|
|
# compare source and destination and write only if changed
|
|
if source_file != destination_file:
|
|
num_changed += 1
|
|
with open(filename, "wb") as f:
|
|
f.write(destination_file.encode())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
"""
|
|
Pre-commit hook to generate Python API documentation using pydoc-markdown
|
|
and write as markdown files. Each package should have a config file,
|
|
pydoc-config.yaml, at the root level that provides configurations for
|
|
the generation. Fails if documentation was updated, passes otherwise. This
|
|
allows for pre-commit to fail in CI/CD and makes sure dev commits the doc
|
|
updates.
|
|
"""
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--package_dirs", nargs="+")
|
|
args = parser.parse_args()
|
|
|
|
ok = True
|
|
for package_dir in args.package_dirs:
|
|
config_path = os.path.join(os.getcwd(), package_dir, "pydoc-config.yaml")
|
|
print(config_path)
|
|
with open(config_path) as config_file:
|
|
config = yaml.full_load(config_file)
|
|
for module in config["modules"]:
|
|
module_name = module["name"]
|
|
submodules = module["submodules"]
|
|
output_file_name = f"./{config['folder']}/{module['file_name']}"
|
|
old_hash = hash_file(output_file_name)
|
|
module_args = []
|
|
for submodule in submodules:
|
|
module_args.append("-m")
|
|
module_args.append(f"{module_name}.{submodule}")
|
|
with open(output_file_name, "w") as output_file:
|
|
subprocess_args = [
|
|
"pydoc-markdown",
|
|
"-I",
|
|
f"./{package_dir}",
|
|
*module_args,
|
|
"--render-toc",
|
|
]
|
|
subprocess.check_call(subprocess_args, stdout=output_file)
|
|
remove_trailing_whitespace(output_file_name)
|
|
new_hash = hash_file(output_file_name)
|
|
ok &= old_hash == new_hash
|
|
|
|
sys.exit(0 if ok else 1)
|