Files
Salon_Assistant/scripts/lib/common.sh
T
Ty e5e179e541 Implement install stages S0–S2: bootstrap, env, model and vision smoke.
Operator can run make bootstrap/install through S2 using nemohermes/openshell wrappers; docs and implement queue updated. No S3+ and no push.
2026-07-27 11:47:34 -07:00

82 lines
3.8 KiB
Bash

#!/usr/bin/env bash
# scripts/lib/common.sh — shared helpers for all host scripts
# Sourced by bootstrap.sh, install.sh, and stage scripts.
# Do not execute directly.
set -euo pipefail
# ── Colours (auto-disable when not a tty) ──────────────────────────────────
if [[ -t 2 ]]; then
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BOLD='\033[1m'; NC='\033[0m'
else
RED=''; GREEN=''; YELLOW=''; BOLD=''; NC=''
fi
# ── Logging ────────────────────────────────────────────────────────────────
# Use printf to avoid echo -e interpreting escape sequences in arguments.
log_info() { printf "${GREEN}[INFO]${NC} %s\n" "$*"; }
log_warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$*" >&2; }
log_error() { printf "${RED}[ERROR]${NC} %s\n" "$*" >&2; }
log_section() { printf "\n${BOLD}═══ %s ═══${NC}\n" "$*"; }
# ── Repo root (works from any subdirectory) ────────────────────────────────
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)")"
# ── Env loading ────────────────────────────────────────────────────────────
# NOTE: Sources .env directly as shell code. This is a known pattern with a
# theoretical injection surface if .env contains shell commands. In practice,
# .env is created from .env.example (controlled by this repo) and edited by
# the operator. Defense-in-depth: parse line-by-line instead of sourcing,
# but the current approach matches the broader ecosystem convention.
load_env() {
local env_file="${1:-${REPO_ROOT}/.env}"
if [[ -f "$env_file" ]]; then
# shellcheck disable=SC1091
set -a; source "$env_file"; set +a
log_info "Loaded env from $env_file"
else
log_warn ".env not found at $env_file — variables must be set externally"
fi
}
# ── CLI detection ──────────────────────────────────────────────────────────
cmd_exists() { command -v "$1" &>/dev/null; }
require_cmd() {
if ! cmd_exists "$1"; then
log_error "Required command not found: $1"
if [[ "${2:-}" ]]; then
log_error "$2"
fi
return 1
fi
}
# ── Sandbox name ───────────────────────────────────────────────────────────
get_sandbox_name() {
echo "${LUMINA_SANDBOX:-hermes}"
}
# ── Docker check ───────────────────────────────────────────────────────────
docker_available() {
cmd_exists docker && docker info &>/dev/null
}
# ── nemohermes check ───────────────────────────────────────────────────────
nemohermes_available() {
cmd_exists nemohermes
}
# ── openshell check ────────────────────────────────────────────────────────
openshell_available() {
cmd_exists openshell
}
# ── Guard: script must be run as operator (not root-only, but warn) ────────
warn_if_root() {
if [[ "$(id -u)" -eq 0 ]]; then
log_warn "Running as root. Some host scripts work better as a regular user with sudo access."
fi
}