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

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