diff --git a/builder/builder-tools/generate_api_docs.py b/builder/builder-tools/generate_api_docs.py index c4bb17b..a6516ec 100644 --- a/builder/builder-tools/generate_api_docs.py +++ b/builder/builder-tools/generate_api_docs.py @@ -3,11 +3,10 @@ import sys import pydoc import logging -#from pathlib import Path - current_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(0, os.path.realpath(os.path.join(current_dir, os.pardir, os.pardir))) + class DocsGenerator: def __init__(self, links_raltive_path="", @@ -22,19 +21,24 @@ class DocsGenerator: self.class_header = class_header self.function_header = function_header - def get_full_markdown(self, module): - output = [self.module_header.format(module.__name__)] + def get_full_markdown(self, module, links_path): + output = [self.module_header.format( + "[{}]({})".format( + module.__name__, + links_path + )) + ] if module.__doc__: output.append(module.__doc__) output.append(self.functions_header) - output.extend(self.get_functions(module)) - output.extend(self.get_classes(module)) + output.extend(self.get_functions(module, links_path)) + output.extend(self.get_classes(module, links_path)) return output - def get_classes(self, item): + def get_classes(self, item, links_path): output = list() for cls_name, cls in pydoc.inspect.getmembers(item, pydoc.inspect.isclass): if cls_name.startswith("_") or cls_name == "__class__": @@ -42,14 +46,20 @@ class DocsGenerator: if cls.__module__ != item.__name__: continue - output.append(self.class_header.format(cls_name)) + output.append(self.class_header.format( + "[{}]({}#L{})".format( + cls_name, + links_path, + pydoc.inspect.getsourcelines(cls)[1] # get source code line + )) + ) output.append(pydoc.inspect.getdoc(cls) or '...') # Get the docstring - output.extend(self.get_functions(cls)) # Get the functions - output.extend(self.get_classes(cls)) # Recurse into any subclasses + output.extend(self.get_functions(cls, links_path)) # Get the functions + output.extend(self.get_classes(cls, links_path)) # Recurse into any subclasses output.append('\n') return output - def get_functions(self, item): + def get_functions(self, item, links_path): output = [] for func_name, func in pydoc.inspect.getmembers(item, pydoc.inspect.isfunction): if func_name.startswith('_') and func_name != '__init__': @@ -57,12 +67,17 @@ class DocsGenerator: # if func.__module__ != item.__name__: # continue - output.append(self.function_header.format(func_name.replace('_', '\\_'))) + output.append(self.function_header.format( + "[{}]({}#L{})".format( + func_name.replace('_', '\\_'), + links_path, + pydoc.inspect.getsourcelines(func)[1] # get source code line + )) + ) output.append('```py') output.append(f'def {func_name}{pydoc.inspect.signature(func)}') output.append('```') - # print(pydoc.inspect.getsourcelines(func[1])) output.append(pydoc.inspect.getdoc(func) or "") # get the docstring @@ -71,7 +86,6 @@ class DocsGenerator: def generate_docs(self, module_import_path, output_path): try: module = pydoc.safeimport(module_import_path) - # print(module.__file__) if module is None: logging.error("Module not found") @@ -79,7 +93,10 @@ class DocsGenerator: except pydoc.ErrorDuringImport as e: logging.error(f"Error while trying to import {module_import_path}: {e}") else: - docs = self.get_full_markdown(module) + relpath = os.path.sep.join( + os.path.relpath(module.__file__, output_path).split(os.path.sep)[1:] + ) + docs = self.get_full_markdown(module, relpath) with open(output_path, 'w') as f: for line in docs: f.write(line.replace("\n", os.linesep) + '\n') @@ -88,7 +105,10 @@ class DocsGenerator: if __name__ == '__main__': modules_list = [ "lib.messaging", + "drone.modules.client_core", ] gen = DocsGenerator() for module in modules_list: - gen.generate_docs(module, os.path.realpath(os.path.join("msg.md"))) + name = module[module.rfind('.') + 1::] + gen.generate_docs(module, os.path.realpath( + os.path.join(current_dir, os.pardir, os.pardir, "docs", "en", "api", f"{name}.md")))