mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 02:05:22 -04:00
Windows: improve Git Bash detection
This commit is contained in:
+36
-6
@@ -14,6 +14,7 @@ Design rules:
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import ntpath
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -134,11 +135,40 @@ _BASH_CACHE: Optional[str] = None
|
|||||||
_BASH_PROBED = False
|
_BASH_PROBED = False
|
||||||
|
|
||||||
# Common Git-for-Windows install locations to probe when bash isn't on PATH.
|
# Common Git-for-Windows install locations to probe when bash isn't on PATH.
|
||||||
_WINDOWS_BASH_FALLBACKS = (
|
_WINDOWS_BASH_ROOT_ENV_VARS = (
|
||||||
r"C:\Program Files\Git\bin\bash.exe",
|
"ProgramFiles",
|
||||||
r"C:\Program Files\Git\usr\bin\bash.exe",
|
"ProgramW6432",
|
||||||
r"C:\Program Files (x86)\Git\bin\bash.exe",
|
"ProgramFiles(x86)",
|
||||||
|
"LocalAppData",
|
||||||
)
|
)
|
||||||
|
_WINDOWS_BASH_DEFAULT_ROOTS = (
|
||||||
|
r"C:\Program Files\Git",
|
||||||
|
r"C:\Program Files (x86)\Git",
|
||||||
|
)
|
||||||
|
_WINDOWS_BASH_RELATIVE_PATHS = (
|
||||||
|
("bin", "bash.exe"),
|
||||||
|
("usr", "bin", "bash.exe"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _windows_bash_fallbacks() -> List[str]:
|
||||||
|
roots: List[str] = []
|
||||||
|
for env_name in _WINDOWS_BASH_ROOT_ENV_VARS:
|
||||||
|
base = os.environ.get(env_name)
|
||||||
|
if base:
|
||||||
|
roots.append(ntpath.join(base, "Git"))
|
||||||
|
roots.extend(_WINDOWS_BASH_DEFAULT_ROOTS)
|
||||||
|
|
||||||
|
paths: List[str] = []
|
||||||
|
seen = set()
|
||||||
|
for root in roots:
|
||||||
|
for rel in _WINDOWS_BASH_RELATIVE_PATHS:
|
||||||
|
path = ntpath.join(root, *rel)
|
||||||
|
key = path.lower()
|
||||||
|
if key not in seen:
|
||||||
|
seen.add(key)
|
||||||
|
paths.append(path)
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
def find_bash() -> Optional[str]:
|
def find_bash() -> Optional[str]:
|
||||||
@@ -153,9 +183,9 @@ def find_bash() -> Optional[str]:
|
|||||||
if _BASH_PROBED:
|
if _BASH_PROBED:
|
||||||
return _BASH_CACHE
|
return _BASH_CACHE
|
||||||
_BASH_PROBED = True
|
_BASH_PROBED = True
|
||||||
found = shutil.which("bash")
|
found = which_tool("bash")
|
||||||
if not found and IS_WINDOWS:
|
if not found and IS_WINDOWS:
|
||||||
for cand in _WINDOWS_BASH_FALLBACKS:
|
for cand in _windows_bash_fallbacks():
|
||||||
if os.path.exists(cand):
|
if os.path.exists(cand):
|
||||||
found = cand
|
found = cand
|
||||||
break
|
break
|
||||||
|
|||||||
+21
-1
@@ -30,6 +30,26 @@ function Fail($msg) {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Find-GitBash {
|
||||||
|
$cmd = Get-Command bash -ErrorAction SilentlyContinue
|
||||||
|
if ($cmd) { return $cmd.Source }
|
||||||
|
|
||||||
|
$roots = @()
|
||||||
|
foreach ($name in @("ProgramFiles", "ProgramW6432", "ProgramFiles(x86)", "LocalAppData")) {
|
||||||
|
$base = [Environment]::GetEnvironmentVariable($name)
|
||||||
|
if ($base) { $roots += (Join-Path $base "Git") }
|
||||||
|
}
|
||||||
|
$roots += @("C:\Program Files\Git", "C:\Program Files (x86)\Git")
|
||||||
|
|
||||||
|
foreach ($root in ($roots | Select-Object -Unique)) {
|
||||||
|
foreach ($relative in @("bin\bash.exe", "usr\bin\bash.exe")) {
|
||||||
|
$candidate = Join-Path $root $relative
|
||||||
|
if (Test-Path $candidate) { return $candidate }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
# 1. Locate a Python interpreter (3.11+ required)
|
# 1. Locate a Python interpreter (3.11+ required)
|
||||||
Write-Step "Checking for Python"
|
Write-Step "Checking for Python"
|
||||||
function Get-PythonVersionText($launcher, $launcherArgs) {
|
function Get-PythonVersionText($launcher, $launcherArgs) {
|
||||||
@@ -101,7 +121,7 @@ Write-Step "Running first-time setup"
|
|||||||
if ($LASTEXITCODE -ne 0) { Fail "setup.py failed." }
|
if ($LASTEXITCODE -ne 0) { Fail "setup.py failed." }
|
||||||
|
|
||||||
# 5. Friendly note about Git Bash (full Cookbook / agent-shell parity)
|
# 5. Friendly note about Git Bash (full Cookbook / agent-shell parity)
|
||||||
if (-not (Get-Command bash -ErrorAction SilentlyContinue)) {
|
if (-not (Find-GitBash)) {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "NOTE: Git Bash (bash.exe) was not found on PATH." -ForegroundColor Yellow
|
Write-Host "NOTE: Git Bash (bash.exe) was not found on PATH." -ForegroundColor Yellow
|
||||||
Write-Host " The core app works without it. For full Cookbook background" -ForegroundColor Yellow
|
Write-Host " The core app works without it. For full Cookbook background" -ForegroundColor Yellow
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
"""Regression tests for cross-platform helper behavior."""
|
||||||
|
|
||||||
|
from core import platform_compat
|
||||||
|
|
||||||
|
|
||||||
|
def _reset_bash_cache(monkeypatch):
|
||||||
|
monkeypatch.setattr(platform_compat, "_BASH_CACHE", None)
|
||||||
|
monkeypatch.setattr(platform_compat, "_BASH_PROBED", False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_bash_tries_windows_exe_suffix(monkeypatch):
|
||||||
|
_reset_bash_cache(monkeypatch)
|
||||||
|
monkeypatch.setattr(platform_compat, "IS_WINDOWS", True)
|
||||||
|
|
||||||
|
expected = r"C:\Program Files\Git\bin\bash.exe"
|
||||||
|
|
||||||
|
def fake_which(name):
|
||||||
|
return expected if name == "bash.exe" else None
|
||||||
|
|
||||||
|
monkeypatch.setattr(platform_compat.shutil, "which", fake_which)
|
||||||
|
monkeypatch.setattr(platform_compat.os.path, "exists", lambda _path: False)
|
||||||
|
|
||||||
|
assert platform_compat.find_bash() == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_bash_checks_local_app_data_git_install(monkeypatch):
|
||||||
|
_reset_bash_cache(monkeypatch)
|
||||||
|
monkeypatch.setattr(platform_compat, "IS_WINDOWS", True)
|
||||||
|
monkeypatch.setattr(platform_compat.shutil, "which", lambda _name: None)
|
||||||
|
for env_name in platform_compat._WINDOWS_BASH_ROOT_ENV_VARS:
|
||||||
|
monkeypatch.delenv(env_name, raising=False)
|
||||||
|
monkeypatch.setenv("LocalAppData", r"C:\Users\alice\AppData\Local")
|
||||||
|
|
||||||
|
expected = r"C:\Users\alice\AppData\Local\Git\bin\bash.exe"
|
||||||
|
monkeypatch.setattr(platform_compat.os.path, "exists", lambda path: path == expected)
|
||||||
|
|
||||||
|
assert platform_compat.find_bash() == expected
|
||||||
Reference in New Issue
Block a user