diff --git a/archdoc-cli/ARCHITECTURE.md b/archdoc-cli/ARCHITECTURE.md new file mode 100644 index 0000000..e69de29 diff --git a/archdoc-cli/src/main.rs b/archdoc-cli/src/main.rs index 297b420..727a207 100644 --- a/archdoc-cli/src/main.rs +++ b/archdoc-cli/src/main.rs @@ -325,9 +325,19 @@ fn generate_docs(model: &ProjectModel, out: &str) -> Result<()> { // Create individual documentation files for modules and files for (module_id, _module) in &model.modules { let module_doc_path = modules_path.join(format!("{}.md", sanitize_filename(module_id))); - let module_content = format!("# Module: {}\n\nTODO: Add module documentation\n", module_id); - std::fs::write(&module_doc_path, module_content) - .map_err(|e| anyhow::anyhow!("Failed to create module doc {}: {}", module_doc_path.display(), e))?; + match renderer.render_module_md(model, module_id) { + Ok(module_content) => { + std::fs::write(&module_doc_path, module_content) + .map_err(|e| anyhow::anyhow!("Failed to create module doc {}: {}", module_doc_path.display(), e))?; + } + Err(e) => { + eprintln!("Warning: Failed to render module doc for {}: {}", module_id, e); + // Fallback to simple template + let module_content = format!("# Module: {}\n\nTODO: Add module documentation\n", module_id); + std::fs::write(&module_doc_path, module_content) + .map_err(|e| anyhow::anyhow!("Failed to create module doc {}: {}", module_doc_path.display(), e))?; + } + } } for (_file_id, file_doc) in &model.files { diff --git a/archdoc-core/src/renderer.rs b/archdoc-core/src/renderer.rs index a06c29c..890828e 100644 --- a/archdoc-core/src/renderer.rs +++ b/archdoc-core/src/renderer.rs @@ -28,7 +28,9 @@ impl Renderer { handlebars.register_template_string("architecture_md", Self::architecture_md_template()) .expect("Failed to register architecture_md template"); - // TODO: Register other templates + // Register module documentation template + handlebars.register_template_string("module_md", Self::module_md_template()) + .expect("Failed to register module_md template"); Self { templates: handlebars, @@ -151,6 +153,82 @@ impl Renderer { "# } + fn module_md_template() -> &'static str { + r#"# Module: {{{module_name}}} + +{{{module_summary}}} + +## Symbols + +{{#each symbols}} +### {{{name}}} + +{{{signature}}} + +{{{docstring}}} + +**Type:** {{{kind}}} + +**Metrics:** +- Fan-in: {{{fan_in}}} +- Fan-out: {{{fan_out}}} +{{#if is_critical}} +- Critical: Yes +{{/if}} + +{{/each}} + +## Dependencies + +### Imports +{{#each imports}} +- {{{this}}} +{{/each}} + +### Outbound Modules +{{#each outbound_modules}} +- {{{this}}} +{{/each}} + +### Inbound Modules +{{#each inbound_modules}} +- {{{this}}} +{{/each}} + +## Integrations + +{{#if has_db_integrations}} +### Database Integrations +{{#each db_symbols}} +- {{{this}}} +{{/each}} +{{/if}} + +{{#if has_http_integrations}} +### HTTP/API Integrations +{{#each http_symbols}} +- {{{this}}} +{{/each}} +{{/if}} + +{{#if has_queue_integrations}} +### Queue Integrations +{{#each queue_symbols}} +- {{{this}}} +{{/each}} +{{/if}} + +## Usage Examples + +{{#each usage_examples}} +```python +{{{this}}} +``` + +{{/each}} +"# + } + pub fn render_architecture_md(&self, model: &ProjectModel) -> Result { // Collect integration information let mut db_integrations = Vec::new(); @@ -188,6 +266,72 @@ impl Renderer { .map_err(|e| anyhow::anyhow!("Failed to render architecture.md: {}", e)) } + pub fn render_module_md(&self, model: &ProjectModel, module_id: &str) -> Result { + // Find the module in the project model + let module = model.modules.get(module_id) + .ok_or_else(|| anyhow::anyhow!("Module {} not found", module_id))?; + + // Collect symbols for this module + let mut symbols = Vec::new(); + for symbol_id in &module.symbols { + if let Some(symbol) = model.symbols.get(symbol_id) { + symbols.push(serde_json::json!({ + "name": symbol.qualname, + "signature": symbol.signature, + "docstring": symbol.docstring_first_line.as_deref().unwrap_or("No documentation available"), + "kind": format!("{:?}", symbol.kind), + "fan_in": symbol.metrics.fan_in, + "fan_out": symbol.metrics.fan_out, + "is_critical": symbol.metrics.is_critical, + })); + } + } + + // Collect integration information for this module + let mut db_symbols = Vec::new(); + let mut http_symbols = Vec::new(); + let mut queue_symbols = Vec::new(); + + for symbol_id in &module.symbols { + if let Some(symbol) = model.symbols.get(symbol_id) { + if symbol.integrations_flags.db { + db_symbols.push(symbol.qualname.clone()); + } + if symbol.integrations_flags.http { + http_symbols.push(symbol.qualname.clone()); + } + if symbol.integrations_flags.queue { + queue_symbols.push(symbol.qualname.clone()); + } + } + } + + // Prepare usage examples (for now, just placeholders) + let usage_examples = vec![ + "// Example usage of module functions\n// TODO: Add real usage examples based on module analysis".to_string() + ]; + + // Prepare data for template + let data = serde_json::json!({ + "module_name": module_id, + "module_summary": module.doc_summary.as_deref().unwrap_or("No summary available"), + "symbols": symbols, + "imports": model.files.get(&module.files[0]).map(|f| f.imports.clone()).unwrap_or_default(), + "outbound_modules": module.outbound_modules, + "inbound_modules": module.inbound_modules, + "has_db_integrations": !db_symbols.is_empty(), + "has_http_integrations": !http_symbols.is_empty(), + "has_queue_integrations": !queue_symbols.is_empty(), + "db_symbols": db_symbols, + "http_symbols": http_symbols, + "queue_symbols": queue_symbols, + "usage_examples": usage_examples, + }); + + self.templates.render("module_md", &data) + .map_err(|e| anyhow::anyhow!("Failed to render module.md: {}", e)) + } + pub fn render_integrations_section(&self, model: &ProjectModel) -> Result { // Collect integration information let mut db_integrations = Vec::new(); diff --git a/test-project/docs/architecture/files/.._test-project_src___init__.py.md b/test-project/docs/architecture/files/.._test-project_src___init__.py.md new file mode 100644 index 0000000..8d38942 --- /dev/null +++ b/test-project/docs/architecture/files/.._test-project_src___init__.py.md @@ -0,0 +1,3 @@ +# File: ../test-project/src/__init__.py + +TODO: Add file documentation diff --git a/test-project/docs/architecture/files/.._test-project_src_core.py.md b/test-project/docs/architecture/files/.._test-project_src_core.py.md new file mode 100644 index 0000000..301945b --- /dev/null +++ b/test-project/docs/architecture/files/.._test-project_src_core.py.md @@ -0,0 +1,3 @@ +# File: ../test-project/src/core.py + +TODO: Add file documentation diff --git a/test-project/docs/architecture/files/.._test-project_src_utils.py.md b/test-project/docs/architecture/files/.._test-project_src_utils.py.md new file mode 100644 index 0000000..b166be3 --- /dev/null +++ b/test-project/docs/architecture/files/.._test-project_src_utils.py.md @@ -0,0 +1,3 @@ +# File: ../test-project/src/utils.py + +TODO: Add file documentation diff --git a/test-project/docs/architecture/modules/.._test-project_src___init__.py.md b/test-project/docs/architecture/modules/.._test-project_src___init__.py.md new file mode 100644 index 0000000..e324421 --- /dev/null +++ b/test-project/docs/architecture/modules/.._test-project_src___init__.py.md @@ -0,0 +1,27 @@ +# Module: ../test-project/src/__init__.py + +No summary available + +## Symbols + + +## Dependencies + +### Imports + +### Outbound Modules + +### Inbound Modules + +## Integrations + + + + +## Usage Examples + +```python +// Example usage of module functions +// TODO: Add real usage examples based on module analysis +``` + diff --git a/test-project/docs/architecture/modules/.._test-project_src_core.py.md b/test-project/docs/architecture/modules/.._test-project_src_core.py.md new file mode 100644 index 0000000..4ea4629 --- /dev/null +++ b/test-project/docs/architecture/modules/.._test-project_src_core.py.md @@ -0,0 +1,106 @@ +# Module: ../test-project/src/core.py + +No summary available + +## Symbols + +### DatabaseManager + +class DatabaseManager + +No documentation available + +**Type:** Class + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### __init__ + +def __init__(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### connect + +def connect(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### execute_query + +def execute_query(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### fetch_external_data + +def fetch_external_data(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### process_user_data + +def process_user_data(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 1 + + +## Dependencies + +### Imports +- sqlite3 +- requests + +### Outbound Modules + +### Inbound Modules + +## Integrations + +### Database Integrations +- DatabaseManager +- connect + +### HTTP/API Integrations +- fetch_external_data + + +## Usage Examples + +```python +// Example usage of module functions +// TODO: Add real usage examples based on module analysis +``` + diff --git a/test-project/docs/architecture/modules/.._test-project_src_utils.py.md b/test-project/docs/architecture/modules/.._test-project_src_utils.py.md new file mode 100644 index 0000000..c8a3fe4 --- /dev/null +++ b/test-project/docs/architecture/modules/.._test-project_src_utils.py.md @@ -0,0 +1,77 @@ +# Module: ../test-project/src/utils.py + +No summary available + +## Symbols + +### load_config + +def load_config(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### save_config + +def save_config(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### get_file_size + +def get_file_size(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + +### format_bytes + +def format_bytes(...) + +No documentation available + +**Type:** Function + +**Metrics:** +- Fan-in: 0 +- Fan-out: 0 + + +## Dependencies + +### Imports +- json +- os + +### Outbound Modules + +### Inbound Modules + +## Integrations + + + + +## Usage Examples + +```python +// Example usage of module functions +// TODO: Add real usage examples based on module analysis +``` +