You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mipac/doc_gen.py

112 lines
3.7 KiB

import os
import importlib
import inspect
from pathlib import PurePath
import subprocess
from typing import TypedDict
def get_defined_functions_and_classes(module):
functions = []
classes = []
for name, obj in inspect.getmembers(module):
if inspect.isfunction(obj) and obj.__module__ == module.__name__:
functions.append(name)
elif inspect.isclass(obj) and obj.__module__ == module.__name__:
classes.append(name)
return functions, classes
class IGenerateSphinx(TypedDict):
module_path: PurePath
module_name: str
functions: list[str]
classes: list[str]
def generate_sphinx_output(data: list[IGenerateSphinx]):
output = []
output.append("API Reference\n===============\n")
tmp = {}
for i in hierarchy.values():
tmp[i] = []
# tmp[i].append(f"{i}\n{'-'*len(i)}")
tmp["__OTHER"] = []
def add_data(_data: IGenerateSphinx, add_to: list):
if _data["functions"]:
for function in _data["functions"]:
add_to.append(f"\n{function}\n" + "~" * len(function))
add_to.append(f".. autofunction:: {_data['module_name']}.{function}")
if _data["classes"]:
for class_name in _data["classes"]:
add_to.append(f"\n{class_name}\n" + "~" * len(class_name))
full_class_name = f"{_data['module_name']}.{class_name}"
add_to.append(f".. attributetable:: {full_class_name}")
add_to.append(f".. autoclass:: {full_class_name}\n :members:")
for i in data:
add_to = "__OTHER"
for category in hierarchy.keys():
if PurePath(category).as_posix() in i["module_path"].as_posix():
add_to = hierarchy[category]
add_data(i, tmp[add_to])
for k, v in tmp.items():
output.append(f"{k}\n{'-'*len(k)}")
output.append("\n\n".join(v))
return "\n".join(output)
def generate_documentation(base_path, output_file, hierarchy, exclude_files=[]):
documentation = []
items: list[IGenerateSphinx] = []
for file in [
{"filename": file, "root": root}
for root, dirs, files in os.walk(base_path)
if root != "__pycache__"
for file in files
]:
if file["filename"].endswith(".py") and file["filename"] not in exclude_files:
module_path = os.path.join(file["root"], file["filename"])
module_import_path = module_path.replace(os.path.sep, ".").replace(".py", "")
module = importlib.import_module(module_import_path)
functions, classes = get_defined_functions_and_classes(module)
if functions or classes:
items.append(
{
"module_path": PurePath(module_path),
"module_name": module_import_path,
"functions": functions,
"classes": classes,
}
)
doc_content = generate_sphinx_output(items)
documentation.append(doc_content)
with open(output_file, "w", encoding="utf-8") as doc_file:
doc_file.write("\n\n".join(documentation))
if __name__ == "__main__":
hierarchy = {
"mipac/models": "Misskey Models",
"mipac/manager": "Managers",
"mipac/actions": "Actions",
"mipac/types": "Type class",
"mipac/errors": "Errors",
}
source_path = "mipac"
output_path = "docs/index.rst"
excluded_files = ["__init__.py", "_version.py"] # Add files to exclude here
generate_documentation(source_path, output_path, hierarchy, exclude_files=excluded_files)
os.chdir("./docs")
subprocess.run(
"make gettext && sphinx-intl update -p _build/gettext && ./doc_builder.sh", shell=True
)