mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-25 08:11:54 +00:00
fix(tree): don't count untagged nodes as a repo when choosing merged layout
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
(cherry picked from commit a751df5f89)
This commit is contained in:
1 parent
97f18cb7b0
commit
cbcd8dd601
2 files changed
+42
-8
No files matched your search
+22
-8
@@ -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
|
||||
|
||||
@@ -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"},
|
||||
|
||||
Reference in new issue
Block a user