code2docs 0.1.6__tar.gz → 0.2.1__tar.gz
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-0.1.6 → code2docs-0.2.1}/PKG-INFO +3 -3
- {code2docs-0.1.6 → code2docs-0.2.1}/README.md +2 -2
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/__init__.py +1 -1
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/depgraph_gen.py +33 -5
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/PKG-INFO +3 -3
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/SOURCES.txt +1 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/pyproject.toml +1 -1
- code2docs-0.2.1/tests/test_cli.py +67 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/LICENSE +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/__main__.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/analyzers/__init__.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/analyzers/dependency_scanner.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/analyzers/docstring_extractor.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/analyzers/endpoint_detector.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/analyzers/project_scanner.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/cli.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/config.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/formatters/__init__.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/formatters/badges.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/formatters/markdown.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/formatters/toc.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/__init__.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/api_changelog_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/api_reference_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/architecture_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/changelog_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/coverage_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/examples_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/mkdocs_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/module_docs_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/generators/readme_gen.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/sync/__init__.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/sync/differ.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/sync/updater.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/sync/watcher.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/api_module.md.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/architecture.md.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/example_usage.py.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/index.md.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/module_doc.md.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs/templates/readme.md.j2 +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/dependency_links.txt +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/entry_points.txt +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/requires.txt +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/code2docs.egg-info/top_level.txt +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/setup.cfg +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_analyzers.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_code2docs.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_config.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_formatters.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_generators.py +0 -0
- {code2docs-0.1.6 → code2docs-0.2.1}/tests/test_sync.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2docs
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Auto-generate and sync project documentation from source code analysis
|
|
5
5
|
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -40,7 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
# code2docs
|
|
42
42
|
|
|
43
|
-
  
|
|
44
44
|
|
|
45
45
|
> Auto-generate and sync project documentation from source code analysis.
|
|
46
46
|
|
|
@@ -180,7 +180,7 @@ code2docs can update only specific sections of an existing README using markers:
|
|
|
180
180
|
```markdown
|
|
181
181
|
<!-- code2docs:start --># code2docs
|
|
182
182
|
|
|
183
|
-
   
|
|
184
184
|
> **153** functions | **30** classes | **28** files | CC̄ = 0.0
|
|
185
185
|
|
|
186
186
|
## Installation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# code2docs
|
|
2
2
|
|
|
3
|
-
  
|
|
4
4
|
|
|
5
5
|
> Auto-generate and sync project documentation from source code analysis.
|
|
6
6
|
|
|
@@ -140,7 +140,7 @@ code2docs can update only specific sections of an existing README using markers:
|
|
|
140
140
|
```markdown
|
|
141
141
|
<!-- code2docs:start --># code2docs
|
|
142
142
|
|
|
143
|
-
   
|
|
144
144
|
> **153** functions | **30** classes | **28** files | CC̄ = 0.0
|
|
145
145
|
|
|
146
146
|
## Installation
|
|
@@ -5,7 +5,7 @@ Uses code2llm's AnalysisResult to produce human-readable documentation:
|
|
|
5
5
|
README.md, API references, module docs, examples, and architecture diagrams.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "0.1
|
|
8
|
+
__version__ = "0.2.1"
|
|
9
9
|
__author__ = "Tom Sapletta"
|
|
10
10
|
|
|
11
11
|
from .config import Code2DocsConfig
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Dependency graph generator — Mermaid diagram from coupling matrix."""
|
|
2
2
|
|
|
3
|
+
import ast
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
from typing import Dict, List, Set, Tuple
|
|
4
6
|
|
|
5
7
|
from code2llm.api import AnalysisResult, ModuleInfo
|
|
@@ -37,16 +39,42 @@ class DepGraphGenerator:
|
|
|
37
39
|
return "\n".join(lines)
|
|
38
40
|
|
|
39
41
|
def _collect_edges(self) -> List[Tuple[str, str]]:
|
|
40
|
-
"""Build directed edges from module imports.
|
|
41
|
-
|
|
42
|
+
"""Build directed edges from module imports.
|
|
43
|
+
|
|
44
|
+
Uses ModuleInfo.imports when available, otherwise extracts
|
|
45
|
+
imports from the source file via AST.
|
|
46
|
+
"""
|
|
47
|
+
edges: Set[Tuple[str, str]] = set()
|
|
42
48
|
module_names = set(self.result.modules.keys())
|
|
43
49
|
|
|
44
50
|
for mod_name, mod_info in self.result.modules.items():
|
|
45
|
-
|
|
51
|
+
imports = mod_info.imports
|
|
52
|
+
if not imports:
|
|
53
|
+
imports = self._extract_imports_from_file(mod_info.file)
|
|
54
|
+
for imp in imports:
|
|
46
55
|
for other in module_names:
|
|
47
56
|
if mod_name != other and self._import_matches(imp, other):
|
|
48
|
-
edges.
|
|
49
|
-
return sorted(
|
|
57
|
+
edges.add((mod_name, other))
|
|
58
|
+
return sorted(edges)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def _extract_imports_from_file(file_path: str) -> List[str]:
|
|
62
|
+
"""Parse source file AST to extract import targets."""
|
|
63
|
+
try:
|
|
64
|
+
source = Path(file_path).read_text(encoding="utf-8")
|
|
65
|
+
tree = ast.parse(source)
|
|
66
|
+
except Exception:
|
|
67
|
+
return []
|
|
68
|
+
|
|
69
|
+
imports: List[str] = []
|
|
70
|
+
for node in ast.walk(tree):
|
|
71
|
+
if isinstance(node, ast.Import):
|
|
72
|
+
for alias in node.names:
|
|
73
|
+
imports.append(alias.name)
|
|
74
|
+
elif isinstance(node, ast.ImportFrom):
|
|
75
|
+
if node.module:
|
|
76
|
+
imports.append(node.module)
|
|
77
|
+
return imports
|
|
50
78
|
|
|
51
79
|
@staticmethod
|
|
52
80
|
def _import_matches(imp: str, module: str) -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2docs
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Auto-generate and sync project documentation from source code analysis
|
|
5
5
|
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -40,7 +40,7 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
# code2docs
|
|
42
42
|
|
|
43
|
-
  
|
|
44
44
|
|
|
45
45
|
> Auto-generate and sync project documentation from source code analysis.
|
|
46
46
|
|
|
@@ -180,7 +180,7 @@ code2docs can update only specific sections of an existing README using markers:
|
|
|
180
180
|
```markdown
|
|
181
181
|
<!-- code2docs:start --># code2docs
|
|
182
182
|
|
|
183
|
-
   
|
|
184
184
|
> **153** functions | **30** classes | **28** files | CC̄ = 0.0
|
|
185
185
|
|
|
186
186
|
## Installation
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""CLI smoke tests using Click's CliRunner."""
|
|
2
|
+
|
|
3
|
+
import tempfile
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from click.testing import CliRunner
|
|
7
|
+
|
|
8
|
+
from code2docs.cli import main
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestCLI:
|
|
12
|
+
def setup_method(self):
|
|
13
|
+
self.runner = CliRunner()
|
|
14
|
+
|
|
15
|
+
def test_help(self):
|
|
16
|
+
result = self.runner.invoke(main, ["--help"])
|
|
17
|
+
assert result.exit_code == 0
|
|
18
|
+
assert "code2docs" in result.output
|
|
19
|
+
assert "generate" in result.output
|
|
20
|
+
assert "sync" in result.output
|
|
21
|
+
assert "init" in result.output
|
|
22
|
+
|
|
23
|
+
def test_generate_help(self):
|
|
24
|
+
result = self.runner.invoke(main, ["generate", "--help"])
|
|
25
|
+
assert result.exit_code == 0
|
|
26
|
+
assert "--readme-only" in result.output
|
|
27
|
+
assert "--dry-run" in result.output
|
|
28
|
+
assert "--verbose" in result.output
|
|
29
|
+
|
|
30
|
+
def test_sync_help(self):
|
|
31
|
+
result = self.runner.invoke(main, ["sync", "--help"])
|
|
32
|
+
assert result.exit_code == 0
|
|
33
|
+
assert "Synchronize" in result.output
|
|
34
|
+
|
|
35
|
+
def test_init_creates_config(self):
|
|
36
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
37
|
+
result = self.runner.invoke(main, ["init", tmpdir])
|
|
38
|
+
assert result.exit_code == 0
|
|
39
|
+
assert (Path(tmpdir) / "code2docs.yaml").exists()
|
|
40
|
+
|
|
41
|
+
def test_generate_dry_run(self):
|
|
42
|
+
result = self.runner.invoke(main, [".", "--dry-run"])
|
|
43
|
+
assert result.exit_code == 0
|
|
44
|
+
assert "code2docs" in result.output
|
|
45
|
+
assert "README.md" in result.output
|
|
46
|
+
assert "dry-run" in result.output
|
|
47
|
+
assert "Done!" in result.output
|
|
48
|
+
|
|
49
|
+
def test_readme_only_dry_run(self):
|
|
50
|
+
result = self.runner.invoke(main, [".", "--readme-only", "--dry-run"])
|
|
51
|
+
assert result.exit_code == 0
|
|
52
|
+
assert "README.md" in result.output
|
|
53
|
+
# Should NOT have docs/api since --readme-only
|
|
54
|
+
assert "docs/api" not in result.output
|
|
55
|
+
|
|
56
|
+
def test_default_group_routes_path(self):
|
|
57
|
+
"""Ensure bare path argument is routed to generate."""
|
|
58
|
+
result = self.runner.invoke(main, [".", "--dry-run"])
|
|
59
|
+
assert result.exit_code == 0
|
|
60
|
+
assert "Done!" in result.output
|
|
61
|
+
|
|
62
|
+
def test_verbose(self):
|
|
63
|
+
result = self.runner.invoke(main, [".", "--verbose", "--dry-run"])
|
|
64
|
+
assert result.exit_code == 0
|
|
65
|
+
assert "Functions:" in result.output
|
|
66
|
+
assert "Classes:" in result.output
|
|
67
|
+
assert "Modules:" in result.output
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|