Skip to content

Commit 81e1aec

Browse files
committed
Prefer git bash in windows to wls bash
1 parent 4a11412 commit 81e1aec

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

sdk/src/tools/run-terminal-command.ts

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,25 @@ const GIT_BASH_COMMON_PATHS = [
2020
'C:\\Git\\bin\\bash.exe',
2121
]
2222

23+
// WSL bash paths that are often unreliable (VM may not be running, quote escaping issues)
24+
// These are checked last as a fallback only
25+
const WSL_BASH_PATH_PATTERNS = [
26+
'system32',
27+
'windowsapps',
28+
]
29+
2330
/**
2431
* Find bash executable on Windows.
2532
* Priority:
26-
* 1. CODEBUFF_GIT_BASH_PATH environment variable
27-
* 2. bash.exe in PATH (e.g., inside WSL or Git Bash terminal)
28-
* 3. Common Git Bash installation locations
33+
* 1. CODEBUFF_GIT_BASH_PATH environment variable (user override)
34+
* 2. Common Git Bash installation locations (most reliable)
35+
* 3. Non-WSL bash in PATH (e.g., Git Bash added to PATH)
36+
* 4. WSL bash in PATH (last resort - System32, WindowsApps)
37+
*
38+
* WSL bash is deprioritized because it can fail with cryptic errors when:
39+
* - The WSL VM is not running
40+
* - Quote/argument escaping issues between Windows and Linux
41+
* - UTF-16 encoding mismatches
2942
*/
3043
function findWindowsBash(env: NodeJS.ProcessEnv): string | null {
3144
// Check for user-specified path via environment variable
@@ -34,27 +47,48 @@ function findWindowsBash(env: NodeJS.ProcessEnv): string | null {
3447
return customPath
3548
}
3649

37-
// Check if bash.exe is in PATH (works inside WSL or Git Bash)
50+
// Check common Git Bash installation locations first (most reliable)
51+
for (const commonPath of GIT_BASH_COMMON_PATHS) {
52+
if (fs.existsSync(commonPath)) {
53+
return commonPath
54+
}
55+
}
56+
57+
// Fall back to bash.exe in PATH, but skip WSL paths initially
3858
const pathEnv = env.PATH || env.Path || ''
3959
const pathDirs = pathEnv.split(path.delimiter)
60+
const wslFallbackPaths: string[] = []
4061

4162
for (const dir of pathDirs) {
63+
const dirLower = dir.toLowerCase()
64+
const isWslPath = WSL_BASH_PATH_PATTERNS.some(pattern => dirLower.includes(pattern))
65+
4266
const bashPath = path.join(dir, 'bash.exe')
4367
if (fs.existsSync(bashPath)) {
44-
return bashPath
68+
if (isWslPath) {
69+
// Save WSL paths for last resort
70+
wslFallbackPaths.push(bashPath)
71+
} else {
72+
// Non-WSL bash in PATH (e.g., Git Bash added to PATH)
73+
return bashPath
74+
}
4575
}
46-
// Also check for just 'bash' (for WSL)
76+
77+
// Also check for just 'bash' (without .exe)
4778
const bashPathNoExt = path.join(dir, 'bash')
4879
if (fs.existsSync(bashPathNoExt)) {
49-
return bashPathNoExt
80+
if (isWslPath) {
81+
wslFallbackPaths.push(bashPathNoExt)
82+
} else {
83+
return bashPathNoExt
84+
}
5085
}
5186
}
5287

53-
// Check common Git Bash installation locations
54-
for (const commonPath of GIT_BASH_COMMON_PATHS) {
55-
if (fs.existsSync(commonPath)) {
56-
return commonPath
57-
}
88+
// Last resort: use WSL bash if nothing else is available
89+
// WSL can be unreliable (VM not running, quote escaping issues, UTF-16 encoding)
90+
if (wslFallbackPaths.length > 0) {
91+
return wslFallbackPaths[0]
5892
}
5993

6094
return null

0 commit comments

Comments
 (0)