""" This module contains the 'mkdocs' CLI command, which orchestrates the generation of the main mkdocs.yml configuration file. """ from pathlib import Path from importlib import resources import click import yaml from docforge.nav import load_nav_spec from docforge.nav import resolve_nav from docforge.nav import MkDocsNavEmitter def _load_template(template: Path | None) -> dict: """ Load a YAML template for mkdocs.yml. If no template is provided, loads the built-in sample template. Args: template: Path to the template file, or None. Returns: The loaded template data as a dictionary. """ if template is not None: if not template.exists(): raise click.FileError(str(template), hint="Template not found") return yaml.safe_load(template.read_text(encoding="utf-8")) # Load built-in default text = ( resources.files("docforge.templates") .joinpath("mkdocs.sample.yml") .read_text(encoding="utf-8") ) return yaml.safe_load(text) @click.command("mkdocs") @click.option( "--site-name", required=True, help="MkDocs site_name (required)", ) @click.option( "--docs-dir", type=click.Path(path_type=Path), default=Path("docs"), ) @click.option( "--nav", "nav_file", type=click.Path(path_type=Path), default=Path("docforge.nav.yml"), ) @click.option( "--template", type=click.Path(path_type=Path), default=None, help="Override the built-in mkdocs template", ) @click.option( "--out", type=click.Path(path_type=Path), default=Path("mkdocs.yml"), ) def mkdocs_cmd( docs_dir: Path, nav_file: Path, template: Path | None, out: Path, site_name: str, ) -> None: """ Generate an mkdocs.yml configuration file by combining a template with the navigation structure resolved from a docforge.nav.yml file. Args: docs_dir: Path to the directory containing documentation Markdown files. nav_file: Path to the docforge.nav.yml specification. template: Optional path to an mkdocs.yml template. out: Path where the final mkdocs.yml will be written. site_name: The name of the documentation site. """ if not nav_file.exists(): raise click.FileError(str(nav_file), hint="Nav spec not found") # Load nav spec spec = load_nav_spec(nav_file) # Resolve nav resolved = resolve_nav(spec, docs_dir) # Emit mkdocs nav nav_block = MkDocsNavEmitter().emit(resolved) # Load template (user or built-in) data = _load_template(template) # Inject site_name data["site_name"] = site_name # Inject nav data["nav"] = nav_block # Write output out.write_text( yaml.safe_dump(data, sort_keys=False), encoding="utf-8", ) click.echo(f"mkdocs.yml written to {out}")