"""Package / binary existence probes (cross-distro). Each probe accepts an optional *runner* callable with the same signature as ``subprocess.run``. Defaults to running on the host; for Docker tests, pass a runner that wraps ``docker run --rm ``. """ import subprocess from typing import Any, Callable Runner = Callable[..., Any] def _run(cmd: list[str], runner: Runner = subprocess.run, **kw: Any) -> Any: opts = {"capture_output": True, "text": True, "timeout": 30} opts.update(kw) return runner(cmd, **opts) def _succeeded(r: Any) -> bool: """.returncode==0 for CompletedProcess, or ["success"] for dict.""" if hasattr(r, "returncode"): return r.returncode == 0 return bool(r.get("success", False)) def binary_exists(path: str, runner: Runner = subprocess.run) -> bool: """Check if a binary exists at *path* (e.g. ``/usr/bin/curl``). Uses ``test -f`` (POSIX, guaranteed available). """ return _succeeded(_run(["test", "-f", path], runner)) def binary_on_path(name: str, runner: Runner = subprocess.run) -> bool: """Check if a command is on PATH (via ``command -v``).""" return _succeeded(_run(["sh", "-c", "command -v " + name], runner)) # Backward-compatible aliases package_installed = binary_exists package_version = binary_on_path # used in __init__ export, now binary-based