101 lines
2.2 KiB
Bash
Executable File
101 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -Eeuo pipefail
|
|
|
|
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
API_PID=""
|
|
SECRETARY_PID=""
|
|
WEB_PID=""
|
|
|
|
die() {
|
|
echo "[dev-local] $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || die "'$1' command not found"
|
|
}
|
|
|
|
ensure_port_free() {
|
|
local port="$1"
|
|
if lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
|
|
echo "[dev-local] port $port is already in use:" >&2
|
|
lsof -nP -iTCP:"$port" -sTCP:LISTEN >&2 || true
|
|
die "stop the process using port $port, then rerun the local server"
|
|
fi
|
|
}
|
|
|
|
wait_for_url() {
|
|
local name="$1"
|
|
local url="$2"
|
|
local attempts=90
|
|
|
|
echo "[dev-local] waiting for $name..."
|
|
for ((attempt = 1; attempt <= attempts; attempt++)); do
|
|
if curl -fsS --max-time 2 "$url" >/dev/null 2>&1; then
|
|
echo "[dev-local] $name is ready"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
die "$name did not respond at $url within ${attempts}s"
|
|
}
|
|
|
|
cleanup() {
|
|
local status=$?
|
|
trap - EXIT INT TERM
|
|
|
|
for pid in "$WEB_PID" "$SECRETARY_PID" "$API_PID"; do
|
|
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
kill "$pid" 2>/dev/null || true
|
|
fi
|
|
done
|
|
|
|
wait 2>/dev/null || true
|
|
exit "$status"
|
|
}
|
|
|
|
require_command curl
|
|
require_command lsof
|
|
require_command pnpm
|
|
|
|
[[ -x "$ROOT_DIR/apps/secretary-api/.venv/bin/uvicorn" ]] || \
|
|
die "Secretary API virtualenv is missing: apps/secretary-api/.venv/bin/uvicorn"
|
|
|
|
ensure_port_free 3100
|
|
ensure_port_free 4000
|
|
ensure_port_free 8010
|
|
|
|
trap cleanup EXIT INT TERM
|
|
|
|
(
|
|
cd "$ROOT_DIR/apps/api"
|
|
APP_ADDRESS=127.0.0.1 pnpm dev
|
|
) &
|
|
API_PID=$!
|
|
|
|
(
|
|
cd "$ROOT_DIR/apps/secretary-api"
|
|
./.venv/bin/uvicorn app.main:app --reload --host 127.0.0.1 --port 8010
|
|
) &
|
|
SECRETARY_PID=$!
|
|
|
|
(
|
|
cd "$ROOT_DIR/apps/web"
|
|
pnpm dev --hostname 127.0.0.1 --port 3100
|
|
) &
|
|
WEB_PID=$!
|
|
|
|
wait_for_url "API" "http://127.0.0.1:4000/api/health"
|
|
wait_for_url "Secretary API" "http://127.0.0.1:8010/api/health"
|
|
wait_for_url "Web" "http://127.0.0.1:3100/"
|
|
|
|
echo "[dev-local] all local servers are ready"
|
|
echo "API: http://127.0.0.1:4000"
|
|
echo "Secretary API: http://127.0.0.1:8010"
|
|
echo "Web: http://127.0.0.1:3100"
|
|
echo "Press Ctrl-C to stop all development servers."
|
|
|
|
wait -n "$API_PID" "$SECRETARY_PID" "$WEB_PID"
|