#!/bin/bash # ThrillWiki Development Server Starter # Starts both Django backend and Vue.js frontend servers concurrently set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Script directory and project root SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)" # Configuration BACKEND_PORT=8000 FRONTEND_PORT=5174 BACKEND_DIR="$PROJECT_ROOT/backend" FRONTEND_DIR="$PROJECT_ROOT/frontend" # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Function to check if a port is available check_port() { local port=$1 if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then return 1 else return 0 fi } # Function to kill process on port kill_port() { local port=$1 local pid=$(lsof -ti:$port) if [ ! -z "$pid" ]; then print_warning "Killing process $pid on port $port" kill -9 $pid fi } # Function to wait for service to be ready wait_for_service() { local url=$1 local service_name=$2 local max_attempts=30 local attempt=1 print_status "Waiting for $service_name to be ready at $url" while [ $attempt -le $max_attempts ]; do if curl -s -f "$url" > /dev/null 2>&1; then print_success "$service_name is ready!" return 0 fi echo -n "." sleep 2 ((attempt++)) done print_error "$service_name failed to start after $max_attempts attempts" return 1 } # Function to start backend server start_backend() { print_status "Starting Django backend server..." # Kill any existing process on backend port kill_port $BACKEND_PORT # Clean up Python cache files find "$BACKEND_DIR" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true cd "$BACKEND_DIR" # Check if virtual environment exists if [ ! -d ".venv" ]; then print_error "Backend virtual environment not found. Please run setup-dev.sh first." exit 1 fi # Start Django server in background print_status "Starting Django development server on port $BACKEND_PORT" uv run manage.py runserver 0.0.0.0:$BACKEND_PORT & BACKEND_PID=$! # Wait for backend to be ready wait_for_service "http://localhost:$BACKEND_PORT/api/" "Django backend" cd "$PROJECT_ROOT" } # Function to start frontend server start_frontend() { print_status "Starting Vue.js frontend server..." cd "$FRONTEND_DIR" # Check if node_modules exists if [ ! -d "node_modules" ]; then print_error "Frontend dependencies not installed. Please run setup-dev.sh first." exit 1 fi # Start Vue.js dev server in background print_status "Starting Vue.js development server on port $FRONTEND_PORT" pnpm run dev & FRONTEND_PID=$! # Wait for frontend to be ready wait_for_service "http://localhost:$FRONTEND_PORT" "Vue.js frontend" cd "$PROJECT_ROOT" } # Function to cleanup on script exit cleanup() { print_warning "Shutting down development servers..." if [ ! -z "$BACKEND_PID" ]; then kill $BACKEND_PID 2>/dev/null || true fi if [ ! -z "$FRONTEND_PID" ]; then kill $FRONTEND_PID 2>/dev/null || true fi # Kill any remaining processes on our ports kill_port $BACKEND_PORT kill_port $FRONTEND_PORT print_success "Development servers stopped." exit 0 } # Function to show usage show_usage() { cat << EOF Usage: $0 [OPTIONS] Start both Django backend and Vue.js frontend development servers. Options: -h, --help Show this help message -b, --backend-only Start only the backend server -f, --frontend-only Start only the frontend server -p, --production Start in production mode (if applicable) --no-wait Don't wait for services to be ready Examples: $0 # Start both servers $0 --backend-only # Start only backend $0 --frontend-only # Start only frontend Environment Variables: BACKEND_PORT Backend server port (default: 8000) FRONTEND_PORT Frontend server port (default: 5174) EOF } # Parse command line arguments BACKEND_ONLY=false FRONTEND_ONLY=false PRODUCTION=false WAIT_FOR_SERVICES=true while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_usage exit 0 ;; -b|--backend-only) BACKEND_ONLY=true shift ;; -f|--frontend-only) FRONTEND_ONLY=true shift ;; -p|--production) PRODUCTION=true shift ;; --no-wait) WAIT_FOR_SERVICES=false shift ;; *) print_error "Unknown option: $1" show_usage exit 1 ;; esac done # Override ports from environment if set if [ ! -z "$BACKEND_PORT_ENV" ]; then BACKEND_PORT=$BACKEND_PORT_ENV fi if [ ! -z "$FRONTEND_PORT_ENV" ]; then FRONTEND_PORT=$FRONTEND_PORT_ENV fi # Set up signal handlers for graceful shutdown trap cleanup SIGINT SIGTERM # Print banner echo -e "${GREEN}" echo "==========================================" echo " ThrillWiki Development Environment" echo "==========================================" echo -e "${NC}" print_status "Project root: $PROJECT_ROOT" print_status "Backend port: $BACKEND_PORT" print_status "Frontend port: $FRONTEND_PORT" # Check if required tools are available command -v uv >/dev/null 2>&1 || { print_error "uv is required but not installed. Please install uv first."; exit 1; } command -v pnpm >/dev/null 2>&1 || { print_error "pnpm is required but not installed. Please install pnpm first."; exit 1; } command -v curl >/dev/null 2>&1 || { print_error "curl is required but not installed."; exit 1; } # Start services based on options if [ "$BACKEND_ONLY" = true ]; then print_status "Starting backend only..." start_backend print_success "Backend server started successfully!" print_status "Backend URL: http://localhost:$BACKEND_PORT" print_status "API URL: http://localhost:$BACKEND_PORT/api/" wait elif [ "$FRONTEND_ONLY" = true ]; then print_status "Starting frontend only..." start_frontend print_success "Frontend server started successfully!" print_status "Frontend URL: http://localhost:$FRONTEND_PORT" wait else print_status "Starting both backend and frontend servers..." start_backend & BACKEND_PID=$! start_frontend & FRONTEND_PID=$! print_success "Development servers started successfully!" echo "" print_status "Backend URL: http://localhost:$BACKEND_PORT" print_status "API URL: http://localhost:$BACKEND_PORT/api/" print_status "Frontend URL: http://localhost:$FRONTEND_PORT" echo "" print_status "Press Ctrl+C to stop all servers" # Wait for both processes wait fi