#!/bin/bash # ============================================================================ # Environment Check Script for Task Reporter # Validates all prerequisites required to run the development environment # ============================================================================ # Note: Not using set -e because we handle errors explicitly with ERRORS counter # 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 (scripts are in project root) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$SCRIPT_DIR" # Track overall status ERRORS=0 WARNINGS=0 # Helper functions print_header() { echo -e "\n${BLUE}=== $1 ===${NC}" } print_ok() { echo -e "${GREEN}[OK]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" ((ERRORS++)) } print_warn() { echo -e "${YELLOW}[WARN]${NC} $1" ((WARNINGS++)) } print_info() { echo -e "${BLUE}[INFO]${NC} $1" } # Show help show_help() { echo "Usage: $0 [OPTIONS]" echo "" echo "Validates the development environment for Task Reporter." echo "" echo "Options:" echo " -h, --help Show this help message" echo " -q, --quiet Only show errors and warnings" echo "" echo "Checks performed:" echo " - Python version (3.10+)" echo " - Node.js and npm" echo " - Docker availability" echo " - Virtual environment (venv/)" echo " - Environment file (.env)" echo " - Port availability (8000, 3000, 9000, 9001)" } # Parse arguments QUIET=false while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -q|--quiet) QUIET=true shift ;; *) echo "Unknown option: $1" show_help exit 1 ;; esac done echo -e "${BLUE}============================================${NC}" echo -e "${BLUE} Task Reporter - Environment Check${NC}" echo -e "${BLUE}============================================${NC}" # ============================================================================ # Check Python version # ============================================================================ print_header "Python" if command -v python3 &> /dev/null; then PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1) PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2) if [[ "$PYTHON_MAJOR" -ge 3 ]] && [[ "$PYTHON_MINOR" -ge 10 ]]; then print_ok "Python $PYTHON_VERSION detected" else print_error "Python 3.10+ required, found $PYTHON_VERSION" fi else print_error "Python3 not found. Please install Python 3.10+" fi # ============================================================================ # Check Node.js and npm # ============================================================================ print_header "Node.js" if command -v node &> /dev/null; then NODE_VERSION=$(node --version) print_ok "Node.js $NODE_VERSION detected" else print_error "Node.js not found. Please install Node.js 18+" fi if command -v npm &> /dev/null; then NPM_VERSION=$(npm --version) print_ok "npm $NPM_VERSION detected" else print_error "npm not found. Please install npm" fi # ============================================================================ # Check Docker # ============================================================================ print_header "Docker" if command -v docker &> /dev/null; then DOCKER_VERSION=$(docker --version | cut -d' ' -f3 | tr -d ',') print_ok "Docker $DOCKER_VERSION detected" # Check if Docker daemon is running if docker info &> /dev/null; then print_ok "Docker daemon is running" else print_error "Docker daemon is not running. Please start Docker" fi else print_error "Docker not found. Please install Docker" fi if command -v docker-compose &> /dev/null; then COMPOSE_VERSION=$(docker-compose --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) print_ok "docker-compose $COMPOSE_VERSION detected" elif docker compose version &> /dev/null; then COMPOSE_VERSION=$(docker compose version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) print_ok "docker compose (plugin) $COMPOSE_VERSION detected" else print_error "docker-compose not found. Please install docker-compose" fi # ============================================================================ # Check Virtual Environment # ============================================================================ print_header "Virtual Environment" if [[ -d "$PROJECT_ROOT/venv" ]]; then print_ok "Virtual environment found at venv/" # Check if it has required packages if [[ -f "$PROJECT_ROOT/venv/bin/activate" ]]; then print_ok "venv/bin/activate exists" else print_warn "venv/bin/activate not found - venv may be corrupted" fi else print_error "Virtual environment not found" print_info "Create it with: python3 -m venv venv" print_info "Then activate: source venv/bin/activate" print_info "And install: pip install -r requirements.txt" fi # ============================================================================ # Check Environment File # ============================================================================ print_header "Environment File" if [[ -f "$PROJECT_ROOT/.env" ]]; then print_ok ".env file exists" # Check for critical variables (use || true to prevent set -e from exiting) if grep -q "^FERNET_KEY=.\+" "$PROJECT_ROOT/.env" 2>/dev/null; then print_ok "FERNET_KEY is set" else print_warn "FERNET_KEY appears to be empty" print_info "Generate with: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\"" fi if grep -q "^DATABASE_URL=" "$PROJECT_ROOT/.env" 2>/dev/null; then print_ok "DATABASE_URL is set" else print_warn "DATABASE_URL is not set" fi if grep -q "^MINIO_ENDPOINT=" "$PROJECT_ROOT/.env" 2>/dev/null; then print_ok "MINIO_ENDPOINT is set" else print_info "MINIO_ENDPOINT not in .env (will use defaults)" fi else print_error ".env file not found" print_info "Copy from template: cp .env.example .env" print_info "Then edit .env and set required values" fi # ============================================================================ # Check Port Availability # ============================================================================ print_header "Port Availability" check_port() { local port=$1 local service=$2 if command -v ss &> /dev/null; then if ss -tuln | grep -q ":$port "; then PROCESS=$(ss -tulnp 2>/dev/null | grep ":$port " | awk '{print $NF}' | head -1) print_warn "Port $port ($service) is in use: $PROCESS" else print_ok "Port $port ($service) is available" fi elif command -v netstat &> /dev/null; then if netstat -tuln | grep -q ":$port "; then print_warn "Port $port ($service) is in use" else print_ok "Port $port ($service) is available" fi else print_info "Cannot check port $port - ss/netstat not available" fi } check_port 8000 "Backend API" check_port 3000 "Frontend Dev" check_port 9000 "MinIO S3" check_port 9001 "MinIO Console" # ============================================================================ # Summary # ============================================================================ print_header "Summary" if [[ $ERRORS -eq 0 ]] && [[ $WARNINGS -eq 0 ]]; then echo -e "${GREEN}All checks passed! Environment is ready.${NC}" exit 0 elif [[ $ERRORS -eq 0 ]]; then echo -e "${YELLOW}$WARNINGS warning(s) found. Environment may work but review warnings above.${NC}" exit 0 else echo -e "${RED}$ERRORS error(s) and $WARNINGS warning(s) found.${NC}" echo -e "${RED}Please fix the errors above before starting development.${NC}" exit 1 fi