Files

91 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Starts the FastAPI backend and Vite frontend for local development.
# Run from anywhere — paths are resolved relative to this script.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKEND_DIR="$SCRIPT_DIR/backend"
FRONTEND_DIR="$SCRIPT_DIR/frontend"
VENV="$BACKEND_DIR/.venv"
# Match whichever ROS_DOMAIN_ID the robot containers are using (default 0).
# Override: ROS_DOMAIN_ID=42 ./dev.sh
ROS_DOMAIN_ID="${ROS_DOMAIN_ID:-0}"
# Hostname of the WebRTC signaling server (default: same host as the page).
# Override: VITE_WEBRTC_HOST=rapsbot-v2.local ./dev.sh
# Or set VITE_WEBRTC_HOST in frontend/.env.local (see .env.local.example).
export VITE_WEBRTC_HOST="${VITE_WEBRTC_HOST:-}"
# ── colour helpers ────────────────────────────────────────────────────────────
G='\033[0;32m'; Y='\033[1;33m'; R='\033[0;31m'; NC='\033[0m'
info() { echo -e "${G}[webui]${NC} $*"; }
warn() { echo -e "${Y}[webui]${NC} $*"; }
error() { echo -e "${R}[webui]${NC} $*" >&2; }
# ── sanity checks ─────────────────────────────────────────────────────────────
if [ -z "${ROS_DISTRO:-}" ]; then
error "ROS_DISTRO is not set. Source a ROS setup file first, or rebuild the devcontainer."
exit 1
fi
if ! command -v node &>/dev/null; then
error "Node.js not found. Rebuild the devcontainer to install it (see .devcontainer/Dockerfile)."
exit 1
fi
# ── backend: venv ─────────────────────────────────────────────────────────────
# Prefer the venv baked into the devcontainer image; fall back to a local one.
if [ -d "/opt/webui-venv" ]; then
VENV="/opt/webui-venv"
info "Using devcontainer venv at $VENV"
else
if [ ! -d "$VENV" ]; then
info "Creating Python venv at $VENV..."
python3 -m venv "$VENV"
fi
info "Syncing backend dependencies..."
"$VENV/bin/pip" install -q -r "$BACKEND_DIR/requirements.txt"
fi
# ── frontend: npm deps ────────────────────────────────────────────────────────
if [ ! -d "$FRONTEND_DIR/node_modules" ]; then
info "Installing frontend dependencies..."
npm --prefix "$FRONTEND_DIR" install
fi
# ── cleanup on exit ───────────────────────────────────────────────────────────
BACKEND_PID=""
FRONTEND_PID=""
cleanup() {
warn "Shutting down..."
[ -n "$BACKEND_PID" ] && kill "$BACKEND_PID" 2>/dev/null || true
[ -n "$FRONTEND_PID" ] && kill "$FRONTEND_PID" 2>/dev/null || true
wait "$BACKEND_PID" "$FRONTEND_PID" 2>/dev/null || true
}
trap cleanup EXIT INT TERM
# ── start backend ─────────────────────────────────────────────────────────────
info "Starting FastAPI backend on :8080 (ROS_DOMAIN_ID=$ROS_DOMAIN_ID)"
(
# shellcheck disable=SC1091
set +u # ROS setup.bash references AMENT_TRACE_SETUP_FILES without a default
source "/opt/ros/$ROS_DISTRO/setup.bash"
export ROS_DOMAIN_ID
exec "$VENV/bin/python3" "$BACKEND_DIR/main.py"
) &
BACKEND_PID=$!
# ── start frontend ────────────────────────────────────────────────────────────
info "Starting Vite dev server on :5173"
npm --prefix "$FRONTEND_DIR" run dev &
FRONTEND_PID=$!
info "Ready — open http://localhost:5173"
info "Press Ctrl+C to stop both processes."
echo
# Exit as soon as either process dies
wait -n "$BACKEND_PID" "$FRONTEND_PID"