# Merge Request: Flatten MkDocs Structure + `--module-is-source` Support ## Summary This MR introduces structural improvements to the MkDocs generation pipeline to: 1. Ensure a root `docs/index.md` always exists 2. Flatten documentation structure (remove `docs/<module>/` nesting by default) 3. Add support for `--module-is-source` to treat the module as the documentation root 4. Align navigation (`docforge.nav.yml`) with the new flat layout 5. Regenerate MCP artifacts to reflect updated signatures and docstrings This resolves static hosting issues (e.g., Nginx 403 due to missing `site/index.html`) and makes each generated MkDocs site deployable as a standalone static website. --- ## Motivation Previously, documentation was generated under: ``` docs/<module>/... ``` Which resulted in: ``` site/<module>/index.html ``` When deployed at `/libs/<project>/`, this caused: * Missing `site/index.html` * Nginx returning 403 for root access * Inconsistent static hosting behavior This MR corrects the architecture so each MkDocs build is a valid static site with a root entry point. --- ## Key Changes ### 1️⃣ Flattened Docs Structure **Before** ``` docs/docforge/index.md ``` **After** ``` docs/index.md ``` All documentation paths were updated accordingly: * `docs/docforge/cli/...` → `docs/cli/...` * `docs/docforge/models/...` → `docs/models/...` * `docs/docforge/renderers/...` → `docs/renderers/...` Navigation updated to match the flat layout. --- ### 2️⃣ Root Index Enforcement `MkDocsRenderer` now guarantees: * `docs/index.md` is always created * Parent `index.md` files are auto-generated if missing * Parent indexes link to child modules (idempotent behavior) This ensures: ``` site/index.html ``` Always exists after `mkdocs build`. --- ### 3️⃣ New CLI Flag: `--module-is-source` Added option: ``` --module-is-source ``` Behavior: * Treats the provided module as the documentation root * Removes the top-level module folder from generated paths * Prevents redundant nesting when the module corresponds to the source root Updated components: * `cli.commands.build` * `mkdocs_utils.generate_sources` * `MkDocsRenderer.generate_sources` * Stub files (`.pyi`) * MCP JSON artifacts --- ### 4️⃣ Navigation Spec Update `docforge.nav.yml` updated: **Before** ```yaml home: docforge/index.md ``` **After** ```yaml home: index.md ``` All group paths adjusted to remove `docforge/` prefix. --- ### 5️⃣ MkDocs Config Update `mkdocs.yml` updated to: * Move `site_name` below theme/plugins * Use flat navigation paths * Point Home to `index.md` --- ### 6️⃣ MCP Artifact Regeneration Updated: * Function signatures (new parameter) * Docstrings (reflect `module_is_source`) * Renderer metadata * Line numbers Ensures MCP output matches updated API. --- ## Architectural Outcome Each project now produces a **valid standalone static site**: ``` site/ index.html assets/ search/ ``` Safe for deployment under: ``` /libs/<project>/ ``` No Nginx rewrites required. No directory-index issues. No nested-site ambiguity. --- ## Backward Compatibility * Existing CLI usage remains valid * `--module-is-source` is optional * Navigation spec format unchanged (only paths adjusted) --- ## Deployment Impact After merge: * Each library can be deployed independently * Sites can be merged under a shared root without internal conflicts * Static hosting is predictable and production-safe --- ## Testing * Verified MkDocs build produces `site/index.html` * Verified navigation renders correctly * Verified parent index generation is idempotent * Regenerated MCP docs and validated schema consistency --- ## Result The documentation compiler now: * Produces structurally correct static sites * Supports flat and source-root modes * Eliminates 403 root issues * Scales cleanly across multiple repositories This aligns doc-forge with proper static-site architectural invariants. Reviewed-on: #4 Co-authored-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com> Co-committed-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
148 lines
8.8 KiB
JSON
148 lines
8.8 KiB
JSON
{
|
|
"module": "docforge.cli.mkdocs_utils",
|
|
"content": {
|
|
"path": "docforge.cli.mkdocs_utils",
|
|
"docstring": null,
|
|
"objects": {
|
|
"Path": {
|
|
"name": "Path",
|
|
"kind": "alias",
|
|
"path": "docforge.cli.mkdocs_utils.Path",
|
|
"signature": "<bound method Alias.signature of Alias('Path', 'pathlib.Path')>",
|
|
"docstring": null
|
|
},
|
|
"resources": {
|
|
"name": "resources",
|
|
"kind": "alias",
|
|
"path": "docforge.cli.mkdocs_utils.resources",
|
|
"signature": "<bound method Alias.signature of Alias('resources', 'importlib.resources')>",
|
|
"docstring": null
|
|
},
|
|
"click": {
|
|
"name": "click",
|
|
"kind": "alias",
|
|
"path": "docforge.cli.mkdocs_utils.click",
|
|
"signature": "<bound method Alias.signature of Alias('click', 'click')>",
|
|
"docstring": null
|
|
},
|
|
"yaml": {
|
|
"name": "yaml",
|
|
"kind": "alias",
|
|
"path": "docforge.cli.mkdocs_utils.yaml",
|
|
"signature": "<bound method Alias.signature of Alias('yaml', 'yaml')>",
|
|
"docstring": null
|
|
},
|
|
"GriffeLoader": {
|
|
"name": "GriffeLoader",
|
|
"kind": "class",
|
|
"path": "docforge.cli.mkdocs_utils.GriffeLoader",
|
|
"signature": "<bound method Alias.signature of Alias('GriffeLoader', 'docforge.loaders.GriffeLoader')>",
|
|
"docstring": "Loads Python modules and extracts documentation using the Griffe introspection engine.",
|
|
"members": {
|
|
"load_project": {
|
|
"name": "load_project",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.GriffeLoader.load_project",
|
|
"signature": "<bound method Alias.signature of Alias('load_project', 'docforge.loaders.griffe_loader.GriffeLoader.load_project')>",
|
|
"docstring": "Load multiple modules and combine them into a single Project models.\n\nArgs:\n module_paths: A list of dotted paths to the modules to load.\n project_name: Optional name for the project. Defaults to the first module name.\n skip_import_errors: If True, modules that fail to import will be skipped.\n\nReturns:\n A Project instance containing the loaded modules."
|
|
},
|
|
"load_module": {
|
|
"name": "load_module",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.GriffeLoader.load_module",
|
|
"signature": "<bound method Alias.signature of Alias('load_module', 'docforge.loaders.griffe_loader.GriffeLoader.load_module')>",
|
|
"docstring": "Load a single module and convert its introspection data into the docforge models.\n\nArgs:\n path: The dotted path of the module to load.\n\nReturns:\n A Module instance."
|
|
}
|
|
}
|
|
},
|
|
"discover_module_paths": {
|
|
"name": "discover_module_paths",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.discover_module_paths",
|
|
"signature": "<bound method Alias.signature of Alias('discover_module_paths', 'docforge.loaders.discover_module_paths')>",
|
|
"docstring": "Discover all Python modules under a package via filesystem traversal.\n\nRules:\n- Directory with __init__.py is treated as a package.\n- Any .py file is treated as a module.\n- All paths are converted to dotted module paths.\n\nArgs:\n module_name: The name of the package to discover.\n project_root: The root directory of the project. Defaults to current working directory.\n\nReturns:\n A sorted list of dotted module paths."
|
|
},
|
|
"MkDocsRenderer": {
|
|
"name": "MkDocsRenderer",
|
|
"kind": "class",
|
|
"path": "docforge.cli.mkdocs_utils.MkDocsRenderer",
|
|
"signature": "<bound method Alias.signature of Alias('MkDocsRenderer', 'docforge.renderers.MkDocsRenderer')>",
|
|
"docstring": "Renderer that generates Markdown source files formatted for the MkDocs\n'mkdocstrings' plugin.",
|
|
"members": {
|
|
"name": {
|
|
"name": "name",
|
|
"kind": "attribute",
|
|
"path": "docforge.cli.mkdocs_utils.MkDocsRenderer.name",
|
|
"signature": "<bound method Alias.signature of Alias('name', 'docforge.renderers.mkdocs_renderer.MkDocsRenderer.name')>",
|
|
"docstring": null
|
|
},
|
|
"generate_sources": {
|
|
"name": "generate_sources",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.MkDocsRenderer.generate_sources",
|
|
"signature": "<bound method Alias.signature of Alias('generate_sources', 'docforge.renderers.mkdocs_renderer.MkDocsRenderer.generate_sources')>",
|
|
"docstring": "Produce a set of Markdown files in the output directory based on the\nprovided Project models.\n\nArgs:\n project: The project models to render.\n out_dir: Target directory for documentation files.\n module_is_source: Module is the source folder and to be treated as the root folder."
|
|
}
|
|
}
|
|
},
|
|
"load_nav_spec": {
|
|
"name": "load_nav_spec",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.load_nav_spec",
|
|
"signature": "<bound method Alias.signature of Alias('load_nav_spec', 'docforge.nav.load_nav_spec')>",
|
|
"docstring": "Utility function to load a NavSpec from a file.\n\nArgs:\n path: Path to the navigation specification file.\n\nReturns:\n A loaded NavSpec instance."
|
|
},
|
|
"resolve_nav": {
|
|
"name": "resolve_nav",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.resolve_nav",
|
|
"signature": "<bound method Alias.signature of Alias('resolve_nav', 'docforge.nav.resolve_nav')>",
|
|
"docstring": "Create a ResolvedNav by processing a NavSpec against the filesystem.\nThis expands globs and validates the existence of referenced files.\n\nArgs:\n spec: The navigation specification to resolve.\n docs_root: The root directory for documentation files.\n\nReturns:\n A ResolvedNav instance.\n\nRaises:\n FileNotFoundError: If a pattern doesn't match any files or the docs_root doesn't exist."
|
|
},
|
|
"MkDocsNavEmitter": {
|
|
"name": "MkDocsNavEmitter",
|
|
"kind": "class",
|
|
"path": "docforge.cli.mkdocs_utils.MkDocsNavEmitter",
|
|
"signature": "<bound method Alias.signature of Alias('MkDocsNavEmitter', 'docforge.nav.MkDocsNavEmitter')>",
|
|
"docstring": "Emitter responsible for transforming a ResolvedNav into an MkDocs-compatible\nnavigation structure.",
|
|
"members": {
|
|
"emit": {
|
|
"name": "emit",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.MkDocsNavEmitter.emit",
|
|
"signature": "<bound method Alias.signature of Alias('emit', 'docforge.nav.mkdocs.MkDocsNavEmitter.emit')>",
|
|
"docstring": "Generate a list of navigation entries for mkdocs.yml.\n\nArgs:\n nav: The resolved navigation data.\n\nReturns:\n A list of dictionary mappings representing the MkDocs navigation."
|
|
}
|
|
}
|
|
},
|
|
"generate_sources": {
|
|
"name": "generate_sources",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.generate_sources",
|
|
"signature": "<bound method Function.signature of Function('generate_sources', 9, 33)>",
|
|
"docstring": "Generate Markdown source files for the specified module.\n\nArgs:\n module: The dotted path of the primary module to document.\n project_name: Optional override for the project name.\n docs_dir: Directory where the generated Markdown files will be written.\n module_is_source: Module is the source folder and to be treated as the root folder."
|
|
},
|
|
"generate_config": {
|
|
"name": "generate_config",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.generate_config",
|
|
"signature": "<bound method Function.signature of Function('generate_config', 35, 69)>",
|
|
"docstring": "Generate an mkdocs.yml configuration file.\n\nArgs:\n docs_dir: Path to the directory containing documentation Markdown files.\n nav_file: Path to the docforge.nav.yml specification.\n template: Optional path to an mkdocs.yml template (overrides built-in).\n out: Path where the final mkdocs.yml will be written.\n site_name: The display name for the documentation site."
|
|
},
|
|
"build": {
|
|
"name": "build",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.build",
|
|
"signature": "<bound method Function.signature of Function('build', 71, 84)>",
|
|
"docstring": "Build the documentation site using MkDocs.\n\nArgs:\n mkdocs_yml: Path to the mkdocs.yml configuration file."
|
|
},
|
|
"serve": {
|
|
"name": "serve",
|
|
"kind": "function",
|
|
"path": "docforge.cli.mkdocs_utils.serve",
|
|
"signature": "<bound method Function.signature of Function('serve', 86, 97)>",
|
|
"docstring": "Serve the documentation site with live-reload using MkDocs.\n\nArgs:\n mkdocs_yml: Path to the mkdocs.yml configuration file."
|
|
}
|
|
}
|
|
}
|
|
} |