fix(cli): keep passive update checks noninteractive
This commit is contained in:
@@ -241,11 +241,15 @@ def _is_full_sha(value: Optional[str]) -> bool:
|
||||
|
||||
def _upstream_main_sha() -> Optional[str]:
|
||||
"""Tip SHA of upstream main via HTTPS ls-remote (no auth, no prompts)."""
|
||||
from hermes_cli._subprocess_compat import noninteractive_git_env
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "ls-remote", _UPSTREAM_REPO_URL, "refs/heads/main"],
|
||||
capture_output=True, text=True, encoding="utf-8", errors="replace",
|
||||
timeout=10,
|
||||
stdin=subprocess.DEVNULL,
|
||||
env=noninteractive_git_env(),
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
@@ -277,6 +281,8 @@ def _check_via_rev(local_rev: str) -> Optional[int]:
|
||||
|
||||
def _check_via_local_git(repo_dir: Path) -> Optional[int]:
|
||||
"""Count commits behind origin/main in a local checkout."""
|
||||
from hermes_cli._subprocess_compat import noninteractive_git_env
|
||||
|
||||
origin_url = _git_stdout(["remote", "get-url", "origin"], cwd=repo_dir)
|
||||
if _is_official_ssh_remote(origin_url):
|
||||
head_rev = _git_stdout(["rev-parse", "HEAD"], cwd=repo_dir)
|
||||
@@ -348,6 +354,8 @@ def _check_via_local_git(repo_dir: Path) -> Optional[int]:
|
||||
fetch_args,
|
||||
capture_output=True, timeout=10,
|
||||
cwd=str(repo_dir),
|
||||
stdin=subprocess.DEVNULL,
|
||||
env=noninteractive_git_env(),
|
||||
)
|
||||
fetch_ok = fetch_proc.returncode == 0
|
||||
except Exception:
|
||||
|
||||
@@ -23,7 +23,10 @@ def test_check_for_updates_uses_cache(tmp_path, monkeypatch):
|
||||
(repo_dir / ".git").mkdir()
|
||||
|
||||
cache_file = tmp_path / ".update_check"
|
||||
cache_file.write_text(json.dumps({"ts": time.time(), "behind": 3, "ver": __version__}))
|
||||
cache_file.write_text(
|
||||
json.dumps({"ts": time.time(), "behind": 3, "ver": __version__}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
|
||||
with patch("hermes_cli.banner.subprocess.run") as mock_run:
|
||||
@@ -58,6 +61,21 @@ def test_prefetch_non_blocking():
|
||||
assert banner._update_result == 5
|
||||
|
||||
|
||||
def test_upstream_main_sha_disables_git_prompts(monkeypatch):
|
||||
"""The passive HTTPS probe must never inherit the interactive terminal."""
|
||||
from hermes_cli import banner
|
||||
|
||||
completed = MagicMock(returncode=1, stdout="", stderr="auth required")
|
||||
run = MagicMock(return_value=completed)
|
||||
monkeypatch.setattr(banner.subprocess, "run", run)
|
||||
|
||||
assert banner._upstream_main_sha() is None
|
||||
kwargs = run.call_args.kwargs
|
||||
assert kwargs["stdin"] is banner.subprocess.DEVNULL
|
||||
assert kwargs["env"]["GIT_TERMINAL_PROMPT"] == "0"
|
||||
assert kwargs["env"]["GCM_INTERACTIVE"] == "Never"
|
||||
|
||||
|
||||
def test_check_via_local_git_fetch_failure_returns_none(tmp_path, monkeypatch):
|
||||
"""When git fetch fails and the stale origin/main ref is not ahead,
|
||||
_check_via_local_git must return None (#82166).
|
||||
@@ -90,8 +108,12 @@ def test_check_via_local_git_fetch_failure_returns_none(tmp_path, monkeypatch):
|
||||
stale_zero_proc.returncode = 0
|
||||
stale_zero_proc.stdout = "0"
|
||||
|
||||
fetch_kwargs = None
|
||||
|
||||
def mock_run(args, **kwargs):
|
||||
nonlocal fetch_kwargs
|
||||
if args[:2] == ["git", "fetch"]:
|
||||
fetch_kwargs = kwargs
|
||||
return failed_proc
|
||||
if args[:2] == ["git", "rev-list"]:
|
||||
return stale_zero_proc
|
||||
@@ -104,6 +126,10 @@ def test_check_via_local_git_fetch_failure_returns_none(tmp_path, monkeypatch):
|
||||
assert result is None, (
|
||||
"Fetch failure with stale 0-behind must return None, not 'up to date'"
|
||||
)
|
||||
assert fetch_kwargs is not None
|
||||
assert fetch_kwargs["stdin"] is banner.subprocess.DEVNULL
|
||||
assert fetch_kwargs["env"]["GIT_TERMINAL_PROMPT"] == "0"
|
||||
assert fetch_kwargs["env"]["GCM_INTERACTIVE"] == "Never"
|
||||
|
||||
|
||||
def test_check_via_local_git_fetch_failure_keeps_positive_stale_count(tmp_path, monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user