Skip to content

Commit f71ce48

Browse files
committed
test: use bare 'bash' for detection to match test invocation
On Windows, subprocess.run(['bash', ...]) uses CreateProcess which searches System32 before PATH — finding WSL bash even when shutil.which('bash') returns Git-for-Windows. Probe with bare 'bash' (same as test helpers) so the detection matches actual test behavior.
1 parent ca70454 commit f71ce48

1 file changed

Lines changed: 24 additions & 19 deletions

File tree

tests/conftest.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,47 @@
1414
def _has_working_bash() -> bool:
1515
"""Check whether a functional native bash is available.
1616
17+
On Windows, ``subprocess.run(["bash", ...])`` uses CreateProcess,
18+
which searches System32 *before* PATH — so it may find the WSL
19+
launcher even when Git-for-Windows bash appears first in PATH via
20+
``shutil.which``. We therefore probe with bare ``"bash"`` (the
21+
same way test helpers invoke it) to get an accurate result.
22+
1723
On Windows, only Git-for-Windows bash (MSYS2/MINGW) is accepted.
18-
The WSL launcher (System32\\bash.exe) is rejected because it runs in
19-
a separate Linux filesystem and cannot handle native Windows paths
20-
used by the test fixtures.
24+
The WSL launcher is rejected because it runs in a separate Linux
25+
filesystem and cannot handle native Windows paths used by the
26+
test fixtures.
2127
2228
Set SPECKIT_TEST_BASH=1 to force-enable bash tests regardless.
2329
"""
2430
if os.environ.get("SPECKIT_TEST_BASH") == "1":
2531
return True
26-
bash_path = shutil.which("bash")
27-
if bash_path is None:
32+
if shutil.which("bash") is None:
2833
return False
29-
# On Windows, reject the WSL launcher early (avoids WSL init prompts
30-
# and the 5 s timeout) and only accept MSYS/MINGW/CYGWIN bash.
31-
if sys.platform == "win32":
32-
if "system32" in bash_path.lower():
34+
# Probe with bare "bash" — same as the test helpers — so that
35+
# Windows CreateProcess resolution order is respected.
36+
try:
37+
r = subprocess.run(
38+
["bash", "-c", "echo ok"],
39+
capture_output=True, text=True, timeout=5,
40+
)
41+
if r.returncode != 0 or "ok" not in r.stdout:
3342
return False
43+
except (OSError, subprocess.TimeoutExpired):
44+
return False
45+
# On Windows, verify we have MSYS/MINGW bash (Git for Windows),
46+
# not the WSL launcher which can't handle native paths.
47+
if sys.platform == "win32":
3448
try:
3549
u = subprocess.run(
36-
[bash_path, "-c", "uname -s"],
50+
["bash", "-c", "uname -s"],
3751
capture_output=True, text=True, timeout=5,
3852
)
3953
kernel = u.stdout.strip().upper()
4054
if not any(k in kernel for k in ("MSYS", "MINGW", "CYGWIN")):
4155
return False
4256
except (OSError, subprocess.TimeoutExpired):
4357
return False
44-
try:
45-
r = subprocess.run(
46-
[bash_path, "-c", "echo ok"],
47-
capture_output=True, text=True, timeout=5,
48-
)
49-
if r.returncode != 0 or "ok" not in r.stdout:
50-
return False
51-
except (OSError, subprocess.TimeoutExpired):
52-
return False
5358
return True
5459

5560

0 commit comments

Comments
 (0)