mirror of
https://github.com/instructkr/claw-code.git
synced 2026-10-18 00:00:11 +08:00
test: extract bash detection to shared _bash helper
Moves get_bash_executable and require_bash into a shared module so their lru_cache state is per-session rather than per-test-module. Also adds a comment regarding monkeypatching since lru_cache will silently drop changes to os.environ if it has already been populated. Closes follow-up items from PR review.
This commit is contained in:
1 parent
a916bf9d66
commit
c31c5e27dd
3 files changed
+38
-56
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import functools
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
# Warning: get_bash_executable and require_bash use @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.
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_bash_executable() -> str | None:
|
||||
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):
|
||||
return candidate
|
||||
bash = shutil.which('bash')
|
||||
if bash and 'WindowsApps' not in bash:
|
||||
return bash
|
||||
return None
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def require_bash() -> bool:
|
||||
bash = get_bash_executable()
|
||||
if not bash:
|
||||
return False
|
||||
try:
|
||||
res = subprocess.run([bash, '-c', 'echo 1'], capture_output=True, text=True, timeout=2)
|
||||
return res.returncode == 0
|
||||
except Exception:
|
||||
return False
|
||||
@@ -5,34 +5,7 @@ import subprocess
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_bash_executable() -> str | None:
|
||||
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):
|
||||
return candidate
|
||||
bash = shutil.which('bash')
|
||||
if bash and 'WindowsApps' not in bash:
|
||||
return bash
|
||||
return None
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def require_bash() -> bool:
|
||||
bash = get_bash_executable()
|
||||
if not bash:
|
||||
return False
|
||||
try:
|
||||
res = subprocess.run([bash, '-c', 'echo 1'], capture_output=True, text=True, timeout=2)
|
||||
return res.returncode == 0
|
||||
except Exception:
|
||||
return False
|
||||
from tests._bash import get_bash_executable, require_bash
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
@@ -14,34 +14,7 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
NEXT_ID = REPO_ROOT / 'scripts' / 'roadmap-next-id.sh'
|
||||
DOGFOOD_PROBE = REPO_ROOT / 'scripts' / 'dogfood-probe.py'
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def get_bash_executable() -> str | None:
|
||||
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):
|
||||
return candidate
|
||||
bash = shutil.which('bash')
|
||||
if bash and 'WindowsApps' not in bash:
|
||||
return bash
|
||||
return None
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def require_bash() -> bool:
|
||||
bash = get_bash_executable()
|
||||
if not bash:
|
||||
return False
|
||||
try:
|
||||
res = subprocess.run([bash, '-c', 'echo 1'], capture_output=True, text=True, timeout=2)
|
||||
return res.returncode == 0
|
||||
except Exception:
|
||||
return False
|
||||
from tests._bash import get_bash_executable, require_bash
|
||||
|
||||
|
||||
def run_next_id(roadmap: Path, script: Path = NEXT_ID) -> subprocess.CompletedProcess[str]:
|
||||
|
||||
Reference in new issue
Block a user