- Require `--site-name` when generating mkdocs.yml to ensure valid configs - Inject site_name explicitly into generated mkdocs.yml - Echo MkDocs serve URL (http://127.0.0.1:8000) before starting server - Fix MkDocs nav emission to correctly resolve docs-relative paths - Align MkDocs-related optional dependencies with a compatible, pinned set These changes make MkDocs generation valid by default, improve UX when serving, and prevent nav path and plugin compatibility issues.
155 lines
3.8 KiB
Python
155 lines
3.8 KiB
Python
from pathlib import Path
|
|
from typing import Sequence, Optional
|
|
|
|
import click
|
|
|
|
from docforge.loader import GriffeLoader, discover_module_paths
|
|
from docforge.renderers.mkdocs import MkDocsRenderer
|
|
from docforge.cli.mkdocs import mkdocs_cmd
|
|
|
|
|
|
@click.group()
|
|
def cli() -> None:
|
|
"""doc-forge command-line interface."""
|
|
pass
|
|
|
|
|
|
cli.add_command(mkdocs_cmd)
|
|
|
|
# ---------------------------------------------------------------------
|
|
# tree
|
|
# ---------------------------------------------------------------------
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--modules",
|
|
multiple=True,
|
|
required=True,
|
|
help="Python module import paths to introspect",
|
|
)
|
|
@click.option(
|
|
"--project-name",
|
|
help="Project name (defaults to first module)",
|
|
)
|
|
def tree(
|
|
modules: Sequence[str],
|
|
project_name: Optional[str],
|
|
) -> None:
|
|
"""Show introspection tree."""
|
|
loader = GriffeLoader()
|
|
project = loader.load_project(list(modules), project_name)
|
|
|
|
click.echo(project.name)
|
|
|
|
for module in project.get_all_modules():
|
|
click.echo(f"├── {module.path}")
|
|
|
|
for obj in module.get_all_objects():
|
|
_print_object(obj, indent="│ ")
|
|
|
|
|
|
def _print_object(obj, indent: str) -> None:
|
|
click.echo(f"{indent}├── {obj.name}")
|
|
for member in obj.get_all_members():
|
|
_print_object(member, indent + "│ ")
|
|
|
|
|
|
# ---------------------------------------------------------------------
|
|
# generate
|
|
# ---------------------------------------------------------------------
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--module",
|
|
required=True,
|
|
help="Python module import paths to document",
|
|
)
|
|
@click.option(
|
|
"--project-name",
|
|
help="Project name (defaults to first module)",
|
|
)
|
|
@click.option(
|
|
"--docs-dir",
|
|
type=click.Path(path_type=Path),
|
|
default=Path("docs"),
|
|
)
|
|
def generate(
|
|
module: str,
|
|
project_name: Optional[str],
|
|
docs_dir: Path,
|
|
) -> None:
|
|
"""Generate documentation source files using MkDocs renderer."""
|
|
loader = GriffeLoader()
|
|
discovered_paths = discover_module_paths(
|
|
module,
|
|
)
|
|
project = loader.load_project(
|
|
discovered_paths,
|
|
project_name
|
|
)
|
|
|
|
renderer = MkDocsRenderer()
|
|
renderer.generate_sources(project, docs_dir)
|
|
|
|
click.echo(f"Documentation sources generated in {docs_dir}")
|
|
|
|
|
|
# ---------------------------------------------------------------------
|
|
# build
|
|
# ---------------------------------------------------------------------
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--mkdocs-yml",
|
|
type=click.Path(path_type=Path),
|
|
default=Path("mkdocs.yml"),
|
|
)
|
|
def build(mkdocs_yml: Path) -> None:
|
|
"""Build documentation using MkDocs."""
|
|
if not mkdocs_yml.exists():
|
|
raise click.ClickException(f"mkdocs.yml not found: {mkdocs_yml}")
|
|
|
|
from mkdocs.config import load_config
|
|
from mkdocs.commands.build import build as mkdocs_build
|
|
|
|
mkdocs_build(load_config(str(mkdocs_yml)))
|
|
|
|
click.echo("MkDocs build completed")
|
|
|
|
|
|
# ---------------------------------------------------------------------
|
|
# serve
|
|
# ---------------------------------------------------------------------
|
|
|
|
@cli.command()
|
|
@click.option(
|
|
"--mkdocs-yml",
|
|
type=click.Path(path_type=Path),
|
|
default=Path("mkdocs.yml"),
|
|
)
|
|
def serve(mkdocs_yml: Path) -> None:
|
|
"""Serve documentation using MkDocs."""
|
|
if not mkdocs_yml.exists():
|
|
raise click.ClickException(f"mkdocs.yml not found: {mkdocs_yml}")
|
|
|
|
from mkdocs.commands.serve import serve as mkdocs_serve
|
|
|
|
host = "127.0.0.1"
|
|
port = 8000
|
|
url = f"http://{host}:{port}/"
|
|
|
|
click.echo(f"Serving documentation at {url}")
|
|
mkdocs_serve(config_file=str(mkdocs_yml))
|
|
|
|
|
|
# ---------------------------------------------------------------------
|
|
# entry point
|
|
# ---------------------------------------------------------------------
|
|
|
|
def main() -> None:
|
|
cli()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|