Skip to content
Merged
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
7 changes: 6 additions & 1 deletion diffgraph/structural.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,12 @@ def analyze_local_diff(
continue

parser_errors = (
UnicodeDecodeError, ValueError, RuntimeError, OSError, TypeError
StructuralDependencyError,
UnicodeDecodeError,
ValueError,
RuntimeError,
OSError,
TypeError,
)
try:
old_symbols, old_imports, _old_calls, _old_bindings, _old_rebindings = (
Expand Down
39 changes: 35 additions & 4 deletions tests/test_structural.py
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,36 @@ def invalid_artifact(*args, **kwargs):
cli._validate_structural_artifact({})


def test_missing_parser_dependency_is_a_run_level_cli_error(tmp_path, monkeypatch):
def test_missing_parser_dependency_is_a_scoped_structural_warning(tmp_path, monkeypatch):
"""A parser installation failure must not turn exact Git input into a false change."""
from diffgraph.structural import StructuralDependencyError

root = repo(tmp_path)
write(root, "app.py", "def value():\n return 1\n")
git(root, "add", "app.py")

def unavailable():
raise StructuralDependencyError("parser dependency is unavailable")

monkeypatch.setattr("diffgraph.structural._parser", unavailable)
artifact = analyze_local_diff(str(root), staged=True)

assert_valid(artifact)
assert artifact["symbols"] == []
assert artifact["relationships"] == []
assert artifact["metadata"]["files_analyzed"] == 0
assert artifact["metadata"]["files_skipped"] == 1
assert artifact["metadata"]["warnings"] == [{
"code": "PARSE_FAILURE",
"file": "app.py",
"detail": (
"post-change: StructuralDependencyError: "
"parser dependency is unavailable"
),
}]


def test_cli_emits_valid_artifact_when_parser_dependency_is_unavailable(tmp_path, monkeypatch):
from click.testing import CliRunner
from diffgraph.cli import main
from diffgraph.structural import StructuralDependencyError
Expand All @@ -928,9 +957,11 @@ def unavailable():
result = CliRunner().invoke(
main, ["--structural-json", "-", "diff", "--staged"]
)
assert result.exit_code == 1
assert "parser dependency is unavailable" in result.output
assert "PARSE_FAILURE" not in result.output

assert result.exit_code == 0, result.output
artifact = json.loads(result.output)
assert_valid(artifact)
assert artifact["metadata"]["warnings"][0]["code"] == "PARSE_FAILURE"


def test_missing_ai_dependency_is_a_click_error(tmp_path, monkeypatch):
Expand Down
Loading