mirror of
https://github.com/safishamsi/graphify.git
synced 2026-09-21 21:16:31 +00:00
fix(ids): legacy-id detector only inspects file-level nodes (no Go false-positive)
The graph_has_legacy_ids nudge flagged fresh v9 graphs that contain Go code, because the Go extractor scopes a type node by package directory (_make_id(pkg_dir, name) -> "sub_thing"), which coincides with the OLD one-parent file-stem form of pkg/sub/thing.go even though it's a current, by-design package-scoped id (methods on a type across files in a package share one node). The detector now inspects only file-level nodes (source_location "L1"), whose id is unambiguously the file stem and which the migration actually re-keys. This still catches a genuine pre-#1504 graph (its file nodes carry the old stem) while leaving package/dir-scoped symbol ids alone. Verified end-to-end: a fresh Go graph no longer triggers the rebuild nudge; a real legacy graph still does. The migration itself was already correct — file nodes and Python/AST symbols migrate to full-path ids; Go's package-scoped type ids are intentional and unaffected. This only fixes the over-eager warning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3999dbc67e
commit
73710d33ce
+8
-3
@@ -201,15 +201,20 @@ def graph_has_legacy_ids(nodes: list, root: str | Path | None = None, sample: in
|
||||
stem) rather than the full repo-relative path. Read-only consumers (query,
|
||||
serve) use this to nudge the user to rebuild, since they don't re-extract.
|
||||
|
||||
Heuristic and cheap: samples nodes with a relative ``source_file`` and returns
|
||||
True as soon as one ID matches an OLD stem form but NOT the canonical full-path
|
||||
form. Absolute/sourceless nodes are skipped (can't be classified)."""
|
||||
Heuristic and cheap: only **file-level** nodes (source_location ``L1``) are
|
||||
inspected, because their ID is unambiguously the file stem. Symbol nodes are
|
||||
skipped — some extractors scope a symbol by package/directory (Go's
|
||||
``_make_id(pkg_dir, name)`` → ``sub_thing``), which can coincide with an old
|
||||
file-stem form and would otherwise false-positive. Returns True as soon as one
|
||||
file node's ID matches an OLD stem form but not the canonical full-path form."""
|
||||
from graphify.extractors.base import _file_stem
|
||||
_r = str(root) if root is not None else None
|
||||
checked = 0
|
||||
for node in nodes:
|
||||
if not isinstance(node, dict):
|
||||
continue
|
||||
if str(node.get("source_location") or "") != "L1":
|
||||
continue # only file-level nodes carry an unambiguous file-stem ID
|
||||
nid = node.get("id")
|
||||
sf = node.get("source_file")
|
||||
if not nid or not isinstance(nid, str) or not sf:
|
||||
|
||||
+9
-4
@@ -726,13 +726,18 @@ def test_graph_has_legacy_ids_detects_old_scheme():
|
||||
"""The read-only-consumer nudge (query/serve) flags a pre-#1504 graph and
|
||||
leaves a canonical one alone."""
|
||||
from graphify.build import graph_has_legacy_ids
|
||||
old = [{"id": "api_readme", "source_file": "docs/v1/api/README.md", "type": "document"}]
|
||||
new = [{"id": "docs_v1_api_readme", "source_file": "docs/v1/api/README.md", "type": "document"}]
|
||||
old = [{"id": "api_readme", "source_file": "docs/v1/api/README.md", "type": "document", "source_location": "L1"}]
|
||||
new = [{"id": "docs_v1_api_readme", "source_file": "docs/v1/api/README.md", "type": "document", "source_location": "L1"}]
|
||||
assert graph_has_legacy_ids(old, root=".") is True
|
||||
assert graph_has_legacy_ids(new, root=".") is False
|
||||
# sourceless / top-level nodes don't false-positive
|
||||
assert graph_has_legacy_ids([{"id": "setup", "source_file": "setup.py"}], root=".") is False
|
||||
# sourceless / top-level file nodes don't false-positive
|
||||
assert graph_has_legacy_ids([{"id": "setup", "source_file": "setup.py", "source_location": "L1"}], root=".") is False
|
||||
assert graph_has_legacy_ids([{"id": "x", "label": "y"}], root=".") is False
|
||||
# package/dir-scoped SYMBOL ids (Go's _make_id(pkg_dir, name) -> "sub_thing") must
|
||||
# NOT false-positive: not file-level (no L1), so ignored even though "sub_thing"
|
||||
# coincides with the old file-stem form of pkg/sub/thing.go.
|
||||
go_symbol = [{"id": "sub_thing", "source_file": "pkg/sub/thing.go", "type": "code", "source_location": "L3"}]
|
||||
assert graph_has_legacy_ids(go_symbol, root=".") is False
|
||||
|
||||
|
||||
def test_semantic_rekey_relative_vs_absolute_source_file():
|
||||
|
||||
Reference in New Issue
Block a user