generated from coulomb/repo-seed
Collapse duplicate repository graph nodes
This commit is contained in:
@@ -238,6 +238,13 @@ def fabric_graph_explorer_payload(
|
||||
|
||||
elements: list[dict[str, Any]] = []
|
||||
repository_index = {str(repo.get("slug", "")): repo for repo in repositories}
|
||||
source_repository_node_ids = {
|
||||
str(node.get("id", "")): f"repo:{str(node.get('repo', '')).strip()}"
|
||||
for node in source_nodes
|
||||
if str(node.get("kind", "")) == "Repository"
|
||||
and str(node.get("id", ""))
|
||||
and str(node.get("repo", "")).strip()
|
||||
}
|
||||
for slug in sorted(repo_slugs):
|
||||
repo = repository_index.get(slug, {})
|
||||
has_snapshot = slug in snapshot_repo_slugs or slug in source_repo_slugs
|
||||
@@ -281,6 +288,8 @@ def fabric_graph_explorer_payload(
|
||||
if not node_id:
|
||||
continue
|
||||
kind = str(node.get("kind", ""))
|
||||
if kind == "Repository":
|
||||
continue
|
||||
layer = _layer_for_kind(kind)
|
||||
is_unresolved = node_id in unresolved
|
||||
attributes = node.get("attributes") if isinstance(node.get("attributes"), dict) else {}
|
||||
@@ -342,8 +351,8 @@ def fabric_graph_explorer_payload(
|
||||
)
|
||||
|
||||
for edge in source_edges:
|
||||
source = str(edge.get("from", ""))
|
||||
target = str(edge.get("to", ""))
|
||||
source = source_repository_node_ids.get(str(edge.get("from", "")), str(edge.get("from", "")))
|
||||
target = source_repository_node_ids.get(str(edge.get("to", "")), str(edge.get("to", "")))
|
||||
edge_type = str(edge.get("type", ""))
|
||||
if not source or not target:
|
||||
continue
|
||||
@@ -354,6 +363,8 @@ def fabric_graph_explorer_payload(
|
||||
repo_id = f"repo:{slug}"
|
||||
for node in source_nodes:
|
||||
node_id = str(node.get("id", ""))
|
||||
if str(node.get("kind", "")) == "Repository":
|
||||
continue
|
||||
if str(node.get("repo", "")) != slug or not node_id:
|
||||
continue
|
||||
elements.append(_edge_element(edge_index, repo_id, node_id, "declares", node_layers, node_repos))
|
||||
|
||||
@@ -72,6 +72,57 @@ def test_graph_explorer_manifest_and_payload_validate() -> None:
|
||||
assert "removed nodes are removed" in payload["filter"]["connected_edge_behavior"]
|
||||
|
||||
|
||||
def test_graph_explorer_collapses_discovered_repository_nodes() -> None:
|
||||
graph = {
|
||||
"apiVersion": "railiance.fabric/v1alpha1",
|
||||
"kind": "FabricGraphExport",
|
||||
"generated_at": "2026-05-21T00:00:00Z",
|
||||
"source": {"repo": "fixture-repo", "commit": "abc123"},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "discovery:fixture-repo:repository:fixture-repo",
|
||||
"kind": "Repository",
|
||||
"name": "Fixture Repo",
|
||||
"repo": "fixture-repo",
|
||||
"domain": "testing",
|
||||
"lifecycle": "active",
|
||||
"attributes": {"discovery_origin": "deterministic"},
|
||||
},
|
||||
{
|
||||
"id": "discovery:fixture-repo:library:fixture-service",
|
||||
"kind": "Library",
|
||||
"name": "fixture-service",
|
||||
"repo": "fixture-repo",
|
||||
"domain": "testing",
|
||||
"lifecycle": "active",
|
||||
"attributes": {"language": "python"},
|
||||
},
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"from": "discovery:fixture-repo:repository:fixture-repo",
|
||||
"to": "discovery:fixture-repo:library:fixture-service",
|
||||
"type": "declares_package",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
payload = fabric_graph_explorer_payload(
|
||||
graph,
|
||||
[{"slug": "fixture-repo", "name": "Fixture Repo"}],
|
||||
{"fixture-repo"},
|
||||
)
|
||||
|
||||
nodes = [element for element in payload["elements"] if "source" not in element["data"]]
|
||||
edges = [element for element in payload["elements"] if "source" in element["data"]]
|
||||
repository_nodes = [node for node in nodes if node["data"]["kind"] == "Repository"]
|
||||
declares_package = next(edge for edge in edges if edge["data"]["edgeType"] == "declares_package")
|
||||
|
||||
assert [node["data"]["id"] for node in repository_nodes] == ["repo:fixture-repo"]
|
||||
assert declares_package["data"]["source"] == "repo:fixture-repo"
|
||||
assert declares_package["data"]["target"] == "discovery:fixture-repo:library:fixture-service"
|
||||
|
||||
|
||||
def test_cli_exports_graph_explorer_payload(capsys) -> None:
|
||||
assert cli_main(["export", "--format", "graph-explorer"]) == 0
|
||||
payload = json.loads(capsys.readouterr().out)
|
||||
|
||||
39
workplans/ADHOC-2026-05-21.md
Normal file
39
workplans/ADHOC-2026-05-21.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: ADHOC-2026-05-21
|
||||
type: workplan
|
||||
title: "Ad Hoc Fixes 2026-05-21"
|
||||
domain: railiance
|
||||
repo: railiance-fabric
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-05-21"
|
||||
updated: "2026-05-21"
|
||||
state_hub_workstream_id: "c5126722-3b6c-4a6a-b687-bc2ebfce5d58"
|
||||
---
|
||||
|
||||
# ADHOC-2026-05-21 - Ad Hoc Fixes
|
||||
|
||||
## Collapse Duplicate Repository Icons
|
||||
|
||||
```task
|
||||
id: ADHOC-2026-05-21-T01
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "8af02b06-b9a4-457a-bbdc-fa97543944a4"
|
||||
```
|
||||
|
||||
After projecting all discovery candidates into the local registry graph, the
|
||||
graph explorer rendered each repository twice: once as the canonical registry
|
||||
repository node and once as the discovered `Repository` candidate node.
|
||||
|
||||
The graph explorer now collapses discovered `Repository` nodes into the
|
||||
canonical `repo:<slug>` node and rewires source graph edges to that canonical
|
||||
node, preserving relationships without duplicate repo icons.
|
||||
|
||||
Verification:
|
||||
|
||||
- `python3 -m pytest tests/test_graph_explorer.py -q` passed.
|
||||
- `python3 -m pytest` passed with 34 tests.
|
||||
- Restarted the local registry and confirmed the graph explorer export now has
|
||||
35 repository nodes instead of 69.
|
||||
Reference in New Issue
Block a user