simplify(compat): hermes_cli small facades — drop 7 re-exports/aliases (+relay_runtime alias module), repoint 12 callers/tests
This commit is contained in:
@@ -24,7 +24,7 @@ def cli_obj(_isolate):
|
||||
"display": {"tool_progress": "new"},
|
||||
"terminal": {},
|
||||
}), patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
from cli import HermesCLI
|
||||
obj = HermesCLI.__new__(HermesCLI)
|
||||
obj.model = "test-model"
|
||||
@@ -50,7 +50,7 @@ class TestLowContextWarning:
|
||||
"""Warning shown when context is below Hermes' minimum."""
|
||||
cli_obj.agent.context_compressor.context_length = 32768
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
@@ -64,7 +64,7 @@ class TestLowContextWarning:
|
||||
"""Warning shown for 2048 tokens (common LM Studio default)."""
|
||||
cli_obj.agent.context_compressor.context_length = 2048
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
@@ -75,7 +75,7 @@ class TestLowContextWarning:
|
||||
"""No warning at exactly Hermes' minimum context length."""
|
||||
cli_obj.agent.context_compressor.context_length = MINIMUM_CONTEXT_LENGTH
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
@@ -86,7 +86,7 @@ class TestLowContextWarning:
|
||||
"""No warning above Hermes' minimum context length."""
|
||||
cli_obj.agent.context_compressor.context_length = MINIMUM_CONTEXT_LENGTH + 1
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
@@ -98,7 +98,7 @@ class TestLowContextWarning:
|
||||
cli_obj.agent.context_compressor.context_length = 4096
|
||||
cli_obj.base_url = "http://localhost:11434/v1"
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
@@ -112,7 +112,7 @@ class TestLowContextWarning:
|
||||
cli_obj.agent.context_compressor.context_length = 4096
|
||||
cli_obj.base_url = "http://localhost:8080/v1"
|
||||
with patch("cli.get_tool_definitions", return_value=[]), \
|
||||
patch("cli.build_welcome_banner"):
|
||||
patch("hermes_cli.banner.build_welcome_banner"):
|
||||
cli_obj.show_banner()
|
||||
|
||||
calls = [str(c) for c in cli_obj.console.print.call_args_list]
|
||||
|
||||
@@ -140,7 +140,7 @@ def test_show_banner_does_not_print_skills():
|
||||
cli_obj.preloaded_skills = ["hermes-agent-dev", "github-auth"]
|
||||
cli_obj.console = MagicMock()
|
||||
|
||||
with patch("cli.build_welcome_banner") as mock_banner, patch(
|
||||
with patch("hermes_cli.banner.build_welcome_banner") as mock_banner, patch(
|
||||
"shutil.get_terminal_size", return_value=os.terminal_size((120, 40))
|
||||
):
|
||||
cli_obj.show_banner()
|
||||
|
||||
@@ -249,7 +249,7 @@ def test_runtime_resolution_failure_is_not_sticky(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("hermes_cli.runtime_provider.resolve_runtime_provider", _runtime_resolve)
|
||||
monkeypatch.setattr("hermes_cli.runtime_provider.format_runtime_provider_error", lambda exc: str(exc))
|
||||
monkeypatch.setattr(cli, "AIAgent", _DummyAgent)
|
||||
monkeypatch.setattr("run_agent.AIAgent", _DummyAgent)
|
||||
|
||||
shell = cli.HermesCLI(model="gpt-5", compact=True, max_turns=1)
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ def test_show_session_status_prints_gateway_style_summary():
|
||||
"started_at": 1775791440,
|
||||
}
|
||||
|
||||
with patch("cli.display_hermes_home", return_value="~/.hermes"):
|
||||
with patch("hermes_constants.display_hermes_home", return_value="~/.hermes"):
|
||||
cli_obj._show_session_status()
|
||||
|
||||
printed = "\n".join(str(call.args[0]) for call in cli_obj.console.print.call_args_list)
|
||||
@@ -107,7 +107,7 @@ def test_show_session_status_includes_reasoning_approvals_context():
|
||||
"context_tokens": 50000, "context_length": 200000, "context_percent": 25,
|
||||
}
|
||||
|
||||
with patch("cli.display_hermes_home", return_value="~/.hermes"), \
|
||||
with patch("hermes_constants.display_hermes_home", return_value="~/.hermes"), \
|
||||
patch("tools.approval._get_approval_mode", return_value="manual"), \
|
||||
patch("tools.approval.is_approval_bypass_active_for_session", return_value=False):
|
||||
cli_obj._show_session_status()
|
||||
|
||||
@@ -5,7 +5,12 @@ leak into the input buffer after terminal resize storms or multiplexer
|
||||
tab switches — see issue #14692.
|
||||
"""
|
||||
|
||||
from cli import _strip_leaked_terminal_responses
|
||||
from cli import _strip_leaked_terminal_responses_with_meta
|
||||
|
||||
|
||||
def _strip_leaked_terminal_responses(text: str) -> str:
|
||||
cleaned, _ = _strip_leaked_terminal_responses_with_meta(text)
|
||||
return cleaned
|
||||
|
||||
|
||||
class TestStripLeakedTerminalResponses:
|
||||
|
||||
+25
-21
@@ -8,6 +8,8 @@ import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import pytest
|
||||
|
||||
from hermes_cli import worktree_ops
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -845,7 +847,7 @@ class TestWorktreeLockReaping:
|
||||
import cli
|
||||
wt = self._mk(cli, git_repo, "hermes-dead", pid=999999)
|
||||
# sanity: this is the accumulation bug — remove --force alone can't do it
|
||||
assert cli._worktree_lock_is_live(str(git_repo), str(wt)) == "dead"
|
||||
assert worktree_ops._worktree_lock_is_live(str(git_repo), str(wt)) == "dead"
|
||||
cli._prune_stale_worktrees(str(git_repo))
|
||||
assert not wt.exists(), "dead-locked clean worktree should be unlocked + reaped"
|
||||
|
||||
@@ -899,19 +901,19 @@ class TestWorktreeLockPredicate:
|
||||
["git", "worktree", "add", str(p), "-b", "hermes/hermes-x", "HEAD"],
|
||||
cwd=git_repo, capture_output=True,
|
||||
)
|
||||
assert cli._worktree_lock_is_live(str(git_repo), str(p)) is None
|
||||
assert worktree_ops._worktree_lock_is_live(str(git_repo), str(p)) is None
|
||||
|
||||
|
||||
|
||||
def test_foreign_lock_reason_returns_dead(self, git_repo):
|
||||
import cli
|
||||
p = self._mk_locked(git_repo, "hermes-foreign", "some other tool")
|
||||
assert cli._worktree_lock_is_live(str(git_repo), str(p)) == "dead"
|
||||
assert worktree_ops._worktree_lock_is_live(str(git_repo), str(p)) == "dead"
|
||||
|
||||
def test_bad_repo_root_fails_safe_to_live(self, tmp_path):
|
||||
import cli
|
||||
# Not a git repo -> git query fails -> must report "live" (never delete)
|
||||
assert cli._worktree_lock_is_live(str(tmp_path), str(tmp_path / "x")) == "live"
|
||||
assert worktree_ops._worktree_lock_is_live(str(tmp_path), str(tmp_path / "x")) == "live"
|
||||
|
||||
|
||||
class TestWidenedPruner:
|
||||
@@ -1021,7 +1023,7 @@ class TestWidenedPruner:
|
||||
["git", "worktree", "add", str(p), "-b", "wt/noremote", "HEAD"],
|
||||
cwd=repo, capture_output=True,
|
||||
)
|
||||
assert cli._worktree_commits_all_merged_upstream(str(p)) is False
|
||||
assert worktree_ops._worktree_commits_all_merged_upstream(str(p)) is False
|
||||
|
||||
|
||||
# -- preserved-work warning ----------------------------------------------
|
||||
@@ -1050,10 +1052,10 @@ class TestMergeVerdictCache:
|
||||
wt, sha = self._mk(git_repo, "hermes-cachehit", commit=True)
|
||||
self._merge_upstream(git_repo, sha)
|
||||
|
||||
uncached = cli._worktree_commits_all_merged_upstream(str(wt))
|
||||
uncached = worktree_ops._worktree_commits_all_merged_upstream(str(wt))
|
||||
cache = {}
|
||||
cold = cli._worktree_commits_all_merged_upstream(str(wt), cache=cache)
|
||||
warm = cli._worktree_commits_all_merged_upstream(str(wt), cache=cache)
|
||||
cold = worktree_ops._worktree_commits_all_merged_upstream(str(wt), cache=cache)
|
||||
warm = worktree_ops._worktree_commits_all_merged_upstream(str(wt), cache=cache)
|
||||
|
||||
assert cache, "verdict should have been memoized"
|
||||
assert uncached is cold is warm is True
|
||||
@@ -1070,7 +1072,7 @@ class TestMergeVerdictCache:
|
||||
self._merge_upstream(git_repo, sha)
|
||||
|
||||
cache = {}
|
||||
assert cli._worktree_commits_all_merged_upstream(str(wt), cache=cache) is True
|
||||
assert worktree_ops._worktree_commits_all_merged_upstream(str(wt), cache=cache) is True
|
||||
key_after_merge = set(cache)
|
||||
|
||||
# New local-only work lands in the worktree.
|
||||
@@ -1078,7 +1080,7 @@ class TestMergeVerdictCache:
|
||||
subprocess.run(["git", "add", "more.txt"], cwd=wt, capture_output=True)
|
||||
subprocess.run(["git", "commit", "-m", "new work"], cwd=wt, capture_output=True)
|
||||
|
||||
assert cli._worktree_commits_all_merged_upstream(str(wt), cache=cache) is False
|
||||
assert worktree_ops._worktree_commits_all_merged_upstream(str(wt), cache=cache) is False
|
||||
assert set(cache) != key_after_merge, "moved HEAD must produce a new key"
|
||||
|
||||
|
||||
@@ -1091,8 +1093,8 @@ class TestMergeVerdictCache:
|
||||
monkeypatch.setattr(worktree_ops, "_worktree_merge_cache_path", lambda: path)
|
||||
monkeypatch.setattr(worktree_ops, "_WORKTREE_MERGE_CACHE_MAX", 10)
|
||||
|
||||
cli._save_worktree_merge_cache({f"sha{i}..sha{i}:20": True for i in range(50)})
|
||||
assert len(cli._load_worktree_merge_cache()) == 10
|
||||
worktree_ops._save_worktree_merge_cache({f"sha{i}..sha{i}:20": True for i in range(50)})
|
||||
assert len(worktree_ops._load_worktree_merge_cache()) == 10
|
||||
|
||||
|
||||
class TestPruneParallelEquivalence:
|
||||
@@ -1151,7 +1153,7 @@ class TestPruneParallelEquivalence:
|
||||
# Phase B — an independent board (distinct branch names so creation
|
||||
# can't collide with phase A's leftover refs) run through a real pool.
|
||||
try:
|
||||
cli._worktree_merge_cache_path().unlink()
|
||||
worktree_ops._worktree_merge_cache_path().unlink()
|
||||
except Exception:
|
||||
pass
|
||||
board2 = self._board(git_repo, tag="b")
|
||||
@@ -1177,7 +1179,9 @@ class TestPruneParallelEquivalence:
|
||||
def __init__(self, *a, **kw):
|
||||
raise RuntimeError("cannot start thread")
|
||||
|
||||
monkeypatch.setattr(cli.concurrent.futures, "ThreadPoolExecutor", _Boom)
|
||||
import concurrent.futures
|
||||
|
||||
monkeypatch.setattr(concurrent.futures, "ThreadPoolExecutor", _Boom)
|
||||
monkeypatch.setattr(cli.os, "cpu_count", lambda: 8)
|
||||
|
||||
cli._prune_stale_worktrees(str(git_repo))
|
||||
@@ -1289,7 +1293,7 @@ class TestShallowCloneDeepening:
|
||||
_, clone, wt = self._stuck_worktree(tmp_path)
|
||||
assert cli._worktree_has_unpushed_commits(str(wt))
|
||||
|
||||
assert cli._deepen_shallow_repo(str(clone)) is True
|
||||
assert worktree_ops._deepen_shallow_repo(str(clone)) is True
|
||||
assert not cli._repo_is_shallow(str(clone))
|
||||
assert not cli._worktree_has_unpushed_commits(str(wt)), (
|
||||
"after deepening, the worktree's HEAD is an ancestor of "
|
||||
@@ -1317,7 +1321,7 @@ class TestShallowCloneDeepening:
|
||||
["git", "remote", "set-url", "origin", f"file://{tmp_path}/gone"],
|
||||
clone,
|
||||
)
|
||||
assert cli._deepen_shallow_repo(str(clone), timeout=30) is False
|
||||
assert worktree_ops._deepen_shallow_repo(str(clone), timeout=30) is False
|
||||
cli._prune_stale_worktrees(str(clone))
|
||||
assert wt.exists(), (
|
||||
"offline deepen failure must fall back to preserving the tree"
|
||||
@@ -1325,7 +1329,7 @@ class TestShallowCloneDeepening:
|
||||
|
||||
def test_deepen_noop_on_full_clone(self, git_repo):
|
||||
import cli
|
||||
assert cli._deepen_shallow_repo(str(git_repo)) is True
|
||||
assert worktree_ops._deepen_shallow_repo(str(git_repo)) is True
|
||||
|
||||
def test_real_unpushed_work_survives_deepening(self, tmp_path):
|
||||
"""Deepening must not turn genuinely unpushed commits reapable."""
|
||||
@@ -1384,7 +1388,7 @@ class TestPrMergedEscapeHatch:
|
||||
def test_merged_pr_tree_is_reaped(self, git_repo, tmp_path, monkeypatch):
|
||||
import cli
|
||||
wt = self._mk_diverged(git_repo, "hermes-rebase-merged")
|
||||
assert cli._worktree_commits_all_merged_upstream(str(wt)) is False, (
|
||||
assert worktree_ops._worktree_commits_all_merged_upstream(str(wt)) is False, (
|
||||
"precondition: cherry must NOT consider this merged — the PR "
|
||||
"check is the only thing that can reap it"
|
||||
)
|
||||
@@ -1426,19 +1430,19 @@ class TestPrMergedEscapeHatch:
|
||||
wt = self._mk_diverged(git_repo, "hermes-memo")
|
||||
self._stub_gh(tmp_path, monkeypatch)
|
||||
cache: dict = {}
|
||||
assert cli._worktree_branch_pr_merged(str(wt), cache=cache) is True
|
||||
assert worktree_ops._worktree_branch_pr_merged(str(wt), cache=cache) is True
|
||||
keys = [k for k in cache if k.startswith("pr-merged:")]
|
||||
assert len(keys) == 1 and cache[keys[0]] is True
|
||||
# Break gh: a cached True verdict must not re-consult it.
|
||||
self._stub_gh(tmp_path, monkeypatch, stdout="", exit_code=1)
|
||||
assert cli._worktree_branch_pr_merged(str(wt), cache=cache) is True
|
||||
assert worktree_ops._worktree_branch_pr_merged(str(wt), cache=cache) is True
|
||||
|
||||
def test_negative_verdict_not_cached(self, git_repo, tmp_path, monkeypatch):
|
||||
import cli
|
||||
wt = self._mk_diverged(git_repo, "hermes-nocache-neg")
|
||||
self._stub_gh(tmp_path, monkeypatch, stdout="[]")
|
||||
cache: dict = {}
|
||||
assert cli._worktree_branch_pr_merged(str(wt), cache=cache) is False
|
||||
assert worktree_ops._worktree_branch_pr_merged(str(wt), cache=cache) is False
|
||||
assert not [k for k in cache if k.startswith("pr-merged:")], (
|
||||
"False must not be memoized — the PR can merge later with the "
|
||||
"same (branch, head) key"
|
||||
|
||||
@@ -15,6 +15,8 @@ import time
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli import worktree_ops
|
||||
|
||||
|
||||
def _run(args, cwd):
|
||||
return subprocess.run(
|
||||
@@ -93,7 +95,7 @@ class TestFetchRemoteBranchHeads:
|
||||
import cli
|
||||
repo = repo_with_bare_origin
|
||||
_mk_worktree(repo, "hermes-a", "hermes/hermes-a", push=True)
|
||||
heads = cli._fetch_remote_branch_heads(str(repo))
|
||||
heads = worktree_ops._fetch_remote_branch_heads(str(repo))
|
||||
assert heads is not None
|
||||
assert "main" in heads
|
||||
assert "hermes/hermes-a" in heads
|
||||
@@ -104,7 +106,7 @@ class TestFetchRemoteBranchHeads:
|
||||
repo.mkdir()
|
||||
_run(["git", "init"], repo)
|
||||
_run(["git", "remote", "add", "origin", str(tmp_path / "missing.git")], repo)
|
||||
assert cli._fetch_remote_branch_heads(str(repo)) is None
|
||||
assert worktree_ops._fetch_remote_branch_heads(str(repo)) is None
|
||||
|
||||
|
||||
class TestBranchPushedExact:
|
||||
@@ -112,8 +114,8 @@ class TestBranchPushedExact:
|
||||
import cli
|
||||
repo = repo_with_bare_origin
|
||||
wt = _mk_worktree(repo, "hermes-x", "hermes/hermes-x", push=True)
|
||||
heads = cli._fetch_remote_branch_heads(str(repo))
|
||||
assert cli._worktree_branch_pushed_exact(str(wt), heads) is True
|
||||
heads = worktree_ops._fetch_remote_branch_heads(str(repo))
|
||||
assert worktree_ops._worktree_branch_pushed_exact(str(wt), heads) is True
|
||||
|
||||
def test_local_ahead_of_push_false(self, repo_with_bare_origin):
|
||||
import cli
|
||||
@@ -122,22 +124,22 @@ class TestBranchPushedExact:
|
||||
repo, "hermes-y", "hermes/hermes-y",
|
||||
push=True, extra_commit_after_push=True,
|
||||
)
|
||||
heads = cli._fetch_remote_branch_heads(str(repo))
|
||||
assert cli._worktree_branch_pushed_exact(str(wt), heads) is False
|
||||
heads = worktree_ops._fetch_remote_branch_heads(str(repo))
|
||||
assert worktree_ops._worktree_branch_pushed_exact(str(wt), heads) is False
|
||||
|
||||
def test_never_pushed_false(self, repo_with_bare_origin):
|
||||
import cli
|
||||
repo = repo_with_bare_origin
|
||||
wt = _mk_worktree(repo, "hermes-z", "hermes/hermes-z", push=False)
|
||||
heads = cli._fetch_remote_branch_heads(str(repo))
|
||||
assert cli._worktree_branch_pushed_exact(str(wt), heads) is False
|
||||
heads = worktree_ops._fetch_remote_branch_heads(str(repo))
|
||||
assert worktree_ops._worktree_branch_pushed_exact(str(wt), heads) is False
|
||||
|
||||
def test_none_heads_false(self, repo_with_bare_origin):
|
||||
import cli
|
||||
repo = repo_with_bare_origin
|
||||
wt = _mk_worktree(repo, "hermes-n", "hermes/hermes-n", push=True)
|
||||
assert cli._worktree_branch_pushed_exact(str(wt), None) is False
|
||||
assert cli._worktree_branch_pushed_exact(str(wt), {}) is False
|
||||
assert worktree_ops._worktree_branch_pushed_exact(str(wt), None) is False
|
||||
assert worktree_ops._worktree_branch_pushed_exact(str(wt), {}) is False
|
||||
|
||||
|
||||
class TestStartupPrunerPushedTier:
|
||||
|
||||
@@ -53,7 +53,7 @@ class TestCleanupFailedWorktreeAdd:
|
||||
return wt
|
||||
|
||||
def test_sweeps_dir_admin_entry_and_branch(self, repo):
|
||||
from cli import _cleanup_failed_worktree_add
|
||||
from hermes_cli.worktree_ops import _cleanup_failed_worktree_add
|
||||
|
||||
wt = self._simulate_timed_out_add(repo)
|
||||
admin = repo / ".git" / "worktrees" / "hermes-dead00"
|
||||
@@ -68,7 +68,7 @@ class TestCleanupFailedWorktreeAdd:
|
||||
|
||||
def test_retry_succeeds_after_cleanup(self, repo):
|
||||
"""The whole point: the same worktree name is creatable again."""
|
||||
from cli import _cleanup_failed_worktree_add
|
||||
from hermes_cli.worktree_ops import _cleanup_failed_worktree_add
|
||||
|
||||
wt = self._simulate_timed_out_add(repo)
|
||||
_cleanup_failed_worktree_add(str(repo), wt, "hermes/hermes-dead00")
|
||||
@@ -80,7 +80,7 @@ class TestCleanupFailedWorktreeAdd:
|
||||
|
||||
def test_noop_when_nothing_exists(self, repo):
|
||||
"""Fail-soft on an error path where git never created anything."""
|
||||
from cli import _cleanup_failed_worktree_add
|
||||
from hermes_cli.worktree_ops import _cleanup_failed_worktree_add
|
||||
|
||||
_cleanup_failed_worktree_add(
|
||||
str(repo), repo / ".worktrees" / "never-existed", "hermes/never-existed"
|
||||
|
||||
@@ -4,7 +4,7 @@ A worktree created off the standalone clone's local ``HEAD`` roots the new
|
||||
branch on a stale base when that clone lags the remote. ``_resolve_worktree_base``
|
||||
fetches and branches from the remote tip instead so the worktree starts current.
|
||||
|
||||
These tests exercise the REAL ``cli._resolve_worktree_base`` /
|
||||
These tests exercise the REAL ``worktree_ops._resolve_worktree_base`` /
|
||||
``cli._setup_worktree`` against a real local "remote" repo (so ``git fetch``
|
||||
works offline in the hermetic sandbox), proving the worktree includes commits
|
||||
that exist on the remote but not on the stale local HEAD.
|
||||
@@ -17,6 +17,8 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from hermes_cli import worktree_ops
|
||||
|
||||
import cli
|
||||
|
||||
|
||||
@@ -76,7 +78,7 @@ def remote_and_clone(tmp_path):
|
||||
class TestResolveWorktreeBase:
|
||||
def test_resolves_to_fetched_upstream(self, remote_and_clone):
|
||||
clone, remote_head, stale_local_head = remote_and_clone
|
||||
base_ref, label = cli._resolve_worktree_base(str(clone))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(clone))
|
||||
# Should resolve to the upstream tracking ref and have fetched it.
|
||||
assert base_ref == "origin/main"
|
||||
assert "fetched" in label
|
||||
@@ -92,7 +94,7 @@ class TestResolveWorktreeBase:
|
||||
_run(["git", "config", "user.email", "t@t.com"], repo)
|
||||
_run(["git", "config", "user.name", "T"], repo)
|
||||
_commit(repo, "README.md", "only commit")
|
||||
base_ref, label = cli._resolve_worktree_base(str(repo))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(repo))
|
||||
assert base_ref == "HEAD"
|
||||
assert "HEAD" in label
|
||||
|
||||
@@ -119,7 +121,7 @@ class TestResolveWorktreeBaseStartupCost:
|
||||
return real_run(args, **kw)
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", spy)
|
||||
base_ref, label = cli._resolve_worktree_base(str(clone))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(clone))
|
||||
assert base_ref == "origin/main"
|
||||
assert "fetched" in label and "ago" in label
|
||||
assert calls == [], "fresh FETCH_HEAD must skip the network fetch"
|
||||
@@ -134,7 +136,7 @@ class TestResolveWorktreeBaseStartupCost:
|
||||
fetch_head = Path(clone) / ".git" / "FETCH_HEAD"
|
||||
old = time.time() - 3600
|
||||
os.utime(fetch_head, (old, old))
|
||||
base_ref, label = cli._resolve_worktree_base(str(clone))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(clone))
|
||||
assert base_ref == "origin/main"
|
||||
assert label == "origin/main (fetched)"
|
||||
|
||||
@@ -154,7 +156,7 @@ class TestResolveWorktreeBaseStartupCost:
|
||||
|
||||
monkeypatch.setattr(subprocess, "run", stall_fetches)
|
||||
start = time.monotonic()
|
||||
base_ref, label = cli._resolve_worktree_base(str(clone))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(clone))
|
||||
elapsed = time.monotonic() - start
|
||||
# Cached tracking ref, single fetch attempt, no step-2 cascade.
|
||||
assert base_ref == "origin/main"
|
||||
@@ -185,7 +187,7 @@ class TestResolveWorktreeBaseStartupCost:
|
||||
_run(
|
||||
["git", "config", "branch.main.merge", "refs/heads/main"], repo
|
||||
)
|
||||
base_ref, label = cli._resolve_worktree_base(str(repo))
|
||||
base_ref, label = worktree_ops._resolve_worktree_base(str(repo))
|
||||
assert base_ref == "HEAD"
|
||||
assert "HEAD" in label
|
||||
|
||||
|
||||
Reference in New Issue
Block a user