#!/usr/bin/env bash # Start the dev backend (FrankenPHP --watch) and the Qt host together, # tearing both down on Ctrl-C / exit / SIGTERM via process-group kill. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" SYMFONY_DIR="$APP_DIR/symfony" QT_BIN="$APP_DIR/build/qml/todo" : "${FRANKENPHP:=frankenphp}" : "${BRIDGE_URL:=http://127.0.0.1:8765}" : "${BRIDGE_TOKEN:=devtoken}" if [ ! -x "$QT_BIN" ]; then echo "Qt host not built. Run 'make build' first." >&2 exit 1 fi if ! command -v "$FRANKENPHP" >/dev/null 2>&1; then echo "frankenphp not on PATH. Set FRANKENPHP=/path/to/frankenphp or install it." >&2 exit 1 fi # Explicit PID-based teardown: SIGTERM the children, give them 2s, # then SIGKILL anything still alive. process-group `kill 0` proved # unreliable when FrankenPHP's --watch fork was reparented. FRANKEN_PID="" QT_PID="" cleanup() { trap - EXIT INT TERM for pid in "$QT_PID" "$FRANKEN_PID"; do [ -n "$pid" ] || continue kill -0 "$pid" 2>/dev/null || continue kill -TERM "$pid" 2>/dev/null || true for _ in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || break sleep 0.2 done kill -KILL "$pid" 2>/dev/null || true done } trap cleanup EXIT INT TERM (cd "$SYMFONY_DIR" && exec "$FRANKENPHP" run --watch --config ../Caddyfile) & FRANKEN_PID=$! echo "frankenphp PID=$FRANKEN_PID" # Wait for the backend to come up. Bail if FrankenPHP dies early. for _ in $(seq 1 50); do if curl -fsS -m 1 "$BRIDGE_URL/healthz" >/dev/null 2>&1; then break fi if ! kill -0 "$FRANKEN_PID" 2>/dev/null; then echo "frankenphp died before becoming ready" >&2 exit 1 fi sleep 0.2 done BRIDGE_URL="$BRIDGE_URL" BRIDGE_TOKEN="$BRIDGE_TOKEN" "$QT_BIN" & QT_PID=$! wait "$QT_PID"