160 lines
4.3 KiB
Python
160 lines
4.3 KiB
Python
"""
|
|
MkDocs documentation management CLI.
|
|
|
|
This script provides a proper CLI interface to:
|
|
- Generate MkDocs Markdown files with mkdocstrings directives
|
|
- Build the documentation site
|
|
- Serve the documentation site locally
|
|
|
|
All operations are performed by calling MkDocs as a Python library
|
|
(no shell command invocation).
|
|
|
|
Requirements:
|
|
- mkdocs
|
|
- mkdocs-material
|
|
- mkdocstrings[python]
|
|
|
|
Usage:
|
|
python manage_docs.py generate
|
|
python manage_docs.py build
|
|
python manage_docs.py serve
|
|
|
|
Optional flags:
|
|
--docs-dir PATH Path to docs directory (default: ./docs)
|
|
--package-root NAME Root Python package name (default: mail_intake)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from mkdocs.commands import build as mkdocs_build
|
|
from mkdocs.commands import serve as mkdocs_serve
|
|
from mkdocs.config import load_config
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent
|
|
DEFAULT_DOCS_DIR = PROJECT_ROOT / "docs"
|
|
DEFAULT_PACKAGE_ROOT = "mail_intake"
|
|
MKDOCS_YML = PROJECT_ROOT / "mkdocs.yml"
|
|
|
|
|
|
def generate_docs_from_nav(
|
|
project_root: Path,
|
|
docs_root: Path,
|
|
package_root: str,
|
|
) -> None:
|
|
"""
|
|
Create and populate MkDocs Markdown files with mkdocstrings directives.
|
|
|
|
This function:
|
|
- Walks the Python package structure
|
|
- Mirrors it under the docs directory
|
|
- Creates missing .md files
|
|
- Creates index.md for packages (__init__.py)
|
|
- Overwrites content with ::: package.module
|
|
|
|
Examples:
|
|
mail_intake/__init__.py -> docs/mail_intake/index.md
|
|
mail_intake/config.py -> docs/mail_intake/config.md
|
|
mail_intake/adapters/__init__.py -> docs/mail_intake/adapters/index.md
|
|
mail_intake/adapters/base.py -> docs/mail_intake/adapters/base.md
|
|
"""
|
|
|
|
package_dir = project_root / package_root
|
|
if not package_dir.exists():
|
|
raise FileNotFoundError(f"Package not found: {package_dir}")
|
|
|
|
docs_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
for py_file in package_dir.rglob("*.py"):
|
|
rel = py_file.relative_to(project_root)
|
|
|
|
if py_file.name == "__init__.py":
|
|
# Package → index.md
|
|
module_path = ".".join(rel.parent.parts)
|
|
md_path = docs_root / rel.parent / "index.md"
|
|
title = rel.parent.name.replace("_", " ").title()
|
|
else:
|
|
# Regular module → <module>.md
|
|
module_path = ".".join(rel.with_suffix("").parts)
|
|
md_path = docs_root / rel.with_suffix(".md")
|
|
title = md_path.stem.replace("_", " ").title()
|
|
|
|
md_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
content = f"""# {title}
|
|
|
|
::: {module_path}
|
|
"""
|
|
|
|
md_path.write_text(content, encoding="utf-8")
|
|
|
|
|
|
def load_mkdocs_config():
|
|
if not MKDOCS_YML.exists():
|
|
raise FileNotFoundError("mkdocs.yml not found at project root")
|
|
return load_config(str(MKDOCS_YML))
|
|
|
|
|
|
def cmd_generate(args: argparse.Namespace) -> None:
|
|
generate_docs_from_nav(
|
|
project_root=PROJECT_ROOT,
|
|
docs_root=args.docs_dir,
|
|
package_root=args.package_root,
|
|
)
|
|
|
|
|
|
def cmd_build(_: argparse.Namespace) -> None:
|
|
config = load_mkdocs_config()
|
|
mkdocs_build.build(config)
|
|
|
|
|
|
def cmd_serve(_: argparse.Namespace) -> None:
|
|
config = load_mkdocs_config()
|
|
mkdocs_serve.serve(config)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
prog="manage_docs.py",
|
|
description="Manage MkDocs documentation for the project",
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--docs-dir",
|
|
type=Path,
|
|
default=DEFAULT_DOCS_DIR,
|
|
help="Path to the docs directory",
|
|
)
|
|
parser.add_argument(
|
|
"--package-root",
|
|
default=DEFAULT_PACKAGE_ROOT,
|
|
help="Root Python package name",
|
|
)
|
|
|
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
|
|
subparsers.add_parser(
|
|
"generate",
|
|
help="Generate Markdown files with mkdocstrings directives",
|
|
).set_defaults(func=cmd_generate)
|
|
|
|
subparsers.add_parser(
|
|
"build",
|
|
help="Build the MkDocs site",
|
|
).set_defaults(func=cmd_build)
|
|
|
|
subparsers.add_parser(
|
|
"serve",
|
|
help="Serve the MkDocs site locally",
|
|
).set_defaults(func=cmd_serve)
|
|
|
|
args = parser.parse_args()
|
|
args.func(args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|