""" Workstation (Docker) build helpers for the Prole installer (root-level). Compose a deterministic Docker build command and derive the image tag version from the workstation/Dockerfile. Includes helpers to check if the current image tag already exists locally to avoid redundant builds. """ from __future__ import annotations from pathlib import Path import re import subprocess from . import config as cfg def get_workstation_version(project_root: Path) -> str: """Parse the workstation Dockerfile for a version. Looks for one of the following (first match wins): - ARG WORKSTATION_VERSION=1.2.3 - LABEL org.opencontainers.image.version="1.2.3" Falls back to "0.1.0" if none found. """ ws = Path(project_root) / "workstation" / "Dockerfile" default_ver = "0.1.0" try: text = ws.read_text(encoding="utf-8") except Exception: return default_ver # ARG pattern m = re.search(r"^\s*ARG\s+WORKSTATION_VERSION\s*=\s*([\w\.-]+)\s*$", text, re.MULTILINE) if m: return m.group(1) # LABEL pattern m2 = re.search(r"org\.opencontainers\.image\.version\s*=\s*\"?([\w\.-]+)\"?", text) if m2: return m2.group(1) return default_ver def get_docker_build_command(project_root: Path) -> str: """Return the canonical Docker build command for the workstation image. docker build -t prole-workstation: . Includes platform flags for Apple Silicon when appropriate. """ ws = Path(project_root) / "workstation" version = get_workstation_version(project_root) platform_args = cfg.get_docker_build_platform_args() plat = (" ".join(platform_args) + " ") if platform_args else "" return f"cd \"{ws}\" && docker build {plat}-t prole-workstation:{version} ." def is_workstation_image_current(project_root: Path) -> bool: """Return True if the local Docker image prole-workstation: exists. This checks only for the presence of the tag. It does not verify whether the image is up-to-date with the Dockerfile. For most installer scenarios, skipping a rebuild when the tag exists is sufficient and saves time. """ version = get_workstation_version(project_root) try: r = subprocess.run( ["bash", "-lc", f"docker image inspect prole-workstation:{version} >/dev/null 2>&1"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) return r.returncode == 0 except Exception: return False