Main documentation generation orchestrator.
| 29 | FIRST_MODULE_TREE_FILENAME, |
| 30 | MODULE_TREE_FILENAME, |
| 31 | OVERVIEW_FILENAME, |
| 32 | Config, |
| 33 | ) |
| 34 | from codewiki.src.utils import file_manager |
| 35 | |
| 36 | |
| 37 | class IncompleteDocumentationError(Exception): |
| 38 | """Raised when generation finishes but some modules have no doc file on disk.""" |
| 39 | |
| 40 | def __init__(self, missing_modules: list[str]): |
| 41 | self.missing_modules = missing_modules |
| 42 | super().__init__( |
| 43 | f"Documentation generation finished but {len(missing_modules)} module doc(s) " |
| 44 | f"are missing: {', '.join(missing_modules)}" |
| 45 | ) |
| 46 | |
| 47 | |
| 48 | class DocumentationGenerator: |
| 49 | """Main documentation generation orchestrator.""" |
| 50 | |
| 51 | def __init__( |
| 52 | self, config: Config, commit_id: str | None = None, backend: LLMBackend | None = None |
| 53 | ): |
| 54 | self.config = config |
| 55 | self.commit_id = commit_id |
| 56 | self.graph_builder = DependencyGraphBuilder(config) |
| 57 | self.backend: LLMBackend = backend or get_backend(config) |
| 58 | |
| 59 | def create_documentation_metadata( |
| 60 | self, working_dir: str, components: dict[str, Any], num_leaf_nodes: int |
| 61 | ): |
| 62 | """Create a metadata file with documentation generation information.""" |
| 63 | from datetime import UTC, datetime |
| 64 | |
| 65 | metadata = { |
| 66 | "generation_info": { |
| 67 | "timestamp": datetime.now(UTC).isoformat(), |
| 68 | "main_model": self.config.main_model, |
| 69 | "generator_version": "1.0.1", |
| 70 | "repo_path": self.config.repo_path, |
| 71 | "commit_id": self.commit_id, |
| 72 | }, |
| 73 | "statistics": { |
| 74 | "total_components": len(components), |
| 75 | "leaf_nodes": num_leaf_nodes, |
| 76 | "max_depth": self.config.max_depth, |
| 77 | }, |
| 78 | "files_generated": ["overview.md", "module_tree.json", "first_module_tree.json"], |
| 79 | } |
| 80 | |
| 81 | # Add generated markdown files to the metadata |
| 82 | try: |
| 83 | for file_path in os.listdir(working_dir): |
| 84 | if file_path.endswith(".md") and file_path not in metadata["files_generated"]: |
| 85 | metadata["files_generated"].append(file_path) |
| 86 | except Exception as e: # noqa: BLE001 — metadata listing is best-effort |
| 87 | logger.warning(f"Could not list generated files: {e}") |
| 88 |
no outgoing calls
no test coverage detected