fix(tree): don't count untagged nodes as a repo when choosing merged layout

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
AromalBiju1andClaude Sonnet 5.5 committed 2026-10-18 12:04:12 +05:30
1 parent 873795a05b
commit a751df5f89
2 files changed
+42 -8

No files matched your search

+22 -8
View File
@@ -152,18 +152,27 @@ def _attach_files(
return root_node, matched_files, by_file
_NO_REPO_LABEL = "(no repo)"
def _repo_groups(
file_nodes: List[Dict[str, Any]],
) -> Dict[str, List[Dict[str, Any]]]:
"""Group nodes by their ``repo`` tag (set by ``merge-graphs`` / ``global add``).
) -> "tuple[Dict[str, List[Dict[str, Any]]], List[Dict[str, Any]]]":
"""Split nodes into ``({repo tag: nodes}, untagged nodes)``.
Nodes without a usable tag go under ``"(no repo)"`` so they are not lost.
The tag is the ``repo`` attribute set by ``merge-graphs`` / ``global add``.
Untagged nodes are returned separately so they never count as a repo: only
real tags decide whether a graph is treated as a merged one.
"""
groups: Dict[str, List[Dict[str, Any]]] = defaultdict(list)
untagged: List[Dict[str, Any]] = []
for n in file_nodes:
tag = n.get("repo")
groups[tag if isinstance(tag, str) and tag else "(no repo)"].append(n)
return groups
if isinstance(tag, str) and tag:
groups[tag].append(n)
else:
untagged.append(n)
return groups, untagged
def build_tree(
@@ -195,9 +204,11 @@ def build_tree(
return {"name": "(empty graph)", "total_count": 0, "children": []}
explicit_root = root is not None
groups = _repo_groups(file_nodes)
groups, untagged = _repo_groups(file_nodes)
if len(groups) < 2:
# Zero or one real repo tag: not a merged graph. Every node, tagged or
# not, goes through the original single-root path.
if root is None:
root = _common_root([n["source_file"] for n in file_nodes])
root_node, matched_files, by_file = _attach_files(
@@ -214,8 +225,11 @@ def build_tree(
}
total_matched = total_files = 0
sample = ""
for tag in sorted(groups):
group = groups[tag]
ordered = sorted(groups.items())
if untagged:
# Kept visible, but only once two real tags made this a merged graph.
ordered.append((_NO_REPO_LABEL, untagged))
for tag, group in ordered:
paths = [n["source_file"] for n in group]
if root is not None:
group_root = root
+20
View File
@@ -136,6 +136,26 @@ def test_build_tree_merged_graph_untagged_nodes_are_kept():
assert set(_by_name(build_tree(graph))) == {"repo-a", "repo-b", "(no repo)"}
def test_build_tree_partially_tagged_single_repo_is_not_a_merged_graph():
"""One real repo tag plus untagged nodes is not a merged graph: it must
take the original single-root path, not grow a "(no repo)" sibling."""
graph = {"nodes": [
{"id": "a", "label": "A", "source_file": "pkg/a.py", "repo": "only-repo"},
{"id": "b", "label": "B", "source_file": "pkg/b.py"},
]}
tree = build_tree(graph)
assert tree["name"] == "pkg"
assert set(_by_name(tree)) == {"a.py", "b.py"}
def test_build_tree_untagged_graph_is_unchanged_by_repo_grouping():
graph = _graph({"pkg/a.py": "func_a", "pkg/sub/b.py": "func_b"})
assert "repo" not in graph["nodes"][0]
tree = build_tree(graph)
assert tree["name"] == "pkg"
assert {"a.py", "sub"} <= set(_by_name(tree))
def test_build_tree_merged_graph_explicit_root_matching_nothing_raises():
graph = _merged_graph({
"repo-a": {"src/a.py": "A"},