#!/bin/bash # Project Launch Script # Automates setup and concurrent execution of backend and frontend servers. set -e # Default configuration BACKEND_PORT=${BACKEND_PORT:-8000} FRONTEND_PORT=${FRONTEND_PORT:-5173} SKIP_INSTALL=false # Help message show_help() { echo "Usage: ./run.sh [options]" echo "" echo "Options:" echo " --help Show this help message" echo " --skip-install Skip dependency checks and installation" echo "" echo "Environment Variables:" echo " BACKEND_PORT Port for the backend server (default: 8000)" echo " FRONTEND_PORT Port for the frontend server (default: 5173)" } # Parse arguments while [[ "$#" -gt 0 ]]; do case $1 in --help) show_help; exit 0 ;; --skip-install) SKIP_INSTALL=true ;; *) echo "Unknown parameter passed: $1"; show_help; exit 1 ;; esac shift done echo "Starting Project Launch Script..." # Environment validation validate_env() { echo "Validating environment..." if ! command -v python3 &> /dev/null; then echo "Error: python3 is not installed." exit 1 fi if ! python3 -c 'import sys; exit(0) if sys.version_info >= (3, 9) else exit(1)'; then PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') echo "Error: python3 version 3.9 or higher is required. Found $PYTHON_VERSION" exit 1 fi if ! command -v npm &> /dev/null; then echo "Error: npm is not installed." exit 1 fi PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))') echo "Environment validation passed (Python $PYTHON_VERSION, npm $(npm -v))" } validate_env # Backend dependency management setup_backend() { if [ "$SKIP_INSTALL" = true ]; then echo "Skipping backend installation..." return fi echo "Setting up backend..." cd backend if [ ! -d ".venv" ]; then echo "Creating virtual environment..." python3 -m venv .venv fi source .venv/bin/activate if [ -f "requirements.txt" ]; then echo "Installing backend dependencies..." pip install -r requirements.txt else echo "Warning: backend/requirements.txt not found." fi cd .. } # Frontend dependency management setup_frontend() { if [ "$SKIP_INSTALL" = true ]; then echo "Skipping frontend installation..." return fi echo "Setting up frontend..." cd frontend if [ ! -d "node_modules" ]; then echo "Installing frontend dependencies..." npm install else echo "frontend/node_modules already exists. Skipping npm install." fi cd .. } setup_backend setup_frontend # Cleanup function for graceful shutdown cleanup() { echo "" echo "Stopping services..." if [ -n "$BACKEND_PID" ]; then kill $BACKEND_PID 2>/dev/null || true fi if [ -n "$FRONTEND_PID" ]; then kill $FRONTEND_PID 2>/dev/null || true fi echo "Services stopped." exit 0 } # Trap SIGINT (Ctrl+C) trap cleanup SIGINT # Start Backend start_backend() { echo -e "\033[0;34m[Backend]\033[0m Starting on port $BACKEND_PORT..." cd backend if [ -f ".venv/bin/activate" ]; then source .venv/bin/activate else echo -e "\033[0;31m[Backend]\033[0m Warning: .venv/bin/activate not found. Attempting to run without venv." fi # Use a subshell to prefix output python3 -m uvicorn src.app:app --reload --port "$BACKEND_PORT" 2>&1 | sed "s/^/$(echo -e '\033[0;34m[Backend]\033[0m ') /" & BACKEND_PID=$! cd .. } # Start Frontend start_frontend() { echo -e "\033[0;32m[Frontend]\033[0m Starting on port $FRONTEND_PORT..." cd frontend # Use a subshell to prefix output npm run dev -- --port "$FRONTEND_PORT" 2>&1 | sed "s/^/$(echo -e '\033[0;32m[Frontend]\033[0m ') /" & FRONTEND_PID=$! cd .. } start_backend start_frontend echo "Services are running. Press Ctrl+C to stop." wait