Skip to content
Closed
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
8 changes: 7 additions & 1 deletion graphify/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -5512,7 +5512,7 @@ def extract(
_empty_sources: list[str] = []
for i, _p in enumerate(paths):
_res = per_file[i] or {}
if _res.get("nodes") or _res.get("error"):
if _res.get("nodes") or _res.get("error") or _res.get("skipped"):
continue
if _get_extractor(_p) is not None:
_empty_sources.append(str(_p))
Expand Down Expand Up @@ -5544,6 +5544,12 @@ def extract(
_failed_sources.append(_key)
_failed_seen.add(_key)
continue
if _res.get("skipped"):
# The extractor declined this file by design (data JSON, #1224), so
# zero nodes is the intended outcome rather than a failure. Marking
# it failed keeps it out of the incremental manifest and re-queues
# it on every subsequent run, forever (#2879).
continue
if (not _res.get("nodes")) and _get_extractor(_p) is not None:
if _key not in _failed_seen:
_failed_sources.append(_key)
Expand Down
39 changes: 39 additions & 0 deletions tests/test_extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3966,3 +3966,42 @@ def test_inferred_uses_edge_dropped_for_module_top_level_reference(tmp_path):
uses = _inferred_uses(result)

assert not any(tgt == "helpers_helper" for _, tgt in uses)


def test_extract_declined_data_json_is_not_failed(tmp_path, capsys):
"""#2879: data JSON is declined by design (#1224), not failed.

A `.json` extractor is registered, so a declined file used to satisfy both
halves of the failed-source test (zero nodes + extractor exists) and was
re-queued on every incremental run because the CLI never stamped it as
processed.
"""
pytest.importorskip("tree_sitter_json")
data = tmp_path / "meta.json"
data.write_text('{"pages": ["a", "b"], "title": "Docs"}\n')
cfg = tmp_path / "package.json"
cfg.write_text('{"dependencies": {"left-pad": "^1.0.0"}}\n')

result = extract([data, cfg], cache_root=tmp_path)
err = capsys.readouterr().err

assert result.get("failed_sources") == []
# ...and no "produced zero nodes" noise for a deliberate decline (#1666).
assert "zero nodes" not in err
# the config JSON still extracts normally
assert any(str(n.get("label", "")).startswith("package.json") for n in result["nodes"])


def test_extract_genuinely_empty_json_still_failed(tmp_path, monkeypatch):
"""#2879 guard: only an explicit `skipped` marker is exempt."""
pytest.importorskip("tree_sitter_json")
import graphify.extract as _ex

monkeypatch.setattr(
_ex, "_get_extractor",
lambda p: (lambda _p: {"nodes": [], "edges": []}) if p.suffix == ".json" else None,
)
p = tmp_path / "meta.json"
p.write_text("{}\n")
result = _ex.extract([p], cache_root=tmp_path)
assert [Path(x).name for x in result.get("failed_sources", [])] == ["meta.json"]
Loading