#!/bin/bash # ============================================ # Focolari Voting System - Script di Sviluppo # ============================================ # # Utilizzo: # ./dev.sh install - Installa dipendenze frontend e backend # ./dev.sh dev - Avvia frontend (dev) + backend (api-only) # ./dev.sh build - Builda il frontend # ./dev.sh build:debug - Builda il frontend in modalità DEBUG (no minify) # ./dev.sh server - Builda frontend (se necessario) e avvia server completo # ./dev.sh server:debug - Builda DEBUG + avvia server (per debug Chrome) # ./dev.sh backend - Avvia solo il backend (api-only) # ./dev.sh frontend - Avvia solo il frontend in dev mode # ./dev.sh shell - Apre shell pipenv del backend # ./dev.sh clean - Pulisce build e cache # ./dev.sh help - Mostra questo messaggio # set -e # Directory del progetto SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BACKEND_DIR="$SCRIPT_DIR/backend-mock" FRONTEND_DIR="$SCRIPT_DIR/frontend" FRONTEND_DIST="$FRONTEND_DIR/dist" # Colori per output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Funzioni di utilità info() { echo -e "${BLUE}ℹ️ $1${NC}" } success() { echo -e "${GREEN}✅ $1${NC}" } warn() { echo -e "${YELLOW}⚠️ $1${NC}" } error() { echo -e "${RED}❌ $1${NC}" exit 1 } # Verifica prerequisiti check_prereqs() { command -v node >/dev/null 2>&1 || error "Node.js non trovato. Installalo prima." command -v npm >/dev/null 2>&1 || error "npm non trovato. Installalo prima." command -v python3 >/dev/null 2>&1 || error "Python3 non trovato. Installalo prima." command -v pipenv >/dev/null 2>&1 || error "pipenv non trovato. Installa con: pip install pipenv" } # Installa dipendenze cmd_install() { info "Installazione dipendenze..." check_prereqs # Backend info "Installazione dipendenze backend (pipenv)..." cd "$BACKEND_DIR" pipenv install success "Backend installato" # Frontend info "Installazione dipendenze frontend (npm)..." cd "$FRONTEND_DIR" npm install success "Frontend installato" success "Tutte le dipendenze installate!" } # Build frontend cmd_build() { info "Build frontend..." cd "$FRONTEND_DIR" npm run build success "Frontend buildato in $FRONTEND_DIST" } # Build frontend in modalità debug (senza minificazione) cmd_build_debug() { info "Build frontend in modalità DEBUG (no minification)..." cd "$FRONTEND_DIR" npm run build -- --minify false --sourcemap success "Frontend DEBUG buildato in $FRONTEND_DIST" warn "Nota: questa build NON è ottimizzata per produzione" } # Verifica se serve rebuild needs_rebuild() { # Se dist non esiste, serve build if [ ! -d "$FRONTEND_DIST" ]; then return 0 fi # Se dist/index.html non esiste, serve build if [ ! -f "$FRONTEND_DIST/index.html" ]; then return 0 fi # Controlla se ci sono file frontend più recenti della build local latest_src=$(find "$FRONTEND_DIR/src" -type f -newer "$FRONTEND_DIST/index.html" 2>/dev/null | head -1) if [ -n "$latest_src" ]; then return 0 fi # Controlla anche index.html e config if [ "$FRONTEND_DIR/index.html" -nt "$FRONTEND_DIST/index.html" ]; then return 0 fi if [ "$FRONTEND_DIR/vite.config.ts" -nt "$FRONTEND_DIST/index.html" ]; then return 0 fi return 1 } # Server completo (build + backend) cmd_server() { check_prereqs # Rebuild se necessario if needs_rebuild; then warn "Rilevati cambiamenti nel frontend, rebuild in corso..." cmd_build else info "Frontend già aggiornato, skip build" fi # Avvia backend con frontend info "Avvio server completo..." cd "$BACKEND_DIR" pipenv run python main.py "$@" } # Server completo in modalità DEBUG (build senza minificazione) cmd_server_debug() { check_prereqs # Rebuild sempre in modalità debug warn "Build DEBUG forzata (no minification, con sourcemap)..." cmd_build_debug # Avvia backend con frontend info "Avvio server completo in modalità DEBUG..." cd "$BACKEND_DIR" pipenv run python main.py "$@" } # Solo backend cmd_backend() { check_prereqs info "Avvio backend (API only)..." cd "$BACKEND_DIR" pipenv run python main.py --api-only "$@" } # Solo frontend dev cmd_frontend() { check_prereqs info "Avvio frontend in dev mode..." cd "$FRONTEND_DIR" npm run dev } # Dev mode: backend api-only + frontend dev (in parallelo) cmd_dev() { check_prereqs info "Avvio ambiente di sviluppo..." info "Backend API: http://localhost:8000" info "Frontend Dev: http://localhost:5173" echo "" # Avvia backend in background cd "$BACKEND_DIR" pipenv run python main.py --api-only & BACKEND_PID=$! # Trap per cleanup trap "kill $BACKEND_PID 2>/dev/null" EXIT # Avvia frontend cd "$FRONTEND_DIR" npm run dev } # Shell pipenv cmd_shell() { info "Apertura shell pipenv backend..." cd "$BACKEND_DIR" pipenv shell } # Pulizia cmd_clean() { info "Pulizia build e cache..." # Frontend rm -rf "$FRONTEND_DIR/node_modules/.vite" rm -rf "$FRONTEND_DIST" # Backend find "$BACKEND_DIR" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true find "$BACKEND_DIR" -type f -name "*.pyc" -delete 2>/dev/null || true success "Pulizia completata" } # Test frontend cmd_test() { check_prereqs info "Esecuzione test frontend..." cd "$FRONTEND_DIR" npm run test:run } # Test in watch mode cmd_test_watch() { check_prereqs info "Avvio test frontend in watch mode..." cd "$FRONTEND_DIR" npm run test } # Test in watch mode CON server backend attivo cmd_test_dev() { check_prereqs # Rebuild frontend se necessario if needs_rebuild; then warn "Rilevati cambiamenti nel frontend, rebuild in corso..." cmd_build fi info "Avvio ambiente di test con server..." info "Server: http://localhost:8000" info "Test: watch mode attivo" echo "" # Avvia backend in background cd "$BACKEND_DIR" pipenv run python main.py "$@" & BACKEND_PID=$! # Aspetta che il server sia pronto sleep 2 # Trap per cleanup trap "kill $BACKEND_PID 2>/dev/null; echo ''; echo 'Server terminato.'" EXIT # Avvia test in watch mode cd "$FRONTEND_DIR" npm run test } # Test E2E con Playwright (headless - avvia server automaticamente) cmd_test_e2e() { check_prereqs # Rebuild frontend se necessario if needs_rebuild; then warn "Rilevati cambiamenti nel frontend, rebuild in corso..." cmd_build fi info "Avvio test E2E (headless)..." info "Il server viene avviato automaticamente da Playwright" echo "" cd "$FRONTEND_DIR" npm run test:e2e "$@" } # Test E2E con browser visibile (headed) - avvia server manualmente cmd_test_e2e_headed() { check_prereqs if needs_rebuild; then warn "Rilevati cambiamenti nel frontend, rebuild in corso..." cmd_build fi info "Avvio test E2E con browser visibile..." info "Server: http://localhost:8000 (users_test.json)" echo "" # Avvia backend in background con dati di test cd "$BACKEND_DIR" pipenv run python main.py -d data/users_test.json & BACKEND_PID=$! # Aspetta che il server sia pronto sleep 3 # Trap per cleanup trap "kill $BACKEND_PID 2>/dev/null; echo ''; success 'Server terminato.'" EXIT # Avvia test headed cd "$FRONTEND_DIR" npm run test:e2e:headed -- "$@" } # Test E2E con UI interattiva (devi avviare i test manualmente dall'UI) cmd_test_e2e_ui() { check_prereqs if needs_rebuild; then warn "Rilevati cambiamenti nel frontend, rebuild in corso..." cmd_build fi info "Avvio Playwright UI (IDE interattivo)..." info "Server: http://localhost:8000 (users_test.json)" info "" info "Nell'UI di Playwright:" info " 1. Clicca su un test per eseguirlo" info " 2. Usa i controlli per step-by-step debugging" info " 3. Vedi screenshot e trace in tempo reale" echo "" # Avvia backend in background con dati di test cd "$BACKEND_DIR" pipenv run python main.py -d data/users_test.json & BACKEND_PID=$! # Aspetta che il server sia pronto sleep 3 # Trap per cleanup trap "kill $BACKEND_PID 2>/dev/null; echo ''; success 'Server terminato.'" EXIT # Avvia Playwright UI cd "$FRONTEND_DIR" npm run test:e2e:ui } # Help cmd_help() { echo "============================================" echo "Focolari Voting System - Script di Sviluppo" echo "============================================" echo "" echo "Utilizzo: ./dev.sh [opzioni]" echo "" echo "Comandi disponibili:" echo " install Installa dipendenze frontend e backend" echo " dev Avvia frontend (dev) + backend (api-only) in parallelo" echo " build Builda il frontend per produzione" echo " build:debug Builda il frontend in modalità DEBUG (no minify, sourcemap)" echo " server Builda frontend (se cambiato) e avvia server completo" echo " server:debug Builda DEBUG + avvia server (per debug con Chrome DevTools)" echo " backend Avvia solo il backend (api-only)" echo " frontend Avvia solo il frontend in dev mode" echo " test Esegue i test frontend (unit)" echo " test:watch Esegue i test frontend in watch mode" echo " test:dev Avvia server + test in watch mode" echo " test:e2e Test E2E headless (server auto)" echo " test:e2e:headed Test E2E con browser visibile" echo " test:e2e:ui Playwright UI per debug interattivo" echo " shell Apre shell pipenv del backend" echo " clean Pulisce build e cache" echo " help Mostra questo messaggio" echo "" echo "Esempi:" echo " ./dev.sh install # Setup iniziale" echo " ./dev.sh dev # Sviluppo (hot reload)" echo " ./dev.sh server # Produzione locale (accessibile da rete)" echo " ./dev.sh server:debug # Build DEBUG + server (per debug Chrome)" echo " ./dev.sh server -p 9000 # Server su porta 9000" echo " ./dev.sh server --host 127.0.0.1 # Solo localhost (non accessibile da rete)" echo " ./dev.sh server -d data/users_test.json # Con dataset test" echo " ./dev.sh build:debug # Solo build DEBUG (senza avviare server)" echo "" echo "Note:" echo " - Il server usa --host 0.0.0.0 di default (accessibile da tutta la rete locale)" echo " - Per accedere da altri dispositivi: usa l'IP della macchina (es. 192.168.1.230:8000)" echo " - Verifica che il firewall non blocchi la porta" echo "" } # Main case "${1:-help}" in install) cmd_install ;; build) cmd_build ;; "build:debug") cmd_build_debug ;; server) shift cmd_server "$@" ;; "server:debug") shift cmd_server_debug "$@" ;; backend) shift cmd_backend "$@" ;; frontend) cmd_frontend ;; dev) cmd_dev ;; shell) cmd_shell ;; clean) cmd_clean ;; test) cmd_test ;; "test:watch") cmd_test_watch ;; "test:dev") shift cmd_test_dev "$@" ;; "test:e2e") shift cmd_test_e2e "$@" ;; "test:e2e:headed") shift cmd_test_e2e_headed "$@" ;; "test:e2e:ui") cmd_test_e2e_ui ;; help|--help|-h) cmd_help ;; *) error "Comando sconosciuto: $1. Usa './dev.sh help' per la lista comandi." ;; esac # Go back to original path cd "$SCRIPT_DIR"