Merge pull request #1246 from VLDCNDN/fix/extract-out-cache-leak

fix: anchor extraction cache at --out root so external output leaves the scanned project clean
This commit is contained in:
Safi
2026-06-11 23:22:35 +01:00
committed by GitHub
2 changed files with 43 additions and 3 deletions
+6 -3
View File
@@ -4206,7 +4206,10 @@ def main() -> None:
ast_result: dict = {"nodes": [], "edges": [], "input_tokens": 0, "output_tokens": 0}
if code_files:
from graphify.extract import extract as _ast_extract
ast_kwargs: dict = {"cache_root": target}
# Anchor the cache at the output root, not the scanned project:
# with --out, a <target>/graphify-out/cache/ would leak a
# graphify-out/ dir into a project that asked for external output.
ast_kwargs: dict = {"cache_root": out_root}
if cli_max_workers is not None:
ast_kwargs["max_workers"] = cli_max_workers
print(f"[graphify extract] AST extraction on {len(code_files)} code files...")
@@ -4230,7 +4233,7 @@ def main() -> None:
if semantic_files:
sem_paths_str = [str(p) for p in semantic_files]
cached_nodes, cached_edges, cached_hyperedges, uncached_paths = (
_check_semantic_cache(sem_paths_str, root=target)
_check_semantic_cache(sem_paths_str, root=out_root)
)
sem_cache_hits = len(semantic_files) - len(uncached_paths)
sem_cache_misses = len(uncached_paths)
@@ -4300,7 +4303,7 @@ def main() -> None:
fresh.get("nodes", []),
fresh.get("edges", []),
fresh.get("hyperedges", []),
root=target,
root=out_root,
)
except Exception as exc:
print(f"[graphify extract] warning: could not write semantic cache: {exc}", file=sys.stderr)
+37
View File
@@ -172,6 +172,43 @@ def test_extract_codeonly_succeeds_without_api_key(monkeypatch, tmp_path):
assert len(json.loads(graph.read_text()).get("nodes", [])) > 0
def test_extract_out_keeps_project_root_clean(monkeypatch, tmp_path):
"""`extract --out DIR` routes every artifact to DIR/graphify-out/ and the
scanned project must not grow a graphify-out/ (or anything else) beside
its sources.
Guards the centralized-output workflow: run from the project root with
--out pointing outside the repo, and the repo stays byte-identical.
"""
project = tmp_path / "project"
project.mkdir()
corpus = _code_only_corpus(project)
external = tmp_path / "external-graphs"
_clear_backend_keys(monkeypatch)
monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
monkeypatch.chdir(corpus) # run from the project root, like a real user
monkeypatch.setattr(
mainmod.sys, "argv",
["graphify", "extract", ".", "--out", str(external)],
)
try:
mainmod.main()
except SystemExit as exc:
assert exc.code in (None, 0), f"unexpected exit code {exc.code}"
out = external / "graphify-out"
assert (out / "graph.json").exists(), "graph.json must land under --out"
assert (out / "manifest.json").exists(), "manifest.json must land under --out"
assert not (corpus / "graphify-out").exists(), (
"scanned project must not grow a graphify-out/ when --out is set"
)
assert sorted(p.name for p in corpus.iterdir()) == ["auth.py"], (
"no stray files may appear in the project root"
)
def test_extract_without_key_still_errors_when_docs_present(
monkeypatch, tmp_path, capsys
):