"""doctor: validate host prerequisites for running bot-bottle.""" from __future__ import annotations import argparse import shutil import subprocess import sys from pathlib import Path from ._common import PROG def _ok(label: str, detail: str) -> None: print(f"ok: {label}: {detail}") def _fail(label: str, detail: str) -> None: print(f"fail: {label}: {detail}") def _check_python() -> bool: version = sys.version_info detail = f"{version.major}.{version.minor}.{version.micro}" if version >= (3, 11): _ok("python", detail) return True _fail("python", f"{detail}; need 3.11 or newer") return False def _check_docker() -> bool: docker = shutil.which("docker") if not docker: _fail("docker", "docker command not found") return False try: result = subprocess.run( [docker, "info"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, timeout=10, ) except (OSError, subprocess.TimeoutExpired) as exc: _fail("docker", f"daemon check failed: {exc}") return False if result.returncode == 0: _ok("docker", "daemon reachable") return True _fail("docker", "daemon not reachable") return False def _check_config_dir() -> bool: config = Path.home() / ".bot-bottle" if config.is_dir(): _ok("config", str(config)) return True _fail("config", f"{config} does not exist") return False def cmd_doctor(argv: list[str]) -> int: parser = argparse.ArgumentParser(prog=f"{PROG} doctor", add_help=True) parser.parse_args(argv) checks = ( _check_python(), _check_docker(), _check_config_dir(), ) return 0 if all(checks) else 1