feat(cli,mkdocs): require site_name, fix nav paths, and echo serve URL

- 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.
This commit is contained in:
2026-01-21 00:32:29 +05:30
parent 46b7cc52e1
commit 4fa3bc0533
5 changed files with 46 additions and 5 deletions

View File

@@ -133,6 +133,12 @@ def serve(mkdocs_yml: Path) -> None:
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))

View File

@@ -25,6 +25,11 @@ def _load_template(template: Path | None) -> dict:
@click.command("mkdocs")
@click.option(
"--site-name",
required=True,
help="MkDocs site_name (required)",
)
@click.option(
"--docs-dir",
type=click.Path(path_type=Path),
@@ -52,6 +57,7 @@ def mkdocs_cmd(
nav_file: Path,
template: Path | None,
out: Path,
site_name: str,
) -> None:
"""Generate mkdocs.yml from nav spec and template."""
@@ -70,6 +76,9 @@ def mkdocs_cmd(
# Load template (user or built-in)
data = _load_template(template)
# Inject site_name
data["site_name"] = site_name
# Inject nav
data["nav"] = nav_block

View File

@@ -9,6 +9,11 @@ def _load_template(template: Optional[Path]) -> Dict[str, Any]:
@click.command("mkdocs")
@click.option(
"--site-name",
required=True,
help="MkDocs site_name (required)",
)
@click.option(
"--docs-dir",
type=click.Path(path_type=Path),
@@ -35,5 +40,6 @@ def mkdocs_cmd(
nav_file: Path,
template: Optional[Path],
out: Path,
site_name: str,
) -> None:
...

View File

@@ -19,14 +19,27 @@ class MkDocsNavEmitter:
entries: List[str] = []
for p in paths:
# Convert filesystem path back to docs-relative path
entries.append(self._to_relative(p))
rel_path = self._to_relative(p, nav._docs_root)
entries.append(rel_path)
result.append({group: entries})
return result
def _to_relative(self, path: Path) -> str:
def _to_relative(self, path: Path, docs_root: Path | None) -> str:
"""
Convert a filesystem path to a docs-relative path.
"""
# Normalize to POSIX-style for MkDocs
if docs_root and path.is_absolute():
try:
path = path.relative_to(docs_root.resolve())
except ValueError:
pass
elif docs_root:
# Handle relative paths (e.g. starting with 'docs/')
path_str = path.as_posix()
docs_root_str = docs_root.as_posix()
if path_str.startswith(docs_root_str + "/"):
return path_str[len(docs_root_str) + 1:]
# Fallback for other cases
return path.as_posix().split("/docs/", 1)[-1]