feat: enhance resolve_diff_scope_context to handle skipped diff-scope sources and add related tests

This commit is contained in:
bearsyankees
2026-03-23 20:52:26 -04:00
parent 21f89dd6bd
commit 861e2f7683
2 changed files with 73 additions and 1 deletions

View File

@@ -1018,6 +1018,7 @@ def resolve_diff_scope_context(
repo_scopes: list[RepoDiffScope] = []
skipped_non_git: list[str] = []
skipped_diff_scope: list[str] = []
for source in local_sources:
source_path = source.get("source_path")
if not source_path:
@@ -1025,9 +1026,23 @@ def resolve_diff_scope_context(
if not _is_git_repo(Path(source_path)):
skipped_non_git.append(source_path)
continue
repo_scopes.append(_resolve_repo_diff_scope(source, diff_base, env_map))
try:
repo_scopes.append(_resolve_repo_diff_scope(source, diff_base, env_map))
except ValueError as e:
if scope_mode == "auto":
skipped_diff_scope.append(f"{source_path} (diff-scope skipped: {e})")
continue
raise
if not repo_scopes:
if scope_mode == "auto":
metadata: dict[str, Any] = {"active": False, "mode": scope_mode}
if skipped_non_git:
metadata["skipped_non_git_sources"] = skipped_non_git
if skipped_diff_scope:
metadata["skipped_diff_scope_sources"] = skipped_diff_scope
return DiffScopeResult(active=False, mode=scope_mode, metadata=metadata)
raise ValueError(
"Diff-scope is active, but no Git repositories were found. "
"Use --scope-mode full to disable diff-scope for this run."
@@ -1044,6 +1059,8 @@ def resolve_diff_scope_context(
}
if skipped_non_git:
metadata["skipped_non_git_sources"] = skipped_non_git
if skipped_diff_scope:
metadata["skipped_diff_scope_sources"] = skipped_diff_scope
return DiffScopeResult(
active=True,

View File

@@ -1,6 +1,8 @@
import importlib.util
from pathlib import Path
import pytest
def _load_utils_module():
module_path = Path(__file__).resolve().parents[2] / "strix" / "interface" / "utils.py"
@@ -96,3 +98,56 @@ def test_resolve_base_ref_falls_back_to_remote_main(monkeypatch) -> None:
assert base_ref == "refs/remotes/origin/main"
assert "refs/remotes/origin/main" in calls
assert "origin/main" not in calls
def test_resolve_diff_scope_context_auto_degrades_when_repo_scope_resolution_fails(
monkeypatch,
) -> None:
source = {"source_path": "/tmp/repo", "workspace_subdir": "repo"}
monkeypatch.setattr(utils, "_should_activate_auto_scope", lambda *_args, **_kwargs: True)
monkeypatch.setattr(utils, "_is_git_repo", lambda _repo_path: True)
monkeypatch.setattr(
utils,
"_resolve_repo_diff_scope",
lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("shallow history")),
)
result = utils.resolve_diff_scope_context(
local_sources=[source],
scope_mode="auto",
diff_base=None,
non_interactive=True,
env={},
)
assert result.active is False
assert result.mode == "auto"
assert result.metadata["active"] is False
assert result.metadata["mode"] == "auto"
assert "skipped_diff_scope_sources" in result.metadata
assert result.metadata["skipped_diff_scope_sources"] == [
"/tmp/repo (diff-scope skipped: shallow history)"
]
def test_resolve_diff_scope_context_diff_mode_still_raises_on_repo_scope_resolution_failure(
monkeypatch,
) -> None:
source = {"source_path": "/tmp/repo", "workspace_subdir": "repo"}
monkeypatch.setattr(utils, "_is_git_repo", lambda _repo_path: True)
monkeypatch.setattr(
utils,
"_resolve_repo_diff_scope",
lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("shallow history")),
)
with pytest.raises(ValueError, match="shallow history"):
utils.resolve_diff_scope_context(
local_sources=[source],
scope_mode="diff",
diff_base=None,
non_interactive=True,
env={},
)