Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions code_review_graph/changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,19 @@ def analyze_changes(
for key, ranges in parse_diff_ranges(repo_root, base).items()
}

# The affected-flows lookup and the no-ranges fallback match
# changed_files against nodes.file_path, which stores absolute
# normalized paths. CLI callers pass repo-relative diff paths, so an
# exact IN (...) match finds no nodes and detect-changes reports
# "0 affected flow(s)" even when the MCP tool reports hundreds on the
# same input (#848). Remap the same way as changed_ranges keys;
# already-absolute inputs (MCP) pass through pathlib joining unchanged.
if repo_root is not None:
_root = Path(repo_root)
changed_files = [
normalize_file_path(_root / fp) for fp in changed_files
]

# Map changes to nodes.
if changed_ranges:
changed_nodes = map_changes_to_nodes(store, changed_ranges)
Expand Down
29 changes: 29 additions & 0 deletions tests/test_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,35 @@ def test_analyze_changes_with_flows(self):
)
assert len(result["affected_flows"]) >= 1

def test_analyze_changes_flows_with_relative_cli_paths(self):
"""Relative changed_files still hit flows stored under absolute paths.

Real builds store absolute node paths while the CLI passes
repo-relative diff paths, which made detect-changes report
"0 affected flow(s)" where the MCP tool reported them (#848).
"""
repo_root = "/repo" if not Path("C:/").exists() else "C:/repo"
routes_abs = f"{repo_root}/routes.py"
services_abs = f"{repo_root}/services.py"
self._add_func("handler", path=routes_abs, line_start=1, line_end=10)
self._add_func("service", path=services_abs, line_start=1, line_end=10)
self._add_call(
f"{routes_abs}::handler",
f"{services_abs}::service",
routes_abs,
)

flows = trace_flows(self.store)
store_flows(self.store, flows)

result = analyze_changes(
self.store,
changed_files=["services.py"],
changed_ranges={services_abs: [(1, 10)]},
repo_root=repo_root,
)
assert len(result["affected_flows"]) >= 1

def test_analyze_changes_review_priorities_ordered(self):
"""Review priorities are ordered by descending risk score."""
# Create several functions with varying risk levels.
Expand Down