code2docs 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code2docs/__init__.py +32 -0
- code2docs/__main__.py +6 -0
- code2docs/analyzers/__init__.py +13 -0
- code2docs/analyzers/dependency_scanner.py +159 -0
- code2docs/analyzers/docstring_extractor.py +111 -0
- code2docs/analyzers/endpoint_detector.py +116 -0
- code2docs/analyzers/project_scanner.py +45 -0
- code2docs/cli.py +226 -0
- code2docs/config.py +158 -0
- code2docs/formatters/__init__.py +7 -0
- code2docs/formatters/badges.py +52 -0
- code2docs/formatters/markdown.py +73 -0
- code2docs/formatters/toc.py +63 -0
- code2docs/generators/__init__.py +42 -0
- code2docs/generators/api_reference_gen.py +150 -0
- code2docs/generators/architecture_gen.py +192 -0
- code2docs/generators/changelog_gen.py +121 -0
- code2docs/generators/examples_gen.py +194 -0
- code2docs/generators/module_docs_gen.py +204 -0
- code2docs/generators/readme_gen.py +229 -0
- code2docs/sync/__init__.py +6 -0
- code2docs/sync/differ.py +125 -0
- code2docs/sync/updater.py +77 -0
- code2docs/sync/watcher.py +75 -0
- code2docs/templates/api_module.md.j2 +62 -0
- code2docs/templates/architecture.md.j2 +45 -0
- code2docs/templates/example_usage.py.j2 +12 -0
- code2docs/templates/index.md.j2 +31 -0
- code2docs/templates/readme.md.j2 +85 -0
- code2docs-0.1.1.dist-info/METADATA +228 -0
- code2docs-0.1.1.dist-info/RECORD +35 -0
- code2docs-0.1.1.dist-info/WHEEL +5 -0
- code2docs-0.1.1.dist-info/entry_points.txt +2 -0
- code2docs-0.1.1.dist-info/licenses/LICENSE +201 -0
- code2docs-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""File watcher for auto-resync on source changes (requires watchdog)."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from ..config import Code2DocsConfig
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def start_watcher(project_path: str, config: Optional[Code2DocsConfig] = None) -> None:
|
|
11
|
+
"""Start watching project for file changes and auto-resync docs.
|
|
12
|
+
|
|
13
|
+
Requires watchdog package: pip install code2docs[watch]
|
|
14
|
+
"""
|
|
15
|
+
try:
|
|
16
|
+
from watchdog.observers import Observer
|
|
17
|
+
from watchdog.events import FileSystemEventHandler, FileModifiedEvent
|
|
18
|
+
except ImportError:
|
|
19
|
+
raise ImportError(
|
|
20
|
+
"watchdog is required for watch mode. "
|
|
21
|
+
"Install with: pip install code2docs[watch]"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
config = config or Code2DocsConfig()
|
|
25
|
+
project = Path(project_path).resolve()
|
|
26
|
+
|
|
27
|
+
class DocsHandler(FileSystemEventHandler):
|
|
28
|
+
"""Handler that triggers resync on Python file changes."""
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
self._last_trigger = 0.0
|
|
32
|
+
self._debounce_seconds = 2.0
|
|
33
|
+
|
|
34
|
+
def on_modified(self, event):
|
|
35
|
+
if not event.src_path.endswith(".py"):
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
# Check ignore patterns
|
|
39
|
+
rel = str(Path(event.src_path).relative_to(project))
|
|
40
|
+
for pattern in config.sync.ignore:
|
|
41
|
+
if pattern.rstrip("/") in rel:
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
# Debounce
|
|
45
|
+
now = time.time()
|
|
46
|
+
if now - self._last_trigger < self._debounce_seconds:
|
|
47
|
+
return
|
|
48
|
+
self._last_trigger = now
|
|
49
|
+
|
|
50
|
+
print(f" Change detected: {rel}")
|
|
51
|
+
try:
|
|
52
|
+
from .differ import Differ
|
|
53
|
+
from .updater import Updater
|
|
54
|
+
|
|
55
|
+
differ = Differ(config)
|
|
56
|
+
changes = differ.detect_changes(str(project))
|
|
57
|
+
if changes:
|
|
58
|
+
print(f" Regenerating {len(changes)} changed modules...")
|
|
59
|
+
updater = Updater(config)
|
|
60
|
+
updater.apply(str(project), changes)
|
|
61
|
+
print(" Done.")
|
|
62
|
+
except Exception as e:
|
|
63
|
+
print(f" Error during resync: {e}")
|
|
64
|
+
|
|
65
|
+
handler = DocsHandler()
|
|
66
|
+
observer = Observer()
|
|
67
|
+
observer.schedule(handler, str(project), recursive=True)
|
|
68
|
+
observer.start()
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
while True:
|
|
72
|
+
time.sleep(1)
|
|
73
|
+
except KeyboardInterrupt:
|
|
74
|
+
observer.stop()
|
|
75
|
+
observer.join()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# `{{ module_name }}`
|
|
2
|
+
|
|
3
|
+
> Source: `{{ module_info.file }}`
|
|
4
|
+
|
|
5
|
+
{% if classes %}
|
|
6
|
+
## Classes
|
|
7
|
+
|
|
8
|
+
{% for cls_name, cls_info in classes.items() %}
|
|
9
|
+
### `{{ cls_info.name }}`
|
|
10
|
+
|
|
11
|
+
{% if cls_info.bases %}
|
|
12
|
+
Inherits from: {% for b in cls_info.bases %}`{{ b }}`{% if not loop.last %}, {% endif %}{% endfor %}
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% if cls_info.docstring %}
|
|
16
|
+
{{ cls_info.docstring }}
|
|
17
|
+
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% if methods[cls_name] %}
|
|
20
|
+
#### Methods
|
|
21
|
+
|
|
22
|
+
{% for method in methods[cls_name] %}
|
|
23
|
+
{% set args = method.args|join(', ') %}
|
|
24
|
+
{% set ret = ' → ' ~ method.returns if method.returns else '' %}
|
|
25
|
+
{% set cc = method.complexity.get('cyclomatic', 0) %}
|
|
26
|
+
- `{{ method.name }}({{ args }}){{ ret }}`{% if method.docstring %} — {{ method.docstring.split('\n')[0] }}{% endif %}{% if cc > 10 %} ⚠️ CC={{ cc }}{% endif %}
|
|
27
|
+
|
|
28
|
+
{% endfor %}
|
|
29
|
+
{% endif %}
|
|
30
|
+
{% endfor %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
{% if functions %}
|
|
34
|
+
## Functions
|
|
35
|
+
|
|
36
|
+
{% for func_name, func in functions.items() %}
|
|
37
|
+
{% set args = func.args|join(', ') %}
|
|
38
|
+
{% set ret = ' → ' ~ func.returns if func.returns else '' %}
|
|
39
|
+
### `{{ func.name }}({{ args }}){{ ret }}`
|
|
40
|
+
|
|
41
|
+
{% if func.docstring %}
|
|
42
|
+
{{ func.docstring }}
|
|
43
|
+
|
|
44
|
+
{% endif %}
|
|
45
|
+
{% set cc = func.complexity.get('cyclomatic', 0) %}
|
|
46
|
+
{% if cc %}
|
|
47
|
+
- Complexity: {{ cc }}
|
|
48
|
+
{% endif %}
|
|
49
|
+
{% if func.calls %}
|
|
50
|
+
- Calls: {% for c in func.calls[:10] %}`{{ c }}`{% if not loop.last %}, {% endif %}{% endfor %}
|
|
51
|
+
|
|
52
|
+
{% endif %}
|
|
53
|
+
{% endfor %}
|
|
54
|
+
{% endif %}
|
|
55
|
+
|
|
56
|
+
{% if module_info.imports %}
|
|
57
|
+
## Imports
|
|
58
|
+
|
|
59
|
+
{% for imp in module_info.imports|sort %}
|
|
60
|
+
- `{{ imp }}`
|
|
61
|
+
{% endfor %}
|
|
62
|
+
{% endif %}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# {{ project_name }} — Architecture
|
|
2
|
+
|
|
3
|
+
> Auto-generated from {{ module_count }} modules, {{ function_count }} functions, {{ class_count }} classes
|
|
4
|
+
|
|
5
|
+
## Module Dependency Graph
|
|
6
|
+
|
|
7
|
+
{{ module_graph }}
|
|
8
|
+
|
|
9
|
+
{% if layers %}
|
|
10
|
+
## Architecture Layers
|
|
11
|
+
|
|
12
|
+
{% for layer_name, modules in layers.items() %}
|
|
13
|
+
### {{ layer_name }}
|
|
14
|
+
|
|
15
|
+
{% for mod in modules %}
|
|
16
|
+
- `{{ mod }}`
|
|
17
|
+
{% endfor %}
|
|
18
|
+
|
|
19
|
+
{% endfor %}
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
## Key Classes
|
|
23
|
+
|
|
24
|
+
{{ class_diagram }}
|
|
25
|
+
|
|
26
|
+
{% if patterns %}
|
|
27
|
+
## Detected Patterns
|
|
28
|
+
|
|
29
|
+
{% for pattern in patterns %}
|
|
30
|
+
- **{{ pattern.name }}** ({{ pattern.type }}) — confidence: {{ "%.0f%%"|format(pattern.confidence * 100) }}, functions: {% for f in pattern.functions[:5] %}`{{ f }}`{% if not loop.last %}, {% endif %}{% endfor %}
|
|
31
|
+
|
|
32
|
+
{% endfor %}
|
|
33
|
+
{% endif %}
|
|
34
|
+
|
|
35
|
+
{% if entry_points %}
|
|
36
|
+
## Entry Points
|
|
37
|
+
|
|
38
|
+
{% for ep in entry_points %}
|
|
39
|
+
- `{{ ep }}`
|
|
40
|
+
{% endfor %}
|
|
41
|
+
{% endif %}
|
|
42
|
+
|
|
43
|
+
## Metrics Summary
|
|
44
|
+
|
|
45
|
+
{{ metrics_table }}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# {{ project_name }} — Documentation
|
|
2
|
+
|
|
3
|
+
> Auto-generated by [code2docs](https://github.com/wronai/code2docs)
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Architecture](architecture.md)
|
|
8
|
+
{% if api_reference %}
|
|
9
|
+
- [API Reference](api/index.md)
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% if module_docs %}
|
|
12
|
+
- [Module Documentation](modules/)
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% if changelog %}
|
|
15
|
+
- [Changelog](changelog.md)
|
|
16
|
+
{% endif %}
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
| Metric | Value |
|
|
21
|
+
|--------|-------|
|
|
22
|
+
| Modules | {{ module_count }} |
|
|
23
|
+
| Functions | {{ function_count }} |
|
|
24
|
+
| Classes | {{ class_count }} |
|
|
25
|
+
{% if avg_complexity %}
|
|
26
|
+
| Avg Complexity | {{ avg_complexity }} |
|
|
27
|
+
{% endif %}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
*Generated on {{ generated_date }} by code2docs v{{ version }}*
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{% if sync_markers %}<!-- code2docs:start -->{% endif %}
|
|
2
|
+
# {{ project_name }}
|
|
3
|
+
|
|
4
|
+
{% if badges %}{{ badges }}{% endif %}
|
|
5
|
+
|
|
6
|
+
{% if "overview" in sections %}
|
|
7
|
+
> **{{ stats.get('functions_found', 0) }}** functions | **{{ stats.get('classes_found', 0) }}** classes | **{{ stats.get('files_processed', 0) }}** files | CC̄ = {{ avg_complexity }}
|
|
8
|
+
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% if "install" in sections and dependencies and dependencies.install_command %}
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
{{ dependencies.install_command }}
|
|
15
|
+
```
|
|
16
|
+
{% if dependencies.python_version %}
|
|
17
|
+
Requires Python {{ dependencies.python_version }}
|
|
18
|
+
{% endif %}
|
|
19
|
+
|
|
20
|
+
{% if dependencies.dependencies %}
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
{% for dep in dependencies.dependencies %}
|
|
24
|
+
- `{{ dep.name }}` {{ dep.version_spec }}
|
|
25
|
+
{% endfor %}
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% endif %}
|
|
28
|
+
|
|
29
|
+
{% if "quickstart" in sections %}
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
{% if entry_points %}
|
|
33
|
+
```python
|
|
34
|
+
{% for ep in entry_points[:3] %}
|
|
35
|
+
# Entry point: {{ ep }}
|
|
36
|
+
{% endfor %}
|
|
37
|
+
```
|
|
38
|
+
{% else %}
|
|
39
|
+
```python
|
|
40
|
+
import {{ project_name }}
|
|
41
|
+
```
|
|
42
|
+
{% endif %}
|
|
43
|
+
{% endif %}
|
|
44
|
+
|
|
45
|
+
{% if "api" in sections %}
|
|
46
|
+
## API Overview
|
|
47
|
+
|
|
48
|
+
{% if public_classes %}
|
|
49
|
+
### Classes
|
|
50
|
+
|
|
51
|
+
{% for name, cls in public_classes.items()|list %}
|
|
52
|
+
- **`{{ cls.name }}`**{% if cls.docstring %} — {{ cls.docstring.split('\n')[0] }}{% endif %}
|
|
53
|
+
|
|
54
|
+
{% endfor %}
|
|
55
|
+
{% endif %}
|
|
56
|
+
|
|
57
|
+
{% if public_functions %}
|
|
58
|
+
### Functions
|
|
59
|
+
|
|
60
|
+
{% for name, func in public_functions.items()|list %}
|
|
61
|
+
{% set args = func.args|join(', ') %}
|
|
62
|
+
{% set ret = ' → ' ~ func.returns if func.returns else '' %}
|
|
63
|
+
- `{{ func.name }}({{ args }}){{ ret }}`{% if func.docstring %} — {{ func.docstring.split('\n')[0] }}{% endif %}
|
|
64
|
+
|
|
65
|
+
{% endfor %}
|
|
66
|
+
{% endif %}
|
|
67
|
+
{% endif %}
|
|
68
|
+
|
|
69
|
+
{% if "structure" in sections and module_tree %}
|
|
70
|
+
## Project Structure
|
|
71
|
+
|
|
72
|
+
{{ module_tree }}
|
|
73
|
+
{% endif %}
|
|
74
|
+
|
|
75
|
+
{% if "endpoints" in sections and endpoints %}
|
|
76
|
+
## Endpoints
|
|
77
|
+
|
|
78
|
+
| Method | Path | Function | Framework |
|
|
79
|
+
|--------|------|----------|-----------|
|
|
80
|
+
{% for ep in endpoints %}
|
|
81
|
+
| {{ ep.method }} | `{{ ep.path }}` | `{{ ep.function_name }}` | {{ ep.framework }} |
|
|
82
|
+
{% endfor %}
|
|
83
|
+
{% endif %}
|
|
84
|
+
|
|
85
|
+
{% if sync_markers %}<!-- code2docs:end -->{% endif %}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: code2docs
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Auto-generate and sync project documentation from source code analysis
|
|
5
|
+
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/wronai/code2docs
|
|
8
|
+
Project-URL: Repository, https://github.com/wronai/code2docs
|
|
9
|
+
Project-URL: Issues, https://github.com/wronai/code2docs/issues
|
|
10
|
+
Keywords: documentation,auto-docs,readme-generator,api-reference,code-analysis,static-analysis,markdown
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
20
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: code2llm>=0.5.0
|
|
25
|
+
Requires-Dist: jinja2>=3.1
|
|
26
|
+
Requires-Dist: click>=8.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Provides-Extra: watch
|
|
29
|
+
Requires-Dist: watchdog>=3.0; extra == "watch"
|
|
30
|
+
Provides-Extra: mkdocs
|
|
31
|
+
Requires-Dist: mkdocs>=1.5; extra == "mkdocs"
|
|
32
|
+
Requires-Dist: mkdocs-material>=9.0; extra == "mkdocs"
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
36
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
37
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# code2docs
|
|
42
|
+
|
|
43
|
+
  
|
|
44
|
+
|
|
45
|
+
> Auto-generate and sync project documentation from source code analysis.
|
|
46
|
+
|
|
47
|
+
**code2docs** uses [code2llm](https://github.com/wronai/code2llm)'s `AnalysisResult` to produce human-readable documentation: README.md, API references, module docs, usage examples, and architecture diagrams.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
code2llm → AnalysisResult → .toon / .mmd / context.md (for LLM)
|
|
51
|
+
code2docs → AnalysisResult → README.md / docs/ / examples/ (for humans)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install code2docs
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or from source:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/wronai/code2docs
|
|
64
|
+
cd code2docs
|
|
65
|
+
pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Optional extras
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install code2docs[watch] # file watcher (watchdog)
|
|
72
|
+
pip install code2docs[mkdocs] # MkDocs integration
|
|
73
|
+
pip install code2docs[dev] # development tools
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Generate full documentation for a project
|
|
80
|
+
code2docs ./my-project
|
|
81
|
+
|
|
82
|
+
# Generate only README
|
|
83
|
+
code2docs ./my-project --readme-only
|
|
84
|
+
|
|
85
|
+
# Sync (regenerate only changed modules)
|
|
86
|
+
code2docs sync ./my-project
|
|
87
|
+
|
|
88
|
+
# Watch mode (auto-resync on file changes)
|
|
89
|
+
code2docs watch ./my-project
|
|
90
|
+
|
|
91
|
+
# Initialize config file
|
|
92
|
+
code2docs init ./my-project
|
|
93
|
+
|
|
94
|
+
# Dry-run (show what would be generated)
|
|
95
|
+
code2docs ./my-project --dry-run
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Python API
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from code2docs import generate_readme, generate_docs, Code2DocsConfig
|
|
102
|
+
|
|
103
|
+
# Generate README
|
|
104
|
+
generate_readme("./my-project", output="README.md")
|
|
105
|
+
|
|
106
|
+
# Generate full docs with custom config
|
|
107
|
+
config = Code2DocsConfig(project_name="mylib", verbose=True)
|
|
108
|
+
docs = generate_docs("./my-project", config=config)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Generated Output
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
<project>/
|
|
115
|
+
├── README.md # Main README (auto-generated sections)
|
|
116
|
+
├── docs/
|
|
117
|
+
│ ├── index.md # Documentation index
|
|
118
|
+
│ ├── architecture.md # Architecture + Mermaid diagrams
|
|
119
|
+
│ ├── api/
|
|
120
|
+
│ │ ├── index.md # API overview
|
|
121
|
+
│ │ ├── module_analyzer.md # Per-module API reference
|
|
122
|
+
│ │ └── ...
|
|
123
|
+
│ └── modules/
|
|
124
|
+
│ ├── analyzer.md # Detailed module documentation
|
|
125
|
+
│ └── ...
|
|
126
|
+
├── examples/
|
|
127
|
+
│ ├── basic_usage.py # Auto-generated usage example
|
|
128
|
+
│ ├── class_examples.py # Class usage examples
|
|
129
|
+
│ └── ...
|
|
130
|
+
└── code2docs.yaml # Generator configuration
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Configuration
|
|
134
|
+
|
|
135
|
+
Create `code2docs.yaml` in your project root (or run `code2docs init`):
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
project:
|
|
139
|
+
name: my-project
|
|
140
|
+
source: ./
|
|
141
|
+
output: ./docs/
|
|
142
|
+
|
|
143
|
+
readme:
|
|
144
|
+
sections:
|
|
145
|
+
- overview
|
|
146
|
+
- install
|
|
147
|
+
- quickstart
|
|
148
|
+
- api
|
|
149
|
+
- structure
|
|
150
|
+
- endpoints
|
|
151
|
+
badges:
|
|
152
|
+
- version
|
|
153
|
+
- python
|
|
154
|
+
- coverage
|
|
155
|
+
- complexity
|
|
156
|
+
sync_markers: true
|
|
157
|
+
|
|
158
|
+
docs:
|
|
159
|
+
api_reference: true
|
|
160
|
+
module_docs: true
|
|
161
|
+
architecture: true
|
|
162
|
+
changelog: true
|
|
163
|
+
|
|
164
|
+
examples:
|
|
165
|
+
auto_generate: true
|
|
166
|
+
from_entry_points: true
|
|
167
|
+
|
|
168
|
+
sync:
|
|
169
|
+
strategy: markers # markers | full | git-diff
|
|
170
|
+
watch: false
|
|
171
|
+
ignore:
|
|
172
|
+
- "tests/"
|
|
173
|
+
- "__pycache__"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Sync Markers
|
|
177
|
+
|
|
178
|
+
code2docs can update only specific sections of an existing README using markers:
|
|
179
|
+
|
|
180
|
+
```markdown
|
|
181
|
+
<!-- code2docs:start -->
|
|
182
|
+
... auto-generated content ...
|
|
183
|
+
<!-- code2docs:end -->
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Content outside markers is preserved.
|
|
187
|
+
|
|
188
|
+
## Architecture
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
code2docs/
|
|
192
|
+
├── cli.py # CLI (click-based)
|
|
193
|
+
├── config.py # Configuration (code2docs.yaml)
|
|
194
|
+
├── analyzers/ # Adapters to code2llm + custom detectors
|
|
195
|
+
│ ├── project_scanner.py # Wrapper on code2llm.ProjectAnalyzer
|
|
196
|
+
│ ├── endpoint_detector.py # Flask/FastAPI/Django route extraction
|
|
197
|
+
│ ├── docstring_extractor.py
|
|
198
|
+
│ └── dependency_scanner.py
|
|
199
|
+
├── generators/ # Documentation generators
|
|
200
|
+
│ ├── readme_gen.py # README.md generator
|
|
201
|
+
│ ├── api_reference_gen.py # docs/api/ reference from signatures
|
|
202
|
+
│ ├── module_docs_gen.py # docs/modules/ per-module docs
|
|
203
|
+
│ ├── examples_gen.py # examples/ from signatures
|
|
204
|
+
│ ├── changelog_gen.py # CHANGELOG from git log
|
|
205
|
+
│ └── architecture_gen.py # Architecture + Mermaid diagrams
|
|
206
|
+
├── templates/ # Jinja2 templates
|
|
207
|
+
├── sync/ # Change detection & selective regeneration
|
|
208
|
+
│ ├── differ.py
|
|
209
|
+
│ ├── updater.py
|
|
210
|
+
│ └── watcher.py
|
|
211
|
+
└── formatters/ # Markdown, badges, TOC
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Requirements
|
|
215
|
+
|
|
216
|
+
- Python >= 3.9
|
|
217
|
+
- [code2llm](https://github.com/wronai/code2llm) >= 0.5.0
|
|
218
|
+
- Jinja2 >= 3.1
|
|
219
|
+
- Click >= 8.0
|
|
220
|
+
- PyYAML >= 6.0
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
Apache License 2.0 - see [LICENSE](LICENSE) for details.
|
|
225
|
+
|
|
226
|
+
## Author
|
|
227
|
+
|
|
228
|
+
Created by **Tom Sapletta** - [tom@sapletta.com](mailto:tom@sapletta.com)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
code2docs/__init__.py,sha256=SVjnL6qDNfeTiIDxrMLSA5nUCxBOHsskx-MRtv2HrFQ,958
|
|
2
|
+
code2docs/__main__.py,sha256=dGGkQIZVFDZXEXa9PWew7cBh7hBAYDWfJ9LeezMf2UI,116
|
|
3
|
+
code2docs/cli.py,sha256=eIqzRk43rJbK2uJ_nVyRh3b7N_q9DR5bhntess3CxKc,8317
|
|
4
|
+
code2docs/config.py,sha256=uDEehtGBtZGW9wOHGADzRF-1leoHCtSfHU_-gKusTcI,5377
|
|
5
|
+
code2docs/analyzers/__init__.py,sha256=lIvbHr8JCuYTd8QJNsR7RANLFdlpIMJEsv-lMO7Avdc,370
|
|
6
|
+
code2docs/analyzers/dependency_scanner.py,sha256=bnPAR9VE1tJNcYTf_4BjF2NG5lv-mswPC_kYgATjljg,5409
|
|
7
|
+
code2docs/analyzers/docstring_extractor.py,sha256=lrjtDh6NLgk-ZTy8BlqbCL0W9pIJP0fIMhfDWuS7G6U,4194
|
|
8
|
+
code2docs/analyzers/endpoint_detector.py,sha256=os7mFpMnLhFL9UaU1aO8hpuRa1oeZspAW97kzj5z1mg,3940
|
|
9
|
+
code2docs/analyzers/project_scanner.py,sha256=igtIvr-DFRNPCmaRjQyODu2uyzdPynM6OAIAVePg3W8,1759
|
|
10
|
+
code2docs/formatters/__init__.py,sha256=3-myGxFceSgOW3g1eQFUJO3tEDF03MbG-7WL1WEylk4,240
|
|
11
|
+
code2docs/formatters/badges.py,sha256=zd3Us9n1-ZVcQTR9GtskHrwaBqBWcKJ_5wL_swNaQT8,1737
|
|
12
|
+
code2docs/formatters/markdown.py,sha256=umUvUyKVuvvT-SysWV6xgEQWpc-_UiR9Trf3hodUyBs,2294
|
|
13
|
+
code2docs/formatters/toc.py,sha256=EBynYUlgkk5W5_QqsRHWbIW2Cfpk3sJulk3FvURHK60,1770
|
|
14
|
+
code2docs/generators/__init__.py,sha256=ijLywzOaI_Rl-Bj8Q-SG2AGQMVR8v4ydrbD89f6Ulzk,1323
|
|
15
|
+
code2docs/generators/api_reference_gen.py,sha256=d-tuf4G2XuYzVl2CPFOW-imGjomhSCjN4HrC4N0RLAk,5982
|
|
16
|
+
code2docs/generators/architecture_gen.py,sha256=O3RaOU4SSNF625EtLzVlYKA_ZSKqPKh6mTPkgg0oP90,7322
|
|
17
|
+
code2docs/generators/changelog_gen.py,sha256=6Vcj02tITC2jhnf53sE841N3vsB7VO9nOKTYq7Oi-cM,4007
|
|
18
|
+
code2docs/generators/examples_gen.py,sha256=6sa11Nab9AnJ7PsGw6CuYXnRRZo0LQrwanGbQQMIKDE,7473
|
|
19
|
+
code2docs/generators/module_docs_gen.py,sha256=Vou6_5GpHat52OmaT8dowGHJJBVo46tJx-C6qWZnyxE,8233
|
|
20
|
+
code2docs/generators/readme_gen.py,sha256=BE-XWic51yf9jihQEcBKn0CeLqOAbSVz5ss-suReCCw,8699
|
|
21
|
+
code2docs/sync/__init__.py,sha256=MOTJYvJXPZF-4PS47lv-6bOc9J2ZoQGoIchp3vIuwrU,162
|
|
22
|
+
code2docs/sync/differ.py,sha256=XqYDhxTM53AOCsbNrB_R3KVawg-an9YqUjPmyKsBS0I,4167
|
|
23
|
+
code2docs/sync/updater.py,sha256=xlDX2YahgcUY1p0KkKrAmnWb1OEeePmBcYR_1sUrV4o,3100
|
|
24
|
+
code2docs/sync/watcher.py,sha256=HvY4aK-WhCUrYEXoNFoQihBkith_JZHKwVKQV07CIJc,2392
|
|
25
|
+
code2docs/templates/api_module.md.j2,sha256=mn8rH6YRlo1JIr0m8I6JkEvkhDCMOszfl9CEwEEZLAI,1485
|
|
26
|
+
code2docs/templates/architecture.md.j2,sha256=kx_lECcC9FGHTEnhgPNVGIijDFXu5xFcm4wMHC85lNg,881
|
|
27
|
+
code2docs/templates/example_usage.py.j2,sha256=G0mF7iLtisnsh-PfPTMLgVoNSDw6J-MqPndzMTtcuJk,225
|
|
28
|
+
code2docs/templates/index.md.j2,sha256=pj56gwiLuXxV64xVYfzmtboMLyFKF-Kty01Ps0t37xM,653
|
|
29
|
+
code2docs/templates/readme.md.j2,sha256=xG_vImqOGZKasRbQBuIunWQGaOEA_rjmtIpp8HJHm6U,2043
|
|
30
|
+
code2docs-0.1.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
31
|
+
code2docs-0.1.1.dist-info/METADATA,sha256=cDRE_OuSQvV2wJWGb_Y-aSEOMDx1PtFYuoKpdSzt8dM,6620
|
|
32
|
+
code2docs-0.1.1.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
|
|
33
|
+
code2docs-0.1.1.dist-info/entry_points.txt,sha256=ATamjPNo2CbTaAUN3LfK8qrnY3EQE9gE7lMDgPYhLdQ,49
|
|
34
|
+
code2docs-0.1.1.dist-info/top_level.txt,sha256=L-O2M4M-NSiphgcKSfXFsC-t6PqziMl8Ef6tsNR2DaM,10
|
|
35
|
+
code2docs-0.1.1.dist-info/RECORD,,
|