mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-09 13:21:42 +00:00
fix terminal cwd handling on windows
This commit is contained in:
parent
ad5f3341d3
commit
9ed7252a98
2 changed files with 73 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ from tools.environments.local import (
|
|||
LocalEnvironment,
|
||||
_msys_to_windows_path,
|
||||
_resolve_safe_cwd,
|
||||
_windows_to_msys_path,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -70,6 +71,35 @@ class TestMsysToWindowsPath:
|
|||
assert _msys_to_windows_path("") == ""
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _windows_to_msys_path — reverse translation for bash builtin cd
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestWindowsToMsysPath:
|
||||
def test_noop_on_non_windows(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", False)
|
||||
assert _windows_to_msys_path(r"C:\Users\NVIDIA") == r"C:\Users\NVIDIA"
|
||||
|
||||
def test_translates_backslash_path(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", True)
|
||||
assert _windows_to_msys_path(r"C:\Users\NVIDIA") == "/c/Users/NVIDIA"
|
||||
assert _windows_to_msys_path(r"D:\Projects\foo bar") == "/d/Projects/foo bar"
|
||||
|
||||
def test_translates_forward_slash_native_path(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", True)
|
||||
assert _windows_to_msys_path("C:/Users/NVIDIA") == "/c/Users/NVIDIA"
|
||||
|
||||
def test_translates_drive_root(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", True)
|
||||
assert _windows_to_msys_path(r"C:\\") == "/c/"
|
||||
assert _windows_to_msys_path("D:/") == "/d/"
|
||||
|
||||
def test_does_not_translate_non_drive_path(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", True)
|
||||
assert _windows_to_msys_path("/tmp/foo") == "/tmp/foo"
|
||||
assert _windows_to_msys_path(r"\\server\share") == r"\\server\share"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _resolve_safe_cwd — Windows fast path
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -196,3 +226,23 @@ class TestExtractCwdFromOutputWindowsMsys:
|
|||
env._extract_cwd_from_output(result)
|
||||
|
||||
assert env.cwd == str(new_dir)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Command wrapping — native Windows cwd must be Git Bash-friendly for cd
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestWrapCommandWindowsNativeCwd:
|
||||
def test_wrap_command_converts_native_cwd_for_builtin_cd(self, monkeypatch):
|
||||
monkeypatch.setattr(local_mod, "_IS_WINDOWS", True)
|
||||
|
||||
with patch.object(
|
||||
LocalEnvironment, "init_session", autospec=True, return_value=None
|
||||
):
|
||||
env = LocalEnvironment(cwd=r"C:\Users\liush", timeout=10)
|
||||
|
||||
env._snapshot_ready = True
|
||||
wrapped = env._wrap_command("pwd", r"C:\Users\liush")
|
||||
|
||||
assert "builtin cd -- /c/Users/liush || exit 126" in wrapped
|
||||
assert r"builtin cd -- C:\Users\liush || exit 126" not in wrapped
|
||||
|
|
|
|||
|
|
@ -40,6 +40,24 @@ def _msys_to_windows_path(cwd: str) -> str:
|
|||
return f"{drive}:{tail or chr(92)}" # chr(92) = backslash, avoid raw-string escape
|
||||
|
||||
|
||||
def _windows_to_msys_path(cwd: str) -> str:
|
||||
"""Translate a native Windows path (``C:\\Users\\x``) to Git Bash /
|
||||
MSYS form (``/c/Users/x``) so ``builtin cd`` resolves it reliably.
|
||||
|
||||
No-ops on non-Windows hosts or for paths that aren't drive-qualified
|
||||
native Windows paths. Returns the input unchanged when no translation
|
||||
applies.
|
||||
"""
|
||||
if not _IS_WINDOWS or not cwd:
|
||||
return cwd
|
||||
m = re.match(r'^([a-zA-Z]):[\\/]*(.*)$', cwd)
|
||||
if not m:
|
||||
return cwd
|
||||
drive = m.group(1).lower()
|
||||
tail = (m.group(2) or "").replace('\\', '/').lstrip('/')
|
||||
return f"/{drive}/{tail}" if tail else f"/{drive}/"
|
||||
|
||||
|
||||
def _resolve_safe_cwd(cwd: str) -> str:
|
||||
"""Return ``cwd`` if it exists as a directory, else the nearest existing
|
||||
ancestor. Falls back to ``tempfile.gettempdir()`` only if walking up the
|
||||
|
|
@ -921,6 +939,11 @@ class LocalEnvironment(BaseEnvironment):
|
|||
|
||||
return "/tmp"
|
||||
|
||||
@staticmethod
|
||||
def _quote_cwd_for_cd(cwd: str) -> str:
|
||||
"""Use native paths for Python, but Git Bash-friendly paths for cd."""
|
||||
return BaseEnvironment._quote_cwd_for_cd(_windows_to_msys_path(cwd))
|
||||
|
||||
def _run_bash(self, cmd_string: str, *, login: bool = False,
|
||||
timeout: int = 120,
|
||||
stdin_data: str | None = None) -> subprocess.Popen:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue