Files
prop-ai-hr/scripts/dev.sh
T

165 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PIDS=()
usage() {
cat <<'EOF'
Usage: ./scripts/dev.sh [start|stop|restart|status|--reset]
Starts MySQL, Redis, MinIO, Qdrant, backend, admin frontend and legacy mobile fallback.
start start local demo services
stop stop backend and frontend dev processes
restart stop backend and frontend, then start again
status show local demo process status
--reset rebuild local demo database before starting services
EOF
}
cleanup() {
trap - INT TERM EXIT
for pid in "${PIDS[@]}"; do
kill "$pid" >/dev/null 2>&1 || true
done
}
ensure_docker() {
if docker info >/dev/null 2>&1; then
return
fi
if [[ "$(uname -s)" == "Darwin" ]] && [[ -d /Applications/Docker.app ]]; then
echo "Docker daemon is not running. Opening Docker Desktop..."
open -a Docker
for _ in {1..90}; do
if docker info >/dev/null 2>&1; then
echo "Docker daemon is ready."
return
fi
sleep 2
done
fi
echo "Docker daemon is not running. Start Docker Desktop, then run ./scripts/dev.sh again." >&2
exit 1
}
ensure_port_free() {
local port="$1"
if lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
echo "Port $port is already in use:" >&2
lsof -nP -iTCP:"$port" -sTCP:LISTEN >&2
echo "Stop the existing process, then run ./scripts/dev.sh again." >&2
exit 1
fi
}
stop_port() {
local port="$1"
local pids
pids="$(lsof -tiTCP:"$port" -sTCP:LISTEN || true)"
if [[ -z "$pids" ]]; then
echo "Port $port is not in use."
return
fi
echo "Stopping port $port: $pids"
kill $pids >/dev/null 2>&1 || true
for _ in {1..20}; do
if ! lsof -nP -iTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1; then
return
fi
sleep 0.2
done
kill -9 $pids >/dev/null 2>&1 || true
}
stop_dev() {
stop_port 8080
stop_port 5173
stop_port 5174
}
status() {
docker compose -f docker-compose.dev.yml ps
lsof -nP -iTCP:8080 -sTCP:LISTEN || true
lsof -nP -iTCP:5173 -sTCP:LISTEN || true
lsof -nP -iTCP:5174 -sTCP:LISTEN || true
}
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
usage
exit 0
fi
COMMAND="${1:-start}"
RESET=false
case "$COMMAND" in
start)
;;
--reset)
COMMAND="start"
RESET=true
;;
stop)
cd "$ROOT_DIR"
stop_dev
exit 0
;;
restart)
cd "$ROOT_DIR"
stop_dev
COMMAND="start"
;;
status)
cd "$ROOT_DIR"
status
exit 0
;;
*)
usage
exit 1
;;
esac
cd "$ROOT_DIR"
ensure_docker
ensure_port_free 8080
ensure_port_free 5173
ensure_port_free 5174
if [[ "$RESET" == true ]]; then
./scripts/reset-dev-db.sh
else
docker compose -f docker-compose.dev.yml up -d mysql redis qdrant minio minio-init
fi
trap cleanup INT TERM EXIT
./scripts/dev-backend.sh &
PIDS+=("$!")
./scripts/dev-frontend.sh &
PIDS+=("$!")
./scripts/dev-mobile.sh &
PIDS+=("$!")
echo "Backend: http://127.0.0.1:8080/"
echo "Admin: http://127.0.0.1:5173/"
echo "Legacy mobile fallback: http://127.0.0.1:5174/h5/user"
echo "Current user side: https://wygj-mobile-uni.localhost/h5/ (run: portless)"
echo "Qdrant: http://127.0.0.1:6333/"
echo "Press Ctrl+C to stop backend, admin frontend and legacy mobile frontend."
while :; do
for pid in "${PIDS[@]}"; do
if ! kill -0 "$pid" >/dev/null 2>&1; then
wait "$pid"
exit $?
fi
done
sleep 2
done