62 lines
1.8 KiB
Bash
Executable File
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
|