#!/usr/bin/env bash set -euo pipefail POLYGUARD_ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" POLYGUARD_VENV_DIR="${POLYGUARD_VENV_DIR:-$POLYGUARD_ROOT_DIR/.venv}" POLYGUARD_PYTHON_BIN="$POLYGUARD_VENV_DIR/bin/python" POLYGUARD_PIP_BIN="$POLYGUARD_VENV_DIR/bin/pip" POLYGUARD_REQ_MARKER="$POLYGUARD_VENV_DIR/.requirements.sha256" requirements_fingerprint() { if command -v shasum >/dev/null 2>&1; then shasum -a 256 "$POLYGUARD_ROOT_DIR/requirements.txt" "$POLYGUARD_ROOT_DIR/pyproject.toml" | shasum -a 256 | awk '{print $1}' return fi if command -v sha256sum >/dev/null 2>&1; then sha256sum "$POLYGUARD_ROOT_DIR/requirements.txt" "$POLYGUARD_ROOT_DIR/pyproject.toml" | sha256sum | awk '{print $1}' return fi # Fallback deterministic value when hash tools are unavailable. echo "no_hash_tool" } venv_has_required_imports() { "$POLYGUARD_PYTHON_BIN" - <<'PY' modules = [ "fastapi", "uvicorn", "pydantic", "yaml", "numpy", "pandas", "pyarrow", "sklearn", "requests", "httpx", "trl", "transformers", "accelerate", "peft", "openenv", ] missing = [] for mod in modules: try: __import__(mod) except Exception: missing.append(mod) if missing: raise SystemExit(1) PY } ensure_polyguard_venv() { if [[ ! -x "$POLYGUARD_PYTHON_BIN" ]]; then python3 -m venv "$POLYGUARD_VENV_DIR" fi } sync_polyguard_requirements() { ensure_polyguard_venv local target_hash current_hash target_hash="$(requirements_fingerprint)" current_hash="" if [[ -f "$POLYGUARD_REQ_MARKER" ]]; then current_hash="$(cat "$POLYGUARD_REQ_MARKER")" fi if [[ "${POLYGUARD_FORCE_SYNC:-false}" != "true" && -n "$current_hash" && "$current_hash" == "$target_hash" ]]; then return fi if [[ "${POLYGUARD_FORCE_SYNC:-false}" != "true" ]] && venv_has_required_imports; then echo "$target_hash" > "$POLYGUARD_REQ_MARKER" return fi "$POLYGUARD_PIP_BIN" install --disable-pip-version-check --upgrade pip setuptools wheel "$POLYGUARD_PIP_BIN" install --disable-pip-version-check -r "$POLYGUARD_ROOT_DIR/requirements.txt" "$POLYGUARD_PIP_BIN" install --disable-pip-version-check --no-build-isolation -e "$POLYGUARD_ROOT_DIR" echo "$target_hash" > "$POLYGUARD_REQ_MARKER" } activate_polyguard_path() { export PATH="$POLYGUARD_VENV_DIR/bin:$PATH" export PYTHONPATH="${PYTHONPATH:-}:$POLYGUARD_ROOT_DIR" }