Skip to content

Commit f2b0177

Browse files
authored
Merge pull request #238 from alex-feel/alex-feel-dev
Normalize extension case and prioritize Git Bash over WSL
2 parents 52e0bef + 76974c6 commit f2b0177

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

scripts/install_claude.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ def find_command_robust(cmd: str, fallback_paths: list[str] | None = None) -> st
169169
for attempt in range(2):
170170
cmd_path = shutil.which(cmd)
171171
if cmd_path:
172+
# Normalize extension case on Windows for Git Bash compatibility
173+
# shutil.which() uses Windows PATHEXT which has uppercase extensions (.EXE)
174+
# but Git Bash is case-sensitive and needs lowercase (.exe)
175+
if sys.platform == 'win32':
176+
path_obj = Path(cmd_path)
177+
ext = path_obj.suffix
178+
if ext.upper() in ['.EXE', '.CMD', '.BAT', '.COM'] and ext != ext.lower():
179+
cmd_path = str(path_obj.with_suffix(ext.lower()))
172180
return cmd_path
173181

174182
# Brief delay for PATH synchronization (especially on Windows)
@@ -325,18 +333,25 @@ def compare_versions(current: str, required: str) -> bool:
325333

326334
# Windows-specific functions
327335
def find_bash_windows() -> str | None:
328-
"""Find Git Bash on Windows."""
329-
# Check CLAUDE_CODE_GIT_BASH_PATH env var
336+
"""Find Git Bash on Windows.
337+
338+
Git Bash is required for Claude Code on Windows and provides consistent
339+
cross-platform bash behavior for CLI command execution.
340+
341+
Returns:
342+
Full path to bash.exe if found, None otherwise.
343+
344+
Note:
345+
Prioritizes Git Bash locations over PATH search to avoid
346+
accidentally finding WSL's bash.exe at C:\\Windows\\System32.
347+
"""
348+
# Check CLAUDE_CODE_GIT_BASH_PATH env var first
330349
env_path = os.environ.get('CLAUDE_CODE_GIT_BASH_PATH')
331350
if env_path and Path(env_path).exists():
332351
return str(Path(env_path).resolve())
333352

334-
# Check if bash is in PATH
335-
bash_path = find_command('bash.exe')
336-
if bash_path:
337-
return bash_path
338-
339-
# Check common locations
353+
# Check Git Bash common locations FIRST (before PATH search)
354+
# This prevents accidentally finding WSL's bash.exe in System32
340355
common_paths = [
341356
r'C:\Program Files\Git\bin\bash.exe',
342357
r'C:\Program Files\Git\usr\bin\bash.exe',
@@ -351,6 +366,15 @@ def find_bash_windows() -> str | None:
351366
if Path(expanded).exists():
352367
return str(Path(expanded).resolve())
353368

369+
# Fall back to PATH search (may find Git Bash if installed elsewhere)
370+
bash_path = find_command('bash.exe')
371+
if bash_path:
372+
# Skip WSL bash in System32/SysWOW64
373+
bash_lower = bash_path.lower()
374+
if 'system32' not in bash_lower and 'syswow64' not in bash_lower:
375+
return bash_path
376+
# WSL bash found - don't use it, return None instead
377+
354378
return None
355379

356380

scripts/setup_environment.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,14 @@ def find_command_robust(cmd: str, fallback_paths: list[str] | None = None) -> st
341341
for attempt in range(2):
342342
cmd_path = shutil.which(cmd)
343343
if cmd_path:
344+
# Normalize extension case on Windows for Git Bash compatibility
345+
# shutil.which() uses Windows PATHEXT which has uppercase extensions (.EXE)
346+
# but Git Bash is case-sensitive and needs lowercase (.exe)
347+
if sys.platform == 'win32':
348+
path_obj = Path(cmd_path)
349+
ext = path_obj.suffix
350+
if ext.upper() in ['.EXE', '.CMD', '.BAT', '.COM'] and ext != ext.lower():
351+
cmd_path = str(path_obj.with_suffix(ext.lower()))
344352
return cmd_path
345353

346354
# Brief delay for PATH synchronization (especially on Windows)
@@ -444,18 +452,18 @@ def find_bash_windows() -> str | None:
444452
445453
Returns:
446454
Full path to bash.exe if found, None otherwise.
455+
456+
Note:
457+
Prioritizes Git Bash locations over PATH search to avoid
458+
accidentally finding WSL's bash.exe at C:\\Windows\\System32.
447459
"""
448-
# Check CLAUDE_CODE_GIT_BASH_PATH env var
460+
# Check CLAUDE_CODE_GIT_BASH_PATH env var first
449461
env_path = os.environ.get('CLAUDE_CODE_GIT_BASH_PATH')
450462
if env_path and Path(env_path).exists():
451463
return str(Path(env_path).resolve())
452464

453-
# Check if bash is in PATH
454-
bash_path = find_command('bash.exe')
455-
if bash_path:
456-
return bash_path
457-
458-
# Check common locations
465+
# Check Git Bash common locations FIRST (before PATH search)
466+
# This prevents accidentally finding WSL's bash.exe in System32
459467
common_paths = [
460468
r'C:\Program Files\Git\bin\bash.exe',
461469
r'C:\Program Files\Git\usr\bin\bash.exe',
@@ -470,6 +478,15 @@ def find_bash_windows() -> str | None:
470478
if Path(expanded).exists():
471479
return str(Path(expanded).resolve())
472480

481+
# Fall back to PATH search (may find Git Bash if installed elsewhere)
482+
bash_path = find_command('bash.exe')
483+
if bash_path:
484+
# Skip WSL bash in System32/SysWOW64
485+
bash_lower = bash_path.lower()
486+
if 'system32' not in bash_lower and 'syswow64' not in bash_lower:
487+
return bash_path
488+
# WSL bash found - don't use it, return None instead
489+
473490
return None
474491

475492

0 commit comments

Comments
 (0)