MCPcopy Create free account
hub / github.com/FSoft-AI4Code/CodeWiki / _detect_changes

Function _detect_changes

codewiki/mcp/tools/analysis.py:28–87  ·  view source on GitHub ↗

Detect changes since last documentation generation. Returns a changes dict with affected modules, or None if no previous generation exists (first run). Detection strategy: 1. Git-based: compare stored commit_id with current HEAD, plus check uncommitted changes via ``git

(
    repo_path: Path,
    output_dir: Path,
)

Source from the content-addressed store, hash-verified

26# ---------------------------------------------------------------------------
27
28
29def _detect_changes(
30 repo_path: Path,
31 output_dir: Path,
32) -> dict[str, Any] | None:
33 """Detect changes since last documentation generation.
34
35 Returns a changes dict with affected modules, or None if no previous
36 generation exists (first run).
37
38 Detection strategy:
39 1. Git-based: compare stored commit_id with current HEAD, plus check
40 uncommitted changes via ``git status``.
41 2. Fallback: compare file mtime with stored ``timestamp`` in metadata.
42 """
43 metadata_path = output_dir / "metadata.json"
44 module_tree_path = output_dir / "module_tree.json"
45
46 if not metadata_path.exists() or not module_tree_path.exists():
47 return None
48
49 try:
50 metadata = json.loads(metadata_path.read_text(encoding="utf-8"))
51 module_tree = json.loads(module_tree_path.read_text(encoding="utf-8"))
52 except (json.JSONDecodeError, OSError, UnicodeDecodeError):
53 return None
54
55 # Try git-based detection first
56 changes = _detect_via_git(repo_path, metadata, output_dir)
57
58 # Fallback to mtime-based detection
59 if changes is None:
60 changes = _detect_via_mtime(repo_path, metadata)
61
62 if changes is None:
63 return None
64
65 changed_files = changes["changed_files"]
66 if not changed_files:
67 return {
68 "has_previous": True,
69 "no_changes": True,
70 "method": changes.get("method", "unknown"),
71 "message": "No changes detected since last generation. Documentation is up to date.",
72 }
73
74 affected, cascade = _find_affected_modules(module_tree, changed_files)
75
76 return {
77 "has_previous": True,
78 "no_changes": False,
79 "method": changes.get("method", "unknown"),
80 "changed_files": changed_files,
81 "affected_modules": sorted(affected),
82 "cascade_modules": sorted(cascade),
83 "hint": (
84 f"Only {len(affected)} module(s) need updating: {sorted(affected)}. "
85 f"Parent modules to refresh: {sorted(cascade)}. "

Callers 1

handle_analyze_repoFunction · 0.85

Calls 4

_detect_via_gitFunction · 0.85
_detect_via_mtimeFunction · 0.85
_find_affected_modulesFunction · 0.85
getMethod · 0.80

Tested by

no test coverage detected