cyberhybridhub/startup.sh

99 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Start the API (port 3000) and Flutter web dev server (port 8080) with merged logs.
# Usage: ./startup.sh
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
API_PORT=3000
WEB_PORT=8080
if [ -f "$ROOT/scripts/flutter-env.sh" ]; then
# shellcheck source=/dev/null
source "$ROOT/scripts/flutter-env.sh"
fi
log() { printf '%s\n' "$*"; }
kill_port() {
local port=$1
if command -v fuser >/dev/null 2>&1; then
if fuser "${port}/tcp" >/dev/null 2>&1; then
log "Stopping process(es) on port ${port}..."
fuser -k "${port}/tcp" >/dev/null 2>&1 || true
sleep 0.5
fi
return
fi
if ! command -v lsof >/dev/null 2>&1; then
warn "Cannot free port ${port}: install fuser or lsof"
return
fi
local pids
pids="$(lsof -t -iTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)"
if [ -n "$pids" ]; then
log "Stopping process(es) on port ${port}: ${pids}"
# shellcheck disable=SC2086
kill ${pids} 2>/dev/null || true
sleep 0.5
# shellcheck disable=SC2086
kill -9 ${pids} 2>/dev/null || true
fi
}
warn() { printf 'WARN: %s\n' "$*" >&2; }
prefix_lines() {
local tag=$1
while IFS= read -r line || [ -n "${line:-}" ]; do
printf '[%s] %s\n' "$tag" "$line"
done
}
cleanup() {
trap - INT TERM EXIT
log "Shutting down..."
if [ -n "${API_PID:-}" ]; then kill "$API_PID" 2>/dev/null || true; fi
if [ -n "${WEB_PID:-}" ]; then kill "$WEB_PID" 2>/dev/null || true; fi
kill_port "$API_PORT"
kill_port "$WEB_PORT"
wait 2>/dev/null || true
}
trap cleanup INT TERM EXIT
log "Freeing ports ${API_PORT} (API) and ${WEB_PORT} (web)..."
kill_port "$API_PORT"
kill_port "$WEB_PORT"
if [ ! -f "$ROOT/server/.env" ]; then
warn "Missing server/.env — copy server/.env.example and configure it first."
fi
log "Starting API on http://localhost:${API_PORT} ..."
(
cd "$ROOT/server"
dart run bin/server.dart 2>&1 | prefix_lines api
) &
API_PID=$!
log "Starting web app on http://localhost:${WEB_PORT} ..."
(
cd "$ROOT"
flutter run -d web-server \
--dart-define=API_BASE_URL="http://localhost:${API_PORT}" \
2>&1 | prefix_lines web
) &
WEB_PID=$!
log "Both services running. Press Ctrl+C to stop."
log " API: http://localhost:${API_PORT}"
log " Web: http://localhost:${WEB_PORT}"
log ""
wait -n 2>/dev/null || wait || true
exit_code=$?
cleanup
exit "$exit_code"