23980a3cf3
Co-authored-by: multica-agent <github@multica.ai>
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import subprocess
|
|
from dataclasses import dataclass
|
|
|
|
|
|
_WINE32_MISSING_HINTS = (
|
|
"it looks like wine32 is missing",
|
|
"wine32 is missing",
|
|
)
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class WineProbeResult:
|
|
available: bool
|
|
version: str | None
|
|
error: str | None
|
|
|
|
|
|
def interpret_wine_probe_output(returncode: int, output: bytes | str | None) -> WineProbeResult:
|
|
if isinstance(output, bytes):
|
|
text = output.decode("utf-8", errors="replace")
|
|
else:
|
|
text = output or ""
|
|
|
|
normalized = text.strip() or None
|
|
if normalized:
|
|
lowered = normalized.lower()
|
|
if any(hint in lowered for hint in _WINE32_MISSING_HINTS):
|
|
return WineProbeResult(available=False, version=normalized, error=normalized)
|
|
|
|
if returncode != 0:
|
|
return WineProbeResult(available=False, version=normalized, error=normalized)
|
|
|
|
return WineProbeResult(available=True, version=normalized, error=None)
|
|
|
|
|
|
def probe_wine_binary(resolved_binary: str, *, timeout_seconds: int = 10) -> WineProbeResult:
|
|
try:
|
|
completed = subprocess.run(
|
|
[resolved_binary, "--version"],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
check=False,
|
|
timeout=timeout_seconds,
|
|
)
|
|
except (OSError, subprocess.TimeoutExpired) as exc:
|
|
return WineProbeResult(available=False, version=None, error=str(exc))
|
|
|
|
return interpret_wine_probe_output(completed.returncode, completed.stdout)
|
|
|
|
|
|
async def probe_wine_binary_async(resolved_binary: str, *, timeout_seconds: int = 10) -> WineProbeResult:
|
|
try:
|
|
process = await asyncio.create_subprocess_exec(
|
|
resolved_binary,
|
|
"--version",
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.STDOUT,
|
|
)
|
|
output, _ = await asyncio.wait_for(process.communicate(), timeout=timeout_seconds)
|
|
except (OSError, asyncio.TimeoutError) as exc:
|
|
return WineProbeResult(available=False, version=None, error=str(exc))
|
|
|
|
return interpret_wine_probe_output(process.returncode, output)
|