#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PYTHON_BIN="$ROOT_DIR/.venv/bin/python" NODE_BIN_DIR="$ROOT_DIR/.tools/node/bin" AUTH_FILE="$ROOT_DIR/backend/src/cache/auth.json" DATA_DIR="$ROOT_DIR/backend/data" ENV_FILE="$ROOT_DIR/.env" REQUIRED_DATA_FILES=( mapDenormalize.csv mapJumps.csv invTypes.csv mapRegions.csv ) print_usage() { cat <<'EOF' Usage: scripts/haul.sh Commands: check Show what is ready and what is still missing setup-data Download required EVE CSV files into backend/data setup-auth Create backend/src/cache/auth.json via EVE SSO backend Start only the Python backend on http://127.0.0.1:8000 frontend Start only the React frontend on http://127.0.0.1:3000 up Start backend and frontend together EOF } load_env() { if [[ -f "$ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a fi if [[ -n "${CHARACTER_ID:-}" && -z "${character_id:-}" ]]; then export character_id="$CHARACTER_ID" fi } require_python() { if [[ ! -x "$PYTHON_BIN" ]]; then echo "Missing Python virtualenv at $PYTHON_BIN" echo "Create it first or rerun environment setup." exit 1 fi } require_node() { if [[ ! -x "$NODE_BIN_DIR/node" || ! -x "$NODE_BIN_DIR/npm" ]]; then echo "Missing repo-local Node runtime under $NODE_BIN_DIR" exit 1 fi } require_frontend_install() { if [[ ! -d "$ROOT_DIR/frontend/node_modules" ]]; then echo "Missing frontend/node_modules" echo "Run: scripts/haul.sh frontend" exit 1 fi } backend_runtime_ready() { local missing=0 if [[ -z "${CLIENT_ID:-}" || -z "${SECRET_KEY:-}" || -z "${character_id:-}" ]]; then echo "Missing required env vars. Run: scripts/haul.sh setup-auth" missing=1 fi if [[ ! -f "$AUTH_FILE" ]]; then echo "Missing auth cache: $AUTH_FILE" echo "Run: scripts/haul.sh setup-auth" missing=1 fi for file_name in "${REQUIRED_DATA_FILES[@]}"; do if [[ ! -f "$DATA_DIR/$file_name" ]]; then echo "Missing data file: $DATA_DIR/$file_name" missing=1 fi done if [[ $missing -ne 0 ]]; then echo "Run: scripts/haul.sh setup-data" return 1 fi return 0 } print_status() { load_env if [[ -x "$PYTHON_BIN" ]]; then echo "python: ready ($PYTHON_BIN)" else echo "python: missing ($PYTHON_BIN)" fi if [[ -x "$NODE_BIN_DIR/node" ]]; then echo "node: ready ($NODE_BIN_DIR/node)" else echo "node: missing ($NODE_BIN_DIR/node)" fi if [[ -d "$ROOT_DIR/frontend/node_modules" ]]; then echo "frontend deps: ready" else echo "frontend deps: missing" fi if [[ -f "$AUTH_FILE" ]]; then echo "auth cache: ready" else echo "auth cache: missing" fi for file_name in "${REQUIRED_DATA_FILES[@]}"; do if [[ -f "$DATA_DIR/$file_name" ]]; then echo "data: ready ($file_name)" else echo "data: missing ($file_name)" fi done if [[ -f "$ENV_FILE" ]]; then echo ".env: present" else echo ".env: missing (setup-auth can create it)" fi } run_setup_data() { require_python exec "$PYTHON_BIN" "$ROOT_DIR/scripts/setup_eve_data.py" } run_setup_auth() { require_python load_env exec "$PYTHON_BIN" "$ROOT_DIR/scripts/setup_auth.py" } run_backend() { require_python load_env backend_runtime_ready cd "$ROOT_DIR/backend/src" exec "$PYTHON_BIN" -m uvicorn main:app --reload --host 127.0.0.1 --port 8000 } run_frontend() { require_node require_frontend_install export PATH="$NODE_BIN_DIR:$PATH" cd "$ROOT_DIR/frontend" exec npm start } run_up() { require_python require_node require_frontend_install load_env backend_runtime_ready export PATH="$NODE_BIN_DIR:$PATH" cd "$ROOT_DIR/backend/src" "$PYTHON_BIN" -m uvicorn main:app --host 127.0.0.1 --port 8000 & backend_pid=$! cleanup() { if kill -0 "$backend_pid" >/dev/null 2>&1; then kill "$backend_pid" wait "$backend_pid" 2>/dev/null || true fi } trap cleanup EXIT INT TERM cd "$ROOT_DIR/frontend" exec npm start } command_name="${1:-}" case "$command_name" in check) print_status ;; setup-data) run_setup_data ;; setup-auth) run_setup_auth ;; backend) run_backend ;; frontend) run_frontend ;; up) run_up ;; *) print_usage exit 1 ;; esac