43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
"""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 <image>``.
|
|
"""
|
|
|
|
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
|