fix: auto-start local adb daemon and optimize path discovery across Linux, macOS and Windows
This commit is contained in:
1 parent
8b3cfe9bb3
commit
41b1b94706
7 files changed
+114
No files matched your search
@@ -211,17 +211,21 @@ def heal_adb_keys(adb_path: str | None = None, force: bool = False) -> dict[str,
|
|||||||
|
|
||||||
# Restart ADB server to trigger key generation
|
# Restart ADB server to trigger key generation
|
||||||
try:
|
try:
|
||||||
|
clean_env = os.environ.copy()
|
||||||
|
clean_env.pop("ADB_SERVER_SOCKET", None)
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[resolved_adb, "kill-server"],
|
[resolved_adb, "kill-server"],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[resolved_adb, "start-server"],
|
[resolved_adb, "start-server"],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
# Execute adb devices to trigger initial handshake & key material generation if needed
|
# Execute adb devices to trigger initial handshake & key material generation if needed
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
@@ -229,6 +233,7 @@ def heal_adb_keys(adb_path: str | None = None, force: bool = False) -> dict[str,
|
|||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error restarting ADB server during key healing: {e}")
|
logger.error(f"Error restarting ADB server during key healing: {e}")
|
||||||
|
|||||||
@@ -246,17 +246,21 @@ class ReadinessEngine:
|
|||||||
return heal_adb_keys(adb_path=adb_path)
|
return heal_adb_keys(adb_path=adb_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
clean_env = os.environ.copy()
|
||||||
|
clean_env.pop("ADB_SERVER_SOCKET", None)
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[adb_path, "kill-server"],
|
[adb_path, "kill-server"],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
res = subprocess.run(
|
res = subprocess.run(
|
||||||
[adb_path, "start-server"],
|
[adb_path, "start-server"],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
timeout=5,
|
timeout=5,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
success = res.returncode == 0
|
success = res.returncode == 0
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -247,11 +247,14 @@ class DevicePool:
|
|||||||
return
|
return
|
||||||
proc = None
|
proc = None
|
||||||
try:
|
try:
|
||||||
|
clean_env = os.environ.copy()
|
||||||
|
clean_env.pop("ADB_SERVER_SOCKET", None)
|
||||||
proc = await asyncio.create_subprocess_exec(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
adb,
|
adb,
|
||||||
"start-server",
|
"start-server",
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
|
env=clean_env,
|
||||||
)
|
)
|
||||||
await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ function Update-EnvironmentPath {
|
|||||||
$standardDirs = @(
|
$standardDirs = @(
|
||||||
"$env:LOCALAPPDATA\Microsoft\WinGet\Links",
|
"$env:LOCALAPPDATA\Microsoft\WinGet\Links",
|
||||||
"$env:LOCALAPPDATA\Android\Sdk\platform-tools",
|
"$env:LOCALAPPDATA\Android\Sdk\platform-tools",
|
||||||
|
"$env:LOCALAPPDATA\Android\android-sdk\platform-tools",
|
||||||
"$env:ProgramFiles\Android\platform-tools",
|
"$env:ProgramFiles\Android\platform-tools",
|
||||||
|
"${env:ProgramFiles(x86)}\Android\android-sdk\platform-tools",
|
||||||
"$env:ProgramFiles\nodejs",
|
"$env:ProgramFiles\nodejs",
|
||||||
"${env:ProgramFiles(x86)}\nodejs",
|
"${env:ProgramFiles(x86)}\nodejs",
|
||||||
"$env:APPDATA\npm",
|
"$env:APPDATA\npm",
|
||||||
@@ -47,16 +49,34 @@ function Update-EnvironmentPath {
|
|||||||
"$env:LOCALAPPDATA\Programs\node",
|
"$env:LOCALAPPDATA\Programs\node",
|
||||||
"$env:USERPROFILE\.local\share\platform-tools",
|
"$env:USERPROFILE\.local\share\platform-tools",
|
||||||
"$env:USERPROFILE\.local\share\node",
|
"$env:USERPROFILE\.local\share\node",
|
||||||
|
"$env:LOCALAPPDATA\nvm",
|
||||||
|
"$env:ProgramData\nvm",
|
||||||
"C:\ProgramData\chocolatey\bin",
|
"C:\ProgramData\chocolatey\bin",
|
||||||
"$env:USERPROFILE\scoop\shims",
|
"$env:USERPROFILE\scoop\shims",
|
||||||
"$env:USERPROFILE\.local\bin",
|
"$env:USERPROFILE\.local\bin",
|
||||||
"$env:USERPROFILE\.cargo\bin"
|
"$env:USERPROFILE\.cargo\bin"
|
||||||
)
|
)
|
||||||
|
if ($env:ANDROID_HOME) { $standardDirs += "$env:ANDROID_HOME\platform-tools" }
|
||||||
|
if ($env:ANDROID_SDK_ROOT) { $standardDirs += "$env:ANDROID_SDK_ROOT\platform-tools" }
|
||||||
|
if ($env:NVM_HOME) { $standardDirs += $env:NVM_HOME }
|
||||||
|
if ($env:NVM_SYMLINK) { $standardDirs += $env:NVM_SYMLINK }
|
||||||
|
|
||||||
$regPath = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
|
$regPath = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||||
$currentPaths = ($env:PATH -split ";") + ($regPath -split ";") + $standardDirs | Where-Object { [string]::IsNullOrWhiteSpace($_) -eq $false -and (Test-Path $_) } | Select-Object -Unique
|
$currentPaths = ($env:PATH -split ";") + ($regPath -split ";") + $standardDirs | Where-Object { [string]::IsNullOrWhiteSpace($_) -eq $false -and (Test-Path $_) } | Select-Object -Unique
|
||||||
$env:PATH = $currentPaths -join ";"
|
$env:PATH = $currentPaths -join ";"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Start-LocalAdbServer {
|
||||||
|
if (Test-CommandExists "adb") {
|
||||||
|
try {
|
||||||
|
$origSocket = $env:ADB_SERVER_SOCKET
|
||||||
|
Remove-Item Env:\ADB_SERVER_SOCKET -ErrorAction SilentlyContinue
|
||||||
|
& adb start-server 2>$null | Out-Null
|
||||||
|
if ($origSocket) { $env:ADB_SERVER_SOCKET = $origSocket }
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Test-CommandExists {
|
function Test-CommandExists {
|
||||||
param([string]$Command)
|
param([string]$Command)
|
||||||
$res = Get-Command $Command -ErrorAction SilentlyContinue
|
$res = Get-Command $Command -ErrorAction SilentlyContinue
|
||||||
@@ -132,6 +152,7 @@ if (-not (Test-CommandExists "scrcpy")) { $missingTools += "scrcpy" }
|
|||||||
|
|
||||||
if ($missingTools.Count -eq 0) {
|
if ($missingTools.Count -eq 0) {
|
||||||
Write-Host " ✔ All system toolchains are already installed (ADB, FFmpeg, scrcpy)." -ForegroundColor Green
|
Write-Host " ✔ All system toolchains are already installed (ADB, FFmpeg, scrcpy)." -ForegroundColor Green
|
||||||
|
Start-LocalAdbServer
|
||||||
} else {
|
} else {
|
||||||
Write-Host " ! Missing toolchains: $($missingTools -join ', ')" -ForegroundColor DarkYellow
|
Write-Host " ! Missing toolchains: $($missingTools -join ', ')" -ForegroundColor DarkYellow
|
||||||
$useWinGet = $false
|
$useWinGet = $false
|
||||||
@@ -175,6 +196,9 @@ if ($missingTools.Count -eq 0) {
|
|||||||
if (-not (Test-CommandExists "adb")) {
|
if (-not (Test-CommandExists "adb")) {
|
||||||
Install-PortablePlatformTools
|
Install-PortablePlatformTools
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensure local ADB daemon is warm & listening
|
||||||
|
Start-LocalAdbServer
|
||||||
}
|
}
|
||||||
|
|
||||||
# 2. Check and Install uv (Fast Python Package Manager)
|
# 2. Check and Install uv (Fast Python Package Manager)
|
||||||
@@ -285,6 +309,7 @@ Write-Host " ✨ Artemis Environment Ready! " -Foreground
|
|||||||
Write-Host "======================================================" -ForegroundColor Cyan
|
Write-Host "======================================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
if ($Launch -or $Open) {
|
if ($Launch -or $Open) {
|
||||||
|
Start-LocalAdbServer
|
||||||
Write-Host "🚀 Launching Showcase UI..." -ForegroundColor Green
|
Write-Host "🚀 Launching Showcase UI..." -ForegroundColor Green
|
||||||
uv run artemis ui --open
|
uv run artemis ui --open
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -127,12 +127,31 @@ install_system_packages() {
|
|||||||
local need_ffmpeg=false
|
local need_ffmpeg=false
|
||||||
local need_scrcpy=false
|
local need_scrcpy=false
|
||||||
|
|
||||||
|
if ! has_cmd adb; then
|
||||||
|
for candidate in \
|
||||||
|
"${ANDROID_HOME:-}/platform-tools" \
|
||||||
|
"${ANDROID_SDK_ROOT:-}/platform-tools" \
|
||||||
|
"${HOME}/Library/Android/sdk/platform-tools" \
|
||||||
|
"${HOME}/Android/Sdk/platform-tools" \
|
||||||
|
"${HOME}/.local/share/platform-tools" \
|
||||||
|
"/opt/homebrew/bin" \
|
||||||
|
"/usr/local/bin"; do
|
||||||
|
if [ -n "${candidate}" ] && [ -x "${candidate}/adb" ]; then
|
||||||
|
export PATH="${candidate}:${PATH}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
if ! has_cmd adb; then need_adb=true; fi
|
if ! has_cmd adb; then need_adb=true; fi
|
||||||
if ! has_cmd ffmpeg; then need_ffmpeg=true; fi
|
if ! has_cmd ffmpeg; then need_ffmpeg=true; fi
|
||||||
if ! has_cmd scrcpy; then need_scrcpy=true; fi
|
if ! has_cmd scrcpy; then need_scrcpy=true; fi
|
||||||
|
|
||||||
if [ "${need_adb}" = false ] && [ "${need_ffmpeg}" = false ] && [ "${need_scrcpy}" = false ]; then
|
if [ "${need_adb}" = false ] && [ "${need_ffmpeg}" = false ] && [ "${need_scrcpy}" = false ]; then
|
||||||
echo -e " ${GREEN}✓ All core system tools are already installed.${NC}"
|
echo -e " ${GREEN}✓ All core system tools are already installed.${NC}"
|
||||||
|
if has_cmd adb; then
|
||||||
|
(unset ADB_SERVER_SOCKET; adb start-server >/dev/null 2>&1 || true)
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -234,6 +253,11 @@ install_system_packages() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure local ADB daemon is warm & listening
|
||||||
|
if has_cmd adb; then
|
||||||
|
(unset ADB_SERVER_SOCKET; adb start-server >/dev/null 2>&1 || true)
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to ensure uv is installed and ready
|
# Function to ensure uv is installed and ready
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ function Update-EnvironmentPath {
|
|||||||
$standardDirs = @(
|
$standardDirs = @(
|
||||||
"$env:LOCALAPPDATA\Microsoft\WinGet\Links",
|
"$env:LOCALAPPDATA\Microsoft\WinGet\Links",
|
||||||
"$env:LOCALAPPDATA\Android\Sdk\platform-tools",
|
"$env:LOCALAPPDATA\Android\Sdk\platform-tools",
|
||||||
|
"$env:LOCALAPPDATA\Android\android-sdk\platform-tools",
|
||||||
"$env:ProgramFiles\Android\platform-tools",
|
"$env:ProgramFiles\Android\platform-tools",
|
||||||
|
"${env:ProgramFiles(x86)}\Android\android-sdk\platform-tools",
|
||||||
"$env:ProgramFiles\nodejs",
|
"$env:ProgramFiles\nodejs",
|
||||||
"${env:ProgramFiles(x86)}\nodejs",
|
"${env:ProgramFiles(x86)}\nodejs",
|
||||||
"$env:APPDATA\npm",
|
"$env:APPDATA\npm",
|
||||||
@@ -42,16 +44,34 @@ function Update-EnvironmentPath {
|
|||||||
"$env:LOCALAPPDATA\Programs\node",
|
"$env:LOCALAPPDATA\Programs\node",
|
||||||
"$env:USERPROFILE\.local\share\platform-tools",
|
"$env:USERPROFILE\.local\share\platform-tools",
|
||||||
"$env:USERPROFILE\.local\share\node",
|
"$env:USERPROFILE\.local\share\node",
|
||||||
|
"$env:LOCALAPPDATA\nvm",
|
||||||
|
"$env:ProgramData\nvm",
|
||||||
"C:\ProgramData\chocolatey\bin",
|
"C:\ProgramData\chocolatey\bin",
|
||||||
"$env:USERPROFILE\scoop\shims",
|
"$env:USERPROFILE\scoop\shims",
|
||||||
"$env:USERPROFILE\.local\bin",
|
"$env:USERPROFILE\.local\bin",
|
||||||
"$env:USERPROFILE\.cargo\bin"
|
"$env:USERPROFILE\.cargo\bin"
|
||||||
)
|
)
|
||||||
|
if ($env:ANDROID_HOME) { $standardDirs += "$env:ANDROID_HOME\platform-tools" }
|
||||||
|
if ($env:ANDROID_SDK_ROOT) { $standardDirs += "$env:ANDROID_SDK_ROOT\platform-tools" }
|
||||||
|
if ($env:NVM_HOME) { $standardDirs += $env:NVM_HOME }
|
||||||
|
if ($env:NVM_SYMLINK) { $standardDirs += $env:NVM_SYMLINK }
|
||||||
|
|
||||||
$regPath = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
|
$regPath = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||||
$currentPaths = ($env:PATH -split ";") + ($regPath -split ";") + $standardDirs | Where-Object { [string]::IsNullOrWhiteSpace($_) -eq $false -and (Test-Path $_) } | Select-Object -Unique
|
$currentPaths = ($env:PATH -split ";") + ($regPath -split ";") + $standardDirs | Where-Object { [string]::IsNullOrWhiteSpace($_) -eq $false -and (Test-Path $_) } | Select-Object -Unique
|
||||||
$env:PATH = $currentPaths -join ";"
|
$env:PATH = $currentPaths -join ";"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Start-LocalAdbServer {
|
||||||
|
if (Test-CommandExists "adb") {
|
||||||
|
try {
|
||||||
|
$origSocket = $env:ADB_SERVER_SOCKET
|
||||||
|
Remove-Item Env:\ADB_SERVER_SOCKET -ErrorAction SilentlyContinue
|
||||||
|
& adb start-server 2>$null | Out-Null
|
||||||
|
if ($origSocket) { $env:ADB_SERVER_SOCKET = $origSocket }
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Test-CommandExists {
|
function Test-CommandExists {
|
||||||
param([string]$Command)
|
param([string]$Command)
|
||||||
$res = Get-Command $Command -ErrorAction SilentlyContinue
|
$res = Get-Command $Command -ErrorAction SilentlyContinue
|
||||||
@@ -164,6 +184,9 @@ if ($missingCore.Count -gt 0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensure local ADB daemon is warm & listening so probes do not hit 'Connection refused'
|
||||||
|
Start-LocalAdbServer
|
||||||
|
|
||||||
# 4. Check or initialize .env
|
# 4. Check or initialize .env
|
||||||
if (-not (Test-Path ".env")) {
|
if (-not (Test-Path ".env")) {
|
||||||
if (Test-Path ".env.example") {
|
if (Test-Path ".env.example") {
|
||||||
@@ -259,6 +282,9 @@ if ($installMcp -match "^[Yy]") {
|
|||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|
||||||
# 8. Launch unified Showcase UI & open browser
|
# 8. Launch unified Showcase UI & open browser
|
||||||
|
# Ensure local ADB daemon is warm & listening
|
||||||
|
Start-LocalAdbServer
|
||||||
|
|
||||||
# Launch via `python -m artemis` (not the `artemis.exe` console-script shim) so the
|
# Launch via `python -m artemis` (not the `artemis.exe` console-script shim) so the
|
||||||
# long-running server never locks .venv\Scripts\artemis.exe against `uv sync` reinstalls.
|
# long-running server never locks .venv\Scripts\artemis.exe against `uv sync` reinstalls.
|
||||||
Write-Host " [INFO] Launching Artemis Showcase UI & Admin Console..." -ForegroundColor Green
|
Write-Host " [INFO] Launching Artemis Showcase UI & Admin Console..." -ForegroundColor Green
|
||||||
|
|||||||
@@ -102,6 +102,23 @@ if ! command -v uv >/dev/null 2>&1; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Check and auto-install missing system toolchains (ADB, FFmpeg, scrcpy)
|
# 3. Check and auto-install missing system toolchains (ADB, FFmpeg, scrcpy)
|
||||||
|
# Discover standard Android SDK / user-space locations if adb not in PATH
|
||||||
|
if ! command -v adb >/dev/null 2>&1; then
|
||||||
|
for candidate in \
|
||||||
|
"${ANDROID_HOME:-}/platform-tools" \
|
||||||
|
"${ANDROID_SDK_ROOT:-}/platform-tools" \
|
||||||
|
"${HOME}/Library/Android/sdk/platform-tools" \
|
||||||
|
"${HOME}/Android/Sdk/platform-tools" \
|
||||||
|
"${HOME}/.local/share/platform-tools" \
|
||||||
|
"/opt/homebrew/bin" \
|
||||||
|
"/usr/local/bin"; do
|
||||||
|
if [ -n "${candidate}" ] && [ -x "${candidate}/adb" ]; then
|
||||||
|
export PATH="${candidate}:${PATH}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
MISSING_CORE=()
|
MISSING_CORE=()
|
||||||
if ! command -v adb >/dev/null 2>&1; then MISSING_CORE+=("adb"); fi
|
if ! command -v adb >/dev/null 2>&1; then MISSING_CORE+=("adb"); fi
|
||||||
if ! command -v ffmpeg >/dev/null 2>&1; then MISSING_CORE+=("ffmpeg"); fi
|
if ! command -v ffmpeg >/dev/null 2>&1; then MISSING_CORE+=("ffmpeg"); fi
|
||||||
@@ -175,6 +192,11 @@ if [ ${#MISSING_CORE[@]} -gt 0 ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure local ADB daemon is warm & listening so probes do not hit 'Connection refused'
|
||||||
|
if command -v adb >/dev/null 2>&1; then
|
||||||
|
(unset ADB_SERVER_SOCKET; adb start-server >/dev/null 2>&1 || true)
|
||||||
|
fi
|
||||||
|
|
||||||
# 4. Check or initialize .env configuration file
|
# 4. Check or initialize .env configuration file
|
||||||
if [ ! -f ".env" ]; then
|
if [ ! -f ".env" ]; then
|
||||||
if [ -f ".env.example" ]; then
|
if [ -f ".env.example" ]; then
|
||||||
@@ -314,6 +336,11 @@ if [ "${IS_REMOTE}" = true ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure local ADB daemon is active and listening before launching UI
|
||||||
|
if command -v adb >/dev/null 2>&1; then
|
||||||
|
(unset ADB_SERVER_SOCKET; adb start-server >/dev/null 2>&1 || true)
|
||||||
|
fi
|
||||||
|
|
||||||
# Launch via `python -m artemis` (not the `artemis` console-script shim) so the
|
# Launch via `python -m artemis` (not the `artemis` console-script shim) so the
|
||||||
# long-running server never pins .venv/Scripts/artemis[.exe] against reinstalls.
|
# long-running server never pins .venv/Scripts/artemis[.exe] against reinstalls.
|
||||||
exec uv run python -m artemis ui "${OPEN_FLAG}" "$@"
|
exec uv run python -m artemis ui "${OPEN_FLAG}" "$@"
|
||||||
Reference in new issue
Block a user