szabadpalya/scripts/up.sh

62 lines
1.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Start everything, in one command.
#
# ./scripts/up.sh
#
# Brings up Postgres, applies any migration that has not run yet, then runs the
# Go API and the Vite dev server together until Ctrl-C stops both.
#
# Open http://localhost:5173 — in development Vite serves the page and proxies
# /api to the Go process on :3000.
set -euo pipefail
cd "$(dirname "$0")/.."
[ -f .env ] || { echo "no .env — copy .env.example and fill it in"; exit 1; }
command -v pnpm >/dev/null || { echo "pnpm is missing — npm i -g pnpm"; exit 1; }
WEB_PID=
API_PID=
# Both halves are process trees, not processes: pnpm sits above vite, and the
# `docker run` client above the container. Kill depth-first so nothing is
# orphaned holding a port. Plain SIGTERM throughout — SIGINT would be ignored by
# the `go run` that is PID 1 inside the container.
kill_tree() {
local pid="$1" child
for child in $(pgrep -P "$pid" 2>/dev/null); do kill_tree "$child"; done
kill "$pid" 2>/dev/null || true
}
cleanup() {
local pid
for pid in $API_PID $WEB_PID; do kill_tree "$pid"; done
wait 2>/dev/null || true
}
trap 'exit 130' INT TERM
trap cleanup EXIT
./scripts/db.sh up
# Idempotent, so it can run on every start. This is what makes a fresh clone —
# or a pull that added a migration — work without a second command.
echo "applying migrations"
./scripts/dev.sh migrate </dev/null
[ -d web/node_modules ] || (cd web && pnpm install)
(cd web && pnpm dev) &
WEB_PID=$!
./scripts/dev.sh server </dev/null &
API_PID=$!
echo
echo " app http://localhost:5173"
echo " api http://localhost:3000"
echo " seed ./scripts/dev.sh seed (wipes campaigns, reloads the fixture)"
echo " stop Ctrl-C"
echo
# Whichever half stops first takes the other one with it, so a crashed API does
# not leave a frontend talking to nothing.
wait -n