manage_docs cli
This commit is contained in:
152
manage_docs.py
Normal file
152
manage_docs.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""
|
||||
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
|
||||
import sys
|
||||
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
|
||||
- Overwrites content with ::: package.module
|
||||
|
||||
Example:
|
||||
mail_intake/config.py -> docs/mail_intake/config.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"):
|
||||
if py_file.name == "__init__.py":
|
||||
continue
|
||||
|
||||
rel = py_file.relative_to(project_root)
|
||||
md_path = docs_root / rel.with_suffix(".md")
|
||||
|
||||
md_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
module_path = ".".join(rel.with_suffix("").parts)
|
||||
title = md_path.stem.replace("_", " ").title()
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user