google styled doc string and create README.md using package doc string

This commit is contained in:
2026-02-28 19:56:58 +05:30
parent f8ca6075fb
commit 219d6f9f87
9 changed files with 212 additions and 41 deletions

View File

@@ -7,6 +7,7 @@ and mkdocstrings, ensuring:
- Root index.md always exists
- Parent package indexes are created automatically
- Child modules are linked in parent index files
- README.md can be generated from the root package docstring
"""
from pathlib import Path
@@ -35,9 +36,14 @@ class MkDocsRenderer:
provided Project models.
Args:
project: The project models to render.
out_dir: Target directory for documentation files.
module_is_source: Module is the source folder and to be treated as the root folder.
project:
The project model to render.
out_dir:
Target directory for generated Markdown.
module_is_source:
If True, treat the module as the root folder.
"""
out_dir.mkdir(parents=True, exist_ok=True)
self._ensure_root_index(project, out_dir)
@@ -59,9 +65,75 @@ class MkDocsRenderer:
module_is_source,
)
def generate_readme(
self,
project: Project,
docs_dir: Path,
module_is_source: bool | None = None,
) -> None:
"""
Generate README.md from the root package docstring.
Behavior:
- If module_is_source is True:
README.md is generated at project root (docs_dir.parent)
- If module_is_source is False:
TODO: generate README.md inside respective module folders
"""
# -------------------------
# Only implement source-root mode
# -------------------------
if not module_is_source:
# TODO: support per-module README generation
return
readme_path = docs_dir.parent / "README.md"
root_module = None
for module in project.get_all_modules():
if module.path == project.name:
root_module = module
break
if root_module is None:
return
doc = ""
if root_module.docstring:
doc = getattr(
root_module.docstring,
"value",
str(root_module.docstring),
)
content = (
f"# {project.name}\n\n"
f"{doc.strip()}\n"
)
if not readme_path.exists() or readme_path.read_text(encoding="utf-8") != content:
readme_path.write_text(
content,
encoding="utf-8",
)
# -------------------------
# Internal helpers
# -------------------------
def _find_root_module(self, project: Project) -> Module | None:
"""
Find the root module matching the project name.
"""
for module in project.get_all_modules():
if module.path == project.name:
return module
return None
def _write_module(
self,
module: Module,
@@ -79,6 +151,7 @@ class MkDocsRenderer:
out_dir: The base output directory.
module_is_source: Module is the source folder and to be treated as the root folder.
"""
parts = module.path.split(".")
if module_is_source:
@@ -90,12 +163,15 @@ class MkDocsRenderer:
# Package → directory/index.md
dir_path = out_dir.joinpath(*parts)
dir_path.mkdir(parents=True, exist_ok=True)
md_path = dir_path / "index.md"
link_target = f"{parts[-1]}/" if parts else None
else:
# Leaf module → parent_dir/<name>.md
dir_path = out_dir.joinpath(*parts[:-1])
dir_path.mkdir(parents=True, exist_ok=True)
md_path = dir_path / f"{parts[-1]}.md"
link_target = f"{parts[-1]}.md" if parts else None
@@ -127,7 +203,7 @@ class MkDocsRenderer:
def _ensure_root_index(
self,
project: Project,
out_dir: Path
out_dir: Path,
) -> None:
root_index = out_dir / "index.md"
@@ -147,14 +223,11 @@ class MkDocsRenderer:
) -> None:
if len(parts) == 1:
parent_index = out_dir / "index.md"
link = f"- [{title}]({link_target})\n"
else:
parent_dir = out_dir.joinpath(*parts[:-1])
parent_dir.mkdir(parents=True, exist_ok=True)
parent_index = parent_dir / "index.md"
link = f"- [{title}]({link_target})\n"
if not parent_index.exists():
parent_title = parts[-2].replace("_", " ").title()
parent_index.write_text(
@@ -164,5 +237,6 @@ class MkDocsRenderer:
content = parent_index.read_text(encoding="utf-8")
link = f"- [{title}]({link_target})\n"
if link not in content:
parent_index.write_text(content + link, encoding="utf-8")