Files
claw-code/tests/_bash.py
Gracy769 ad8cd12fa2 test: ensure full candidate probing and clear cache in setUp
- Updates _check_bash_state to not short-circuit on the first unusable
  bash candidate on Windows, ensuring a working fallback is found if present.
- Clears bash detection cache in unittest setUp/tearDown rather than just
  relying on a pytest fixture, covering native unittest runners.
2026-10-12 22:06:08 +00:00

50 lines
1.7 KiB
Python

import functools
import os
import shutil
import subprocess
# Warning: _check_bash_state uses @functools.lru_cache.
# Do not monkeypatch os.environ['PATH'] or shutil.which in tests and expect
# these functions to re-evaluate. If you must patch them, call .cache_clear()
# before and after the test, or use the _clear_bash_cache pytest fixture.
def _probe_bash(bash_path: str) -> bool:
try:
res = subprocess.run([bash_path, '-c', 'echo 1'], capture_output=True, text=True, timeout=2)
return res.returncode == 0
except Exception:
return False
@functools.lru_cache(maxsize=1)
def _check_bash_state() -> tuple[str | None, str]:
reasons = []
if os.name == 'nt':
for candidate in (
r'C:\Program Files\Git\bin\bash.exe',
r'C:\Program Files\Git\usr\bin\bash.exe',
r'C:\Program Files (x86)\Git\bin\bash.exe',
os.path.expandvars(r'%LOCALAPPDATA%\Programs\Git\bin\bash.exe'),
):
if os.path.exists(candidate):
if _probe_bash(candidate):
return candidate, ""
reasons.append(f"present at {candidate} but unusable")
bash = shutil.which('bash')
if bash and 'WindowsApps' not in bash:
if _probe_bash(bash):
return bash, ""
reasons.append(f"present at {bash} but unusable")
if reasons:
return None, "bash found but broken: " + "; ".join(reasons)
return None, "Requires bash"
def get_bash_executable() -> str | None:
return _check_bash_state()[0]
def require_bash() -> bool:
return get_bash_executable() is not None
def bash_skip_reason() -> str:
return _check_bash_state()[1]