Skip to content

Commit 794ecc0

Browse files
refactor(docs): code analysis engine
changes: - file: _registry_adapters.py area: docs modified: [ReadmeGeneratorAdapter, MkDocsAdapter, ContributingAdapter, ExamplesAdapter] - file: contributing_gen.py area: docs modified: [_render_setup, ContributingGenerator] - file: getting_started_gen.py area: docs modified: [GettingStartedGenerator, _render_installation] dependencies: flow: "_registry_adapters→contributing_gen" - _registry_adapters.py -> getting_started_gen.py - _registry_adapters.py -> contributing_gen.py stats: lines: "+12055/-11916 (net +139)" files: 15 complexity: "+62% complexity (monitor)"
1 parent e25162e commit 794ecc0

32 files changed

+12085
-11921
lines changed

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [3.0.3] - 2026-03-08
11+
12+
### Docs
13+
- Update code2docs/README.md
14+
- Update code2docs/project/context.md
15+
- Update docs/architecture.md
16+
- Update project/context.md
17+
18+
### Test
19+
- Update tests/project/dashboard.html
20+
- Update tests/project/project.yaml
21+
22+
### Other
23+
- Update code2docs/generators/_registry_adapters.py
24+
- Update code2docs/generators/contributing_gen.py
25+
- Update code2docs/generators/getting_started_gen.py
26+
- Update code2docs/project/analysis.json
27+
- Update code2docs/project/analysis.toon
28+
- Update code2docs/project/analysis.yaml
29+
- Update code2docs/project/calls.mmd
30+
- Update code2docs/project/dashboard.html
31+
- Update code2docs/project/flow.mmd
32+
- Update code2docs/project/flow.toon
33+
- ... and 11 more files
34+
1035
## [3.0.2] - 2026-03-08
1136

1237
### Docs

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# code2docs
22

3-
![version](https://img.shields.io/badge/version-3.0.2-blue) ![python](https://img.shields.io/badge/python-%3E%3D3.9-blue) ![docs](https://img.shields.io/badge/docs-auto--generated-blueviolet)
3+
![version](https://img.shields.io/badge/version-3.0.3-blue) ![python](https://img.shields.io/badge/python-%3E%3D3.9-blue) ![docs](https://img.shields.io/badge/docs-auto--generated-blueviolet)
44

55
> Auto-generate and sync project documentation from source code analysis.
66
@@ -140,7 +140,7 @@ code2docs can update only specific sections of an existing README using markers:
140140
```markdown
141141
<!-- code2docs:start --># code2docs
142142

143-
![version](https://img.shields.io/badge/version-3.0.2-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-276-green)
143+
![version](https://img.shields.io/badge/version-3.0.3-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-276-green)
144144
> **276** functions | **57** classes | **51** files | CC̄ = 3.8
145145

146146
> Auto-generated project documentation from source code analysis.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.2
1+
3.0.3

code2docs/README.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,189 @@ Content outside the markers is preserved when regenerating. Enable this with `sy
139139

140140
## Architecture
141141

142+
```
143+
code2docs/
144+
├── registry├── llm_helper├── code2docs/ ├── updater├── sync/ ├── watcher ├── differ ├── quickstart ├── advanced_usage ├── markdown ├── badges├── base├── formatters/ ├── toc ├── coverage_gen ├── _source_links ├── readme_gen ├── depgraph_gen ├── config_docs_gen ├── getting_started_gen ├── changelog_gen├── generators/ ├── code2llm_gen ├── module_docs_gen ├── api_reference_gen ├── mkdocs_gen ├── examples_gen ├── _registry_adapters ├── api_changelog_gen ├── contributing_gen ├── architecture_gen├── analyzers/├── cli├── config ├── project_scanner ├── dependency_scanner ├── docstring_extractor ├── endpoint_detector```
145+
146+
## API Overview
147+
148+
### Classes
149+
150+
- **`GeneratorRegistry`** — Registry of documentation generators.
151+
- **`LLMHelper`** — Thin wrapper around litellm for documentation generation.
152+
- **`Updater`** — Apply selective documentation updates based on detected changes.
153+
- **`ChangeInfo`** — Describes a detected change.
154+
- **`Differ`** — Detect changes between current source and previous state.
155+
- **`MarkdownFormatter`** — Helper for constructing Markdown documents.
156+
- **`GenerateContext`** — Shared context passed to all generators during a run.
157+
- **`BaseGenerator`** — Abstract base for all documentation generators.
158+
- **`CoverageGenerator`** — Generate docs/coverage.md — docstring coverage report.
159+
- **`SourceLinker`** — Build source-code links (relative paths + optional GitHub/GitLab URLs).
160+
- **`ReadmeGenerator`** — Generate README.md from AnalysisResult.
161+
- **`DepGraphGenerator`** — Generate docs/dependency-graph.md with Mermaid diagrams.
162+
- **`ConfigDocsGenerator`** — Generate docs/configuration.md from Code2DocsConfig dataclass.
163+
- **`GettingStartedGenerator`** — Generate docs/getting-started.md from entry points and dependencies.
164+
- **`ChangelogEntry`** — A single changelog entry.
165+
- **`ChangelogGenerator`** — Generate CHANGELOG.md from git log and analysis diff.
166+
- **`Code2LlmGenerator`** — Generate code2llm analysis files in project/ directory.
167+
- **`ModuleDocsGenerator`** — Generate docs/modules.md — consolidated module documentation.
168+
- **`ApiReferenceGenerator`** — Generate docs/api.md — consolidated API reference.
169+
- **`MkDocsGenerator`** — Generate mkdocs.yml from the docs/ directory structure.
170+
- **`ExamplesGenerator`** — Generate examples/ — usage examples from public API signatures.
171+
- **`ReadmeGeneratorAdapter`** — —
172+
- **`ApiReferenceAdapter`** — —
173+
- **`ModuleDocsAdapter`** — —
174+
- **`ArchitectureAdapter`** — —
175+
- **`DepGraphAdapter`** — —
176+
- **`CoverageAdapter`** — —
177+
- **`ApiChangelogAdapter`** — —
178+
- **`ExamplesAdapter`** — —
179+
- **`MkDocsAdapter`** — —
180+
- **`GettingStartedAdapter`** — —
181+
- **`ConfigDocsAdapter`** — —
182+
- **`ContributingAdapter`** — —
183+
- **`Code2LlmAdapter`** — Adapter for code2llm analysis generation.
184+
- **`ApiChange`** — A single API change between two analysis snapshots.
185+
- **`ApiChangelogGenerator`** — Generate API changelog by diffing current analysis with a saved snapshot.
186+
- **`ContributingGenerator`** — Generate CONTRIBUTING.md by detecting dev tools from pyproject.toml.
187+
- **`ArchitectureGenerator`** — Generate docs/architecture.md — architecture overview with diagrams.
188+
- **`DefaultGroup`** — Click Group that routes unknown subcommands to 'generate'.
189+
- **`ReadmeConfig`** — Configuration for README generation.
190+
- **`DocsConfig`** — Configuration for docs/ generation.
191+
- **`ExamplesConfig`** — Configuration for examples/ generation.
192+
- **`SyncConfig`** — Configuration for synchronization.
193+
- **`Code2LlmConfig`** — Configuration for code2llm analysis generation.
194+
- **`LLMConfig`** — Configuration for optional LLM-assisted documentation generation.
195+
- **`Code2DocsConfig`** — Main configuration for code2docs.
196+
- **`ProjectScanner`** — Wraps code2llm's ProjectAnalyzer with code2docs-specific defaults.
197+
- **`DependencyInfo`** — Information about a project dependency.
198+
- **`ProjectDependencies`** — All detected project dependencies.
199+
- **`DependencyScanner`** — Scan and parse project dependency files.
200+
- **`DocstringInfo`** — Parsed docstring with sections.
201+
- **`DocstringExtractor`** — Extract and parse docstrings from AnalysisResult.
202+
- **`Endpoint`** — Represents a detected web endpoint.
203+
- **`EndpointDetector`** — Detects web endpoints from decorator patterns in source code.
204+
205+
### Functions
206+
207+
- `start_watcher(project_path, config)` — Start watching project for file changes and auto-resync docs.
208+
- `generate_badges(project_name, badge_types, stats, deps)` — Generate shields.io badge Markdown strings.
209+
- `generate_toc(markdown_content, max_depth)` — Generate a table of contents from Markdown headings.
210+
- `extract_headings(content, max_depth)` — Extract headings from Markdown content.
211+
- `generate_readme(project_path, output, sections, sync_markers)` — Convenience function to generate a README.
212+
- `generate_docs(project_path, config)` — High-level function to generate all documentation.
213+
- `parse_gitignore(project_path)` — Parse .gitignore file and return list of patterns to exclude.
214+
- `generate_code2llm_analysis(project_path, config)` — Convenience function to generate code2llm analysis.
215+
- `main()` — code2docs — Auto-generate project documentation from source code.
216+
- `generate(project_path, config_path, readme_only, sections)` — Generate documentation (default command).
217+
- `sync(project_path, config_path, verbose, dry_run)` — Synchronize documentation with source code changes.
218+
- `watch(project_path, config_path, verbose)` — Watch for file changes and auto-regenerate docs.
219+
- `init(project_path, output)` — Initialize code2docs.yaml configuration file.
220+
- `check(project_path, config_path, target)` — Health check — verify documentation completeness.
221+
- `diff(project_path, config_path)` — Preview what would change without writing anything.
222+
- `analyze_and_document(project_path, config)` — Convenience function: analyze a project in one call.
223+
224+
225+
## Project Structure
226+
227+
📄 `__main__`
228+
📦 `analyzers`
229+
📄 `analyzers.dependency_scanner` (6 functions, 3 classes)
230+
📄 `analyzers.docstring_extractor` (10 functions, 2 classes)
231+
📄 `analyzers.endpoint_detector` (3 functions, 2 classes)
232+
📄 `analyzers.project_scanner` (4 functions, 1 classes)
233+
📄 `base` (3 functions, 2 classes)
234+
📄 `cli` (14 functions, 1 classes)
235+
📦 `code2docs` (1 functions)
236+
📄 `config` (5 functions, 7 classes)
237+
📄 `examples.advanced_usage`
238+
📄 `examples.quickstart`
239+
📦 `formatters`
240+
📄 `formatters.badges` (2 functions)
241+
📄 `formatters.markdown` (13 functions, 1 classes)
242+
📄 `formatters.toc` (3 functions)
243+
📦 `generators` (1 functions)
244+
📄 `generators._registry_adapters` (26 functions, 13 classes)
245+
📄 `generators._source_links` (6 functions, 1 classes)
246+
📄 `generators.api_changelog_gen` (9 functions, 2 classes)
247+
📄 `generators.api_reference_gen` (7 functions, 1 classes)
248+
📄 `generators.architecture_gen` (10 functions, 1 classes)
249+
📄 `generators.changelog_gen` (6 functions, 2 classes)
250+
📄 `generators.code2llm_gen` (6 functions, 1 classes)
251+
📄 `generators.config_docs_gen` (4 functions, 1 classes)
252+
📄 `generators.contributing_gen` (8 functions, 1 classes)
253+
📄 `generators.coverage_gen` (7 functions, 1 classes)
254+
📄 `generators.depgraph_gen` (9 functions, 1 classes)
255+
📄 `generators.examples_gen` (14 functions, 1 classes)
256+
📄 `generators.getting_started_gen` (8 functions, 1 classes)
257+
📄 `generators.mkdocs_gen` (4 functions, 1 classes)
258+
📄 `generators.module_docs_gen` (9 functions, 1 classes)
259+
📄 `generators.readme_gen` (18 functions, 1 classes)
260+
📄 `llm_helper` (7 functions, 1 classes)
261+
📄 `registry` (4 functions, 1 classes)
262+
📦 `sync`
263+
📄 `sync.differ` (7 functions, 2 classes)
264+
📄 `sync.updater` (2 functions, 1 classes)
265+
📄 `sync.watcher` (1 functions)
266+
267+
## Requirements
268+
269+
270+
271+
## Contributing
272+
273+
**Contributors:**
274+
- Tom Softreck <tom@sapletta.com>
275+
- Tom Sapletta <tom-sapletta-com@users.noreply.github.com>
276+
277+
We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
278+
279+
### Development Setup
280+
281+
```bash
282+
# Clone the repository
283+
git clone https://github.com/wronai/code2docs
284+
cd code2docs
285+
286+
# Install in development mode
287+
pip install -e ".[dev]"
288+
289+
# Run tests
290+
pytest
291+
```
292+
293+
## Documentation
294+
295+
- 📖 [Full Documentation](https://github.com/wronai/code2docs/tree/main/docs) — API reference, module docs, architecture
296+
- 🚀 [Getting Started](https://github.com/wronai/code2docs/blob/main/docs/getting-started.md) — Quick start guide
297+
- 📚 [API Reference](https://github.com/wronai/code2docs/blob/main/docs/api.md) — Complete API documentation
298+
- 🔧 [Configuration](https://github.com/wronai/code2docs/blob/main/docs/configuration.md) — Configuration options
299+
- 💡 [Examples](./examples) — Usage examples and code samples
300+
301+
### Generated Files
302+
303+
| Output | Description | Link |
304+
|--------|-------------|------|
305+
| `README.md` | Project overview (this file) ||
306+
| `docs/api.md` | Consolidated API reference | [View](./docs/api.md) |
307+
| `docs/modules.md` | Module reference with metrics | [View](./docs/modules.md) |
308+
| `docs/architecture.md` | Architecture with diagrams | [View](./docs/architecture.md) |
309+
| `docs/dependency-graph.md` | Dependency graphs | [View](./docs/dependency-graph.md) |
310+
| `docs/coverage.md` | Docstring coverage report | [View](./docs/coverage.md) |
311+
| `docs/getting-started.md` | Getting started guide | [View](./docs/getting-started.md) |
312+
| `docs/configuration.md` | Configuration reference | [View](./docs/configuration.md) |
313+
| `docs/api-changelog.md` | API change tracking | [View](./docs/api-changelog.md) |
314+
| `CONTRIBUTING.md` | Contribution guidelines | [View](./CONTRIBUTING.md) |
315+
| `examples/` | Usage examples | [Browse](./examples) |
316+
| `mkdocs.yml` | MkDocs configuration ||
317+
318+
<!-- code2docs:end -->
319+
```
320+
321+
Content outside the markers is preserved when regenerating. Enable this with `sync_markers: true` in your configuration.
322+
323+
## Architecture
324+
142325
```
143326
code2docs/
144327
├── registry├── llm_helper├── code2docs/ ├── updater├── sync/ ├── watcher ├── differ ├── quickstart ├── advanced_usage ├── markdown ├── badges ├── toc├── formatters/├── base ├── readme_gen ├── coverage_gen ├── _source_links ├── depgraph_gen ├── getting_started_gen ├── config_docs_gen ├── changelog_gen├── generators/ ├── code2llm_gen ├── module_docs_gen ├── api_reference_gen ├── mkdocs_gen ├── _registry_adapters ├── examples_gen ├── api_changelog_gen ├── contributing_gen ├── architecture_gen├── analyzers/├── cli├── config ├── project_scanner ├── docstring_extractor ├── dependency_scanner ├── endpoint_detector```

code2docs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
README.md, API references, module docs, examples, and architecture diagrams.
66
"""
77

8-
__version__ = "3.0.2"
8+
__version__ = "3.0.3"
99
__author__ = "Tom Sapletta"
1010

1111
from .config import Code2DocsConfig

code2docs/generators/_registry_adapters.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ def run(self, ctx: GenerateContext) -> Optional[str]:
2525
preview = content[:500] + "..." if len(content) > 500 else content
2626
click.echo(preview)
2727
return None
28-
readme_path = ctx.project / self.config.readme_output
28+
# Use docs_dir if readme_output is a simple filename, otherwise respect the path
29+
readme_output = Path(self.config.readme_output)
30+
if readme_output.parent == Path("."):
31+
readme_path = ctx.docs_dir / readme_output.name
32+
else:
33+
readme_path = ctx.project / readme_output
2934
gen.write(str(readme_path), content)
3035
return f"✅ {readme_path.relative_to(ctx.project)}"
3136

@@ -141,7 +146,7 @@ def run(self, ctx: GenerateContext) -> Optional[str]:
141146
files = gen.generate_all()
142147
if ctx.dry_run:
143148
return f"[dry-run] examples/ ({len(files)} files)"
144-
examples_dir = ctx.project / "examples"
149+
examples_dir = ctx.docs_dir / "examples"
145150
gen.write_all(str(examples_dir), files)
146151
return f"✅ examples/ ({len(files)} files)"
147152

@@ -158,7 +163,7 @@ def run(self, ctx: GenerateContext) -> Optional[str]:
158163
content = gen.generate(str(ctx.docs_dir))
159164
if ctx.dry_run:
160165
return "[dry-run] mkdocs.yml"
161-
gen.write(str(ctx.project / "mkdocs.yml"), content)
166+
gen.write(str(ctx.docs_dir / "mkdocs.yml"), content)
162167
return "✅ mkdocs.yml"
163168

164169

@@ -208,7 +213,8 @@ def run(self, ctx: GenerateContext) -> Optional[str]:
208213
content = gen.generate()
209214
if ctx.dry_run:
210215
return "[dry-run] CONTRIBUTING.md"
211-
(ctx.project / "CONTRIBUTING.md").write_text(content, encoding="utf-8")
216+
ctx.docs_dir.mkdir(parents=True, exist_ok=True)
217+
(ctx.docs_dir / "CONTRIBUTING.md").write_text(content, encoding="utf-8")
212218
return "✅ CONTRIBUTING.md"
213219

214220

code2docs/generators/contributing_gen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ def _detect_dev_tools(self) -> Dict[str, bool]:
5454
def _render_setup(self, tools: Dict[str, bool]) -> str:
5555
"""Render development setup instructions."""
5656
project = self.config.project_name or "project"
57+
repo_url = self.config.repo_url or "<repository-url>"
5758
lines = [
5859
"## Development Setup\n",
5960
"```bash",
60-
f"git clone <repository-url>",
61+
f"git clone {repo_url}",
6162
f"cd {project}",
6263
"python -m venv .venv",
6364
"source .venv/bin/activate # or .venv\\Scripts\\activate on Windows",

code2docs/generators/getting_started_gen.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ def _render_installation(self) -> str:
5959
dep_scanner = DependencyScanner()
6060
deps = dep_scanner.scan(self.result.project_path)
6161
cmd = deps.install_command or f"pip install {self.config.project_name or '.'}"
62+
repo_url = self.config.repo_url or "<repository-url>"
6263
lines = [
6364
"## Installation\n",
6465
"```bash",
6566
cmd,
6667
"```\n",
6768
"To install from source:\n",
6869
"```bash",
69-
"git clone <repository-url>",
70+
f"git clone {repo_url}",
7071
f"cd {self.config.project_name or 'project'}",
7172
"pip install -e .",
7273
"```",

code2docs/project/analysis.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

code2docs/project/analysis.toon

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ CLASSES:
167167
ExamplesConfig 0m CC̄=0.0 max=0.0
168168
SyncConfig 0m CC̄=0.0 max=0.0
169169
Code2LlmConfig 0m CC̄=0.0 max=0.0
170-
DocstringInfo 0m CC̄=0.0 max=0.0
171170
DependencyInfo 0m CC̄=0.0 max=0.0
172171
ProjectDependencies 0m CC̄=0.0 max=0.0
172+
DocstringInfo 0m CC̄=0.0 max=0.0
173173
Endpoint 0m CC̄=0.0 max=0.0
174174

175175
D:
@@ -262,15 +262,6 @@ Thi...
262262
e: ContributingGenerator
263263
ContributingGenerator # Generate CONTRIBUTING.md by detecting dev tools from pyproje...
264264
__init__(2) CC=1.0
265-
analyzers/docstring_extractor.py:
266-
e: DocstringInfo,DocstringExtractor
267-
DocstringInfo # Parsed docstring with sections....
268-
DocstringExtractor # Extract and parse docstrings from AnalysisResult....
269-
extract_all(1) CC=5.0
270-
→ parse(1) CC=2.0
271-
→ _extract_summary(0) CC=2.0
272-
→ _parse_sections(2) CC=8.0
273-
→ _classify_section(0) CC=5.0
274265
analyzers/dependency_scanner.py:
275266
e: DependencyInfo,ProjectDependencies,DependencyScanner
276267
DependencyInfo # Information about a project dependency....
@@ -282,6 +273,15 @@ Thi...
282273
→ _parse_dep_string(0) CC=2.0
283274
→ _parse_setup_py(1) CC=4.0
284275
→ _parse_requirements_txt(1) CC=5.0
276+
analyzers/docstring_extractor.py:
277+
e: DocstringInfo,DocstringExtractor
278+
DocstringInfo # Parsed docstring with sections....
279+
DocstringExtractor # Extract and parse docstrings from AnalysisResult....
280+
extract_all(1) CC=5.0
281+
→ parse(1) CC=2.0
282+
→ _extract_summary(0) CC=2.0
283+
→ _parse_sections(2) CC=8.0
284+
→ _classify_section(0) CC=5.0
285285
llm_helper.py:
286286
e: LLMHelper,_get_litellm
287287
LLMHelper # Thin wrapper around litellm for documentation generation.

0 commit comments

Comments
 (0)