91 lines
4.0 KiB
Bash
Executable File
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"
|