#!/bin/bash # common.sh # Author: Matthew Raymer # Description: Common utilities and functions for TimeSafari build scripts # This script provides shared logging, timing, and utility functions # that can be sourced by other build scripts to eliminate redundancy. # # Usage: source ./scripts/common.sh # # Provides: # - Color constants # - Logging functions (log_info, log_success, log_warn, log_error) # - Timing function (measure_time) # - Common utility functions # - Environment variable management # ANSI color codes for better output formatting readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly PURPLE='\033[0;35m' readonly CYAN='\033[0;36m' readonly NC='\033[0m' # No Color # Logging functions log_info() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] [INFO]${NC} $1" } log_success() { echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS]${NC} $1" } log_warn() { echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] [WARN]${NC} $1" } log_error() { echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR]${NC} $1" } log_debug() { echo -e "${PURPLE}[$(date '+%Y-%m-%d %H:%M:%S')] [DEBUG]${NC} $1" } log_step() { echo -e "${CYAN}[$(date '+%Y-%m-%d %H:%M:%S')] [STEP]${NC} $1" } # Function to measure and log execution time measure_time() { local start_time=$(date +%s) "$@" local end_time=$(date +%s) local duration=$((end_time - start_time)) log_success "Completed in ${duration} seconds" } # Function to print section headers print_header() { local title="$1" echo -e "\n${BLUE}=== $title ===${NC}\n" } print_footer() { local title="$1" echo -e "\n${GREEN}=== $title Complete ===${NC}\n" } # Function to check if a command exists check_command() { if ! command -v "$1" &> /dev/null; then log_error "$1 is required but not installed." return 1 fi log_debug "Found $1: $(command -v "$1")" return 0 } # Function to check if a directory exists check_directory() { if [ ! -d "$1" ]; then log_error "Directory not found: $1" return 1 fi log_debug "Directory exists: $1" return 0 } # Function to check if a file exists check_file() { if [ ! -f "$1" ]; then log_error "File not found: $1" return 1 fi log_debug "File exists: $1" return 0 } # Function to safely execute a command with error handling safe_execute() { local step_name="$1" local command="$2" log_step "$step_name" if ! measure_time eval "$command"; then log_error "$step_name failed!" return 1 fi return 0 } # Function to check virtual environment for Python scripts check_venv() { if [ ! -d ".venv" ]; then log_error "Virtual environment not found. Please create it first:" log_error "python -m venv .venv" log_error "source .venv/bin/activate" log_error "pip install -r requirements.txt" return 1 fi log_debug "Virtual environment found: .venv" return 0 } # Function to get git hash for versioning get_git_hash() { if command -v git &> /dev/null; then git log -1 --pretty=format:%h 2>/dev/null || echo "unknown" else echo "unknown" fi } # Function to clean build artifacts clean_build_artifacts() { local artifacts=("$@") for artifact in "${artifacts[@]}"; do if [ -e "$artifact" ]; then log_info "Cleaning $artifact" rm -rf "$artifact" fi done } # Function to validate environment variables validate_env_vars() { local required_vars=("$@") local missing_vars=() for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then missing_vars+=("$var") fi done if [ ${#missing_vars[@]} -gt 0 ]; then log_error "Missing required environment variables: ${missing_vars[*]}" return 1 fi return 0 } # Function to set environment variables for different build types setup_build_env() { local build_type="$1" local production="${2:-false}" log_info "Setting up environment for $build_type build" # Get git hash for versioning local git_hash=$(get_git_hash) export VITE_GIT_HASH="$git_hash" log_debug "Set VITE_GIT_HASH=$git_hash" case $build_type in "capacitor") export VITE_PLATFORM=capacitor export VITE_PWA_ENABLED=false export VITE_DISABLE_PWA=true export DEBUG_MIGRATIONS=0 ;; "electron") export VITE_PLATFORM=electron export VITE_PWA_ENABLED=false export VITE_DISABLE_PWA=true export DEBUG_MIGRATIONS=0 ;; "web") export VITE_PLATFORM=web export VITE_PWA_ENABLED=true export VITE_DISABLE_PWA=false export DEBUG_MIGRATIONS=0 ;; *) log_warn "Unknown build type: $build_type, using default environment" export VITE_PLATFORM=web export VITE_PWA_ENABLED=true export VITE_DISABLE_PWA=false export DEBUG_MIGRATIONS=0 ;; esac # Log environment setup log_debug "Environment variables set:" log_debug " VITE_PLATFORM=$VITE_PLATFORM" log_debug " VITE_PWA_ENABLED=$VITE_PWA_ENABLED" log_debug " VITE_DISABLE_PWA=$VITE_DISABLE_PWA" log_debug " DEBUG_MIGRATIONS=$DEBUG_MIGRATIONS" if [ -n "$NODE_ENV" ]; then log_debug " NODE_ENV=$NODE_ENV" fi } # Function to create application directories setup_app_directories() { log_info "Setting up application directories..." # Create TimeSafari data directory mkdir -p ~/.local/share/TimeSafari/timesafari # Create build directories if they don't exist mkdir -p dist log_debug "Application directories created" } # Function to load environment from .env file if it exists load_env_file() { local env_file="$1" if [ -f "$env_file" ]; then log_info "Loading environment from $env_file" # Export variables from .env file (simple key=value format) while IFS='=' read -r key value; do # Skip comments and empty lines [[ $key =~ ^#.*$ ]] && continue [[ -z $key ]] && continue # Remove quotes from value if present value=$(echo "$value" | sed 's/^["'\'']//;s/["'\'']$//') export "$key=$value" log_debug "Loaded: $key=$value" done < "$env_file" else log_debug "No $env_file file found" fi } # Function to print current environment variables print_env_vars() { local prefix="$1" if [ -n "$prefix" ]; then log_info "Environment variables with prefix '$prefix':" env | grep "^$prefix" | sort | while read -r line; do log_debug " $line" done else log_info "Current environment variables:" env | sort | while read -r line; do log_debug " $line" done fi } # Function to print script usage print_usage() { local script_name="$1" local usage_text="$2" echo "Usage: $script_name $usage_text" echo "" echo "Options:" echo " -h, --help Show this help message" echo " -v, --verbose Enable verbose logging" echo " -e, --env Show environment variables" echo "" } # Function to parse command line arguments parse_args() { local args=("$@") local verbose=false local show_env=false for arg in "${args[@]}"; do case $arg in -h|--help) print_usage "$0" "[options]" exit 0 ;; -v|--verbose) verbose=true ;; -e|--env) show_env=true ;; *) # Handle other arguments in child scripts ;; esac done if [ "$verbose" = true ]; then # Enable debug logging set -x fi if [ "$show_env" = true ]; then print_env_vars "VITE_" exit 0 fi } # Export functions for use in child scripts export -f log_info log_success log_warn log_error log_debug log_step export -f measure_time print_header print_footer export -f check_command check_directory check_file export -f safe_execute check_venv get_git_hash export -f clean_build_artifacts validate_env_vars export -f setup_build_env setup_app_directories load_env_file print_env_vars export -f print_usage parse_args