Skip to content

Commit 6b5eb0e

Browse files
refactoring
1 parent 77ed7a0 commit 6b5eb0e

File tree

13 files changed

+654
-183
lines changed

13 files changed

+654
-183
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,6 @@ __marimo__/
212212
.code2docs.state
213213
.code2docs.api_snapshot.json
214214
mkdocs.yml
215+
216+
# Environment / secrets
217+
.env

code2docs/README.md

Lines changed: 160 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
11
<!-- code2docs:start --># code2docs
22

3-
![version](https://img.shields.io/badge/version-0.1.0-blue) ![python](https://img.shields.io/badge/python-%3E%3D3.9-blue) ![coverage](https://img.shields.io/badge/coverage-unknown-lightgrey) ![functions](https://img.shields.io/badge/functions-185-green)
4-
> **185** functions | **42** classes | **31** files | CC̄ = 3.8
3+
![version](https://img.shields.io/badge/version-0.1.0-blue) ![python](https://img.shields.io/badge/python-%3E%3D3.9-blue) ![coverage](https://img.shields.io/badge/coverage-unknown-lightgrey) ![functions](https://img.shields.io/badge/functions-219-green)
4+
> **219** functions | **49** classes | **37** files | CC̄ = 3.8
5+
6+
7+
## How It Works
8+
9+
code2docs uses static code analysis to automatically generate human-readable documentation from your source code.
10+
11+
```
12+
Source Code → code2llm (AST + tree-sitter) → AnalysisResult → code2docs generators → Docs
13+
```
14+
15+
**Analysis pipeline:**
16+
17+
1. **Parsing** — source files are parsed using language-specific AST parsers (tree-sitter) to extract functions, classes, modules, and their relationships
18+
2. **Metric collection** — cyclomatic complexity, fan-in/fan-out coupling, and dependency graphs are computed per function and module
19+
3. **Docstring extraction** — existing docstrings are parsed into structured sections (params, returns, raises, examples)
20+
4. **Documentation generation** — 12 specialized generators transform the analysis into Markdown, YAML, and Python examples
21+
22+
### Supported Languages & Frameworks
23+
24+
| Category | Languages / Frameworks |
25+
|----------|----------------------|
26+
| **Backend** | Python, Java, Go, Rust, C#, Ruby, PHP, Node.js |
27+
| **Frontend** | JavaScript, TypeScript, React, Vue, Angular |
28+
| **Firmware** | C, C++, Embedded C |
29+
| **Frameworks** | Django, Flask, FastAPI, Express, Spring, Rails |
30+
531

632
## Installation
733

@@ -12,73 +38,113 @@ pip install .
1238

1339
## Quick Start
1440

41+
### CLI Usage
42+
43+
```bash
44+
# Generate full documentation for your project
45+
code2docs ./my-project
46+
47+
# Only regenerate README
48+
code2docs ./my-project --readme-only
49+
50+
# Preview what would be generated (no file writes)
51+
code2docs ./my-project --dry-run
52+
53+
# Check documentation health
54+
code2docs check ./my-project
55+
56+
# Sync — regenerate only changed modules
57+
code2docs sync ./my-project
58+
```
59+
60+
### Python API
61+
1562
```python
16-
# Entry point: registry.GeneratorRegistry.__init__
17-
# Entry point: registry.GeneratorRegistry.add
18-
# Entry point: registry.GeneratorRegistry.run_all
63+
from code2docs import generate_readme, generate_docs, Code2DocsConfig
64+
65+
# Quick: generate README
66+
generate_readme("./my-project")
67+
68+
# Full: generate all documentation
69+
config = Code2DocsConfig(project_name="mylib", verbose=True)
70+
generate_docs("./my-project", config=config)
1971
```
2072

2173
## API Overview
2274

23-
### Classes
24-
25-
- **`GeneratorRegistry`** — Registry of documentation generators.
26-
- **`Updater`** — Apply selective documentation updates based on detected changes.
27-
- **`ChangeInfo`** — Describes a detected change.
28-
- **`Differ`** — Detect changes between current source and previous state.
29-
- **`MarkdownFormatter`** — Helper for constructing Markdown documents.
30-
- **`ReadmeGenerator`** — Generate README.md from AnalysisResult.
31-
- **`CoverageGenerator`** — Generate docs/coverage.md — docstring coverage report.
32-
- **`DepGraphGenerator`** — Generate docs/dependency-graph.md with Mermaid diagrams.
33-
- **`GenerateContext`** — Shared context passed to all generators during a run.
34-
- **`BaseGenerator`** — Abstract base for all documentation generators.
35-
- **`ChangelogEntry`** — A single changelog entry.
36-
- **`ChangelogGenerator`** — Generate CHANGELOG.md from git log and analysis diff.
37-
- **`ApiReferenceGenerator`** — Generate docs/api/ — per-module API reference from signatures.
38-
- **`ModuleDocsGenerator`** — Generate docs/modules/ — detailed per-module documentation.
39-
- **`MkDocsGenerator`** — Generate mkdocs.yml from the docs/ directory structure.
40-
- **`ExamplesGenerator`** — Generate examples/ — usage examples from public API signatures.
41-
- **`ReadmeGeneratorAdapter`**
42-
- **`ApiReferenceAdapter`**
43-
- **`ModuleDocsAdapter`**
44-
- **`ArchitectureAdapter`**
45-
- **`DepGraphAdapter`**
46-
- **`CoverageAdapter`**
47-
- **`ApiChangelogAdapter`**
48-
- **`ExamplesAdapter`**
49-
- **`MkDocsAdapter`**
50-
- **`ArchitectureGenerator`** — Generate docs/architecture.md — architecture overview with diagrams.
51-
- **`ApiChange`** — A single API change between two analysis snapshots.
52-
- **`ApiChangelogGenerator`** — Generate API changelog by diffing current analysis with a saved snapshot.
53-
- **`DefaultGroup`** — Click Group that routes unknown subcommands to 'generate'.
54-
- **`ReadmeConfig`** — Configuration for README generation.
55-
- **`DocsConfig`** — Configuration for docs/ generation.
56-
- **`ExamplesConfig`** — Configuration for examples/ generation.
57-
- **`SyncConfig`** — Configuration for synchronization.
58-
- **`Code2DocsConfig`** — Main configuration for code2docs.
59-
- **`ProjectScanner`** — Wraps code2llm's ProjectAnalyzer with code2docs-specific defaults.
60-
- **`DocstringInfo`** — Parsed docstring with sections.
61-
- **`DocstringExtractor`** — Extract and parse docstrings from AnalysisResult.
62-
- **`DependencyInfo`** — Information about a project dependency.
63-
- **`ProjectDependencies`** — All detected project dependencies.
64-
- **`DependencyScanner`** — Scan and parse project dependency files.
65-
- **`Endpoint`** — Represents a detected web endpoint.
66-
- **`EndpointDetector`** — Detects web endpoints from decorator patterns in source code.
67-
68-
### Functions
69-
70-
- `start_watcher(project_path, config)` — Start watching project for file changes and auto-resync docs.
71-
- `generate_badges(project_name, badge_types, stats, deps)` — Generate shields.io badge Markdown strings.
72-
- `generate_toc(markdown_content, max_depth)` — Generate a table of contents from Markdown headings.
73-
- `extract_headings(content, max_depth)` — Extract headings from Markdown content.
74-
- `generate_readme(project_path, output, sections, sync_markers, config)` — Convenience function to generate a README.
75-
- `generate_docs(project_path, config)` — High-level function to generate all documentation.
76-
- `main()` — code2docs — Auto-generate project documentation from source code.
77-
- `generate(project_path, config_path, readme_only, sections, output, verbose, dry_run)` — Generate documentation (default command).
78-
- `sync(project_path, config_path, verbose, dry_run)` — Synchronize documentation with source code changes.
79-
- `watch(project_path, config_path, verbose)` — Watch for file changes and auto-regenerate docs.
80-
- `init(project_path, output)` — Initialize code2docs.yaml configuration file.
81-
- `analyze_and_document(project_path, config)` — Convenience function: analyze a project in one call.
75+
### Key Classes
76+
77+
| Class | Description |
78+
|-------|-------------|
79+
| `GeneratorRegistry` | Registry of documentation generators. |
80+
| `Updater` | Apply selective documentation updates based on detected changes. |
81+
| `ChangeInfo` | Describes a detected change. |
82+
| `Differ` | Detect changes between current source and previous state. |
83+
| `MarkdownFormatter` | Helper for constructing Markdown documents. |
84+
| `ReadmeGenerator` | Generate README.md from AnalysisResult. |
85+
| `CoverageGenerator` | Generate docs/coverage.md — docstring coverage report. |
86+
| `GenerateContext` | Shared context passed to all generators during a run. |
87+
| `BaseGenerator` | Abstract base for all documentation generators. |
88+
| `DepGraphGenerator` | Generate docs/dependency-graph.md with Mermaid diagrams. |
89+
| `GettingStartedGenerator` | Generate docs/getting-started.md from entry points and dependencies. |
90+
| `ConfigDocsGenerator` | Generate docs/configuration.md from Code2DocsConfig dataclass. |
91+
| `ChangelogEntry` | A single changelog entry. |
92+
| `ChangelogGenerator` | Generate CHANGELOG.md from git log and analysis diff. |
93+
| `ApiReferenceGenerator` | Generate docs/api/ — per-module API reference from signatures. |
94+
| `ModuleDocsGenerator` | Generate docs/modules/ — detailed per-module documentation. |
95+
| `MkDocsGenerator` | Generate mkdocs.yml from the docs/ directory structure. |
96+
| `ExamplesGenerator` | Generate examples/ — usage examples from public API signatures. |
97+
| `ReadmeGeneratorAdapter` ||
98+
| `ApiReferenceAdapter` ||
99+
| `ModuleDocsAdapter` ||
100+
| `ArchitectureAdapter` ||
101+
| `DepGraphAdapter` ||
102+
| `CoverageAdapter` ||
103+
| `ApiChangelogAdapter` ||
104+
| `ExamplesAdapter` ||
105+
| `MkDocsAdapter` ||
106+
| `GettingStartedAdapter` ||
107+
| `ConfigDocsAdapter` ||
108+
| `ContributingAdapter` ||
109+
| `ApiChange` | A single API change between two analysis snapshots. |
110+
| `ApiChangelogGenerator` | Generate API changelog by diffing current analysis with a saved snapshot. |
111+
| `ContributingGenerator` | Generate CONTRIBUTING.md by detecting dev tools from pyproject.toml. |
112+
| `ArchitectureGenerator` | Generate docs/architecture.md — architecture overview with diagrams. |
113+
| `DefaultGroup` | Click Group that routes unknown subcommands to 'generate'. |
114+
| `ReadmeConfig` | Configuration for README generation. |
115+
| `DocsConfig` | Configuration for docs/ generation. |
116+
| `ExamplesConfig` | Configuration for examples/ generation. |
117+
| `SyncConfig` | Configuration for synchronization. |
118+
| `LLMConfig` | Configuration for optional LLM-assisted documentation generation. |
119+
| `Code2DocsConfig` | Main configuration for code2docs. |
120+
| `ProjectScanner` | Wraps code2llm's ProjectAnalyzer with code2docs-specific defaults. |
121+
| `DocstringInfo` | Parsed docstring with sections. |
122+
| `DocstringExtractor` | Extract and parse docstrings from AnalysisResult. |
123+
| `DependencyInfo` | Information about a project dependency. |
124+
| `ProjectDependencies` | All detected project dependencies. |
125+
| `DependencyScanner` | Scan and parse project dependency files. |
126+
| `Endpoint` | Represents a detected web endpoint. |
127+
| `EndpointDetector` | Detects web endpoints from decorator patterns in source code. |
128+
129+
### Public Functions
130+
131+
| Function | Signature | Description |
132+
|----------|-----------|-------------|
133+
| `start_watcher` | `(project_path, config)` | Start watching project for file changes and auto-resync docs. |
134+
| `generate_badges` | `(project_name, badge_types, stats, deps)` | Generate shields.io badge Markdown strings. |
135+
| `generate_toc` | `(markdown_content, max_depth)` | Generate a table of contents from Markdown headings. |
136+
| `extract_headings` | `(content, max_depth)` | Extract headings from Markdown content. |
137+
| `generate_readme` | `(project_path, output, sections, sync_markers)` | Convenience function to generate a README. |
138+
| `generate_docs` | `(project_path, config)` | High-level function to generate all documentation. |
139+
| `main` | `()` | code2docs — Auto-generate project documentation from source code. |
140+
| `generate` | `(project_path, config_path, readme_only, sections)` | Generate documentation (default command). |
141+
| `sync` | `(project_path, config_path, verbose, dry_run)` | Synchronize documentation with source code changes. |
142+
| `watch` | `(project_path, config_path, verbose)` | Watch for file changes and auto-regenerate docs. |
143+
| `init` | `(project_path, output)` | Initialize code2docs.yaml configuration file. |
144+
| `check` | `(project_path, config_path, target)` | Health check — verify documentation completeness. |
145+
| `diff` | `(project_path, config_path)` | Preview what would change without writing anything. |
146+
| `analyze_and_document` | `(project_path, config)` | Convenience function: analyze a project in one call. |
147+
82148

83149
## Project Structure
84150

@@ -89,30 +155,55 @@ pip install .
89155
📄 `analyzers.endpoint_detector` (3 functions, 2 classes)
90156
📄 `analyzers.project_scanner` (4 functions, 1 classes)
91157
📄 `base` (3 functions, 2 classes)
92-
📄 `cli` (10 functions, 1 classes)
158+
📄 `cli` (14 functions, 1 classes)
93159
📦 `code2docs` (1 functions)
94-
📄 `config` (2 functions, 5 classes)
160+
📄 `config` (3 functions, 6 classes)
161+
📄 `examples.basic_usage`
162+
📄 `examples.class_examples`
163+
📄 `examples.entry_points`
95164
📦 `formatters`
96165
📄 `formatters.badges` (2 functions)
97166
📄 `formatters.markdown` (13 functions, 1 classes)
98167
📄 `formatters.toc` (3 functions)
99168
📦 `generators` (1 functions)
100-
📄 `generators._registry_adapters` (18 functions, 9 classes)
169+
📄 `generators._registry_adapters` (24 functions, 12 classes)
101170
📄 `generators.api_changelog_gen` (9 functions, 2 classes)
102171
📄 `generators.api_reference_gen` (11 functions, 1 classes)
103-
📄 `generators.architecture_gen` (6 functions, 1 classes)
172+
📄 `generators.architecture_gen` (9 functions, 1 classes)
104173
📄 `generators.changelog_gen` (6 functions, 2 classes)
174+
📄 `generators.config_docs_gen` (4 functions, 1 classes)
175+
📄 `generators.contributing_gen` (8 functions, 1 classes)
105176
📄 `generators.coverage_gen` (7 functions, 1 classes)
106177
📄 `generators.depgraph_gen` (9 functions, 1 classes)
107178
📄 `generators.examples_gen` (12 functions, 1 classes)
179+
📄 `generators.getting_started_gen` (7 functions, 1 classes)
108180
📄 `generators.mkdocs_gen` (4 functions, 1 classes)
109181
📄 `generators.module_docs_gen` (17 functions, 1 classes)
110-
📄 `generators.readme_gen` (14 functions, 1 classes)
182+
📄 `generators.readme_gen` (15 functions, 1 classes)
111183
📄 `registry` (4 functions, 1 classes)
112184
📦 `sync`
113185
📄 `sync.differ` (7 functions, 2 classes)
114186
📄 `sync.updater` (2 functions, 1 classes)
115187
📄 `sync.watcher` (1 functions)
116188

117189

190+
## Generated Documentation
191+
192+
When you run `code2docs`, the following files are produced:
193+
194+
| Output | Description |
195+
|--------|-------------|
196+
| `README.md` | Project overview with badges, stats, and API summary |
197+
| `docs/api/` | Per-module API reference with signatures and complexity |
198+
| `docs/modules/` | Detailed module documentation with metrics |
199+
| `docs/architecture.md` | Architecture overview with Mermaid diagrams |
200+
| `docs/dependency-graph.md` | Module dependency graph and coupling matrix |
201+
| `docs/coverage.md` | Docstring coverage report |
202+
| `docs/getting-started.md` | Getting started guide |
203+
| `docs/configuration.md` | Configuration reference |
204+
| `docs/api-changelog.md` | API change tracking between runs |
205+
| `CONTRIBUTING.md` | Contribution guidelines |
206+
| `examples/` | Auto-generated usage examples |
207+
| `mkdocs.yml` | MkDocs site configuration |
208+
118209
<!-- code2docs:end -->

code2docs/config.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
"""Configuration for code2docs documentation generation."""
22

3+
import os
34
from dataclasses import dataclass, field
45
from pathlib import Path
56
from typing import Dict, List, Optional
67

78
import yaml
89

10+
# Load .env if python-dotenv is installed (optional dependency)
11+
try:
12+
from dotenv import load_dotenv
13+
load_dotenv()
14+
except ImportError:
15+
pass
16+
917

1018
@dataclass
1119
class ReadmeConfig:
1220
"""Configuration for README generation."""
1321
sections: List[str] = field(default_factory=lambda: [
14-
"overview", "install", "quickstart", "api", "structure", "endpoints",
22+
"overview", "how_it_works", "install", "quickstart", "api",
23+
"structure", "endpoints", "generated_docs",
1524
])
1625
badges: List[str] = field(default_factory=lambda: [
1726
"version", "python", "coverage", "complexity",
@@ -43,6 +52,31 @@ class SyncConfig:
4352
ignore: List[str] = field(default_factory=lambda: ["tests/", "__pycache__"])
4453

4554

55+
@dataclass
56+
class LLMConfig:
57+
"""Configuration for optional LLM-assisted documentation generation."""
58+
enabled: bool = False
59+
model: str = "" # litellm format: openai/gpt-4o-mini, anthropic/claude-3-haiku, ollama/llama3
60+
api_key: str = "" # provider API key (not needed for local models)
61+
api_base: str = "" # optional: custom endpoint URL
62+
max_tokens: int = 1024
63+
temperature: float = 0.3 # low for factual documentation
64+
65+
@classmethod
66+
def from_env(cls) -> "LLMConfig":
67+
"""Build LLMConfig from environment variables."""
68+
model = os.environ.get("CODE2DOCS_LLM_MODEL", "")
69+
api_key = os.environ.get("CODE2DOCS_LLM_API_KEY", "")
70+
api_base = os.environ.get("CODE2DOCS_LLM_API_BASE", "")
71+
max_tokens = int(os.environ.get("CODE2DOCS_LLM_MAX_TOKENS", "1024"))
72+
temperature = float(os.environ.get("CODE2DOCS_LLM_TEMPERATURE", "0.3"))
73+
enabled = bool(model)
74+
return cls(
75+
enabled=enabled, model=model, api_key=api_key,
76+
api_base=api_base, max_tokens=max_tokens, temperature=temperature,
77+
)
78+
79+
4680
@dataclass
4781
class Code2DocsConfig:
4882
"""Main configuration for code2docs."""
@@ -55,6 +89,7 @@ class Code2DocsConfig:
5589
docs: DocsConfig = field(default_factory=DocsConfig)
5690
examples: ExamplesConfig = field(default_factory=ExamplesConfig)
5791
sync: SyncConfig = field(default_factory=SyncConfig)
92+
llm: LLMConfig = field(default_factory=LLMConfig.from_env)
5893

5994
# code2llm analysis options
6095
verbose: bool = False
@@ -119,6 +154,19 @@ def from_yaml(cls, path: str) -> "Code2DocsConfig":
119154
ignore=sync_data.get("ignore", ["tests/", "__pycache__"]),
120155
)
121156

157+
# LLM config (YAML overrides env)
158+
llm_data = data.get("llm", {})
159+
if llm_data:
160+
env_llm = config.llm # already loaded from env
161+
config.llm = LLMConfig(
162+
enabled=llm_data.get("enabled", env_llm.enabled),
163+
model=llm_data.get("model", env_llm.model),
164+
api_key=llm_data.get("api_key", env_llm.api_key),
165+
api_base=llm_data.get("api_base", env_llm.api_base),
166+
max_tokens=llm_data.get("max_tokens", env_llm.max_tokens),
167+
temperature=llm_data.get("temperature", env_llm.temperature),
168+
)
169+
122170
return config
123171

124172
def to_yaml(self, path: str) -> None:
@@ -153,6 +201,14 @@ def to_yaml(self, path: str) -> None:
153201
"watch": self.sync.watch,
154202
"ignore": self.sync.ignore,
155203
},
204+
"llm": {
205+
"enabled": self.llm.enabled,
206+
"model": self.llm.model,
207+
"api_base": self.llm.api_base,
208+
"max_tokens": self.llm.max_tokens,
209+
"temperature": self.llm.temperature,
210+
# Note: api_key is intentionally excluded from YAML serialization
211+
},
156212
}
157213
with open(path, "w", encoding="utf-8") as f:
158214
yaml.dump(data, f, default_flow_style=False, sort_keys=False)

0 commit comments

Comments
 (0)