#!/bin/bash # build-electron.sh # Author: Matthew Raymer # Description: Clean, modular Electron build script for TimeSafari application # This script handles Electron builds with proper separation of concerns and # no command chaining, following DRY principles. # # Usage: # ./scripts/build-electron.sh # Development build (runs app) # ./scripts/build-electron.sh --dev # Development build (runs app) # ./scripts/build-electron.sh --test # Test environment build # ./scripts/build-electron.sh --prod # Production environment build # ./scripts/build-electron.sh --windows # Windows build # ./scripts/build-electron.sh --mac # macOS build # ./scripts/build-electron.sh --linux # Linux build # ./scripts/build-electron.sh --appimage # Linux AppImage # ./scripts/build-electron.sh --deb # Debian package # ./scripts/build-electron.sh --dmg # macOS DMG # ./scripts/build-electron.sh --help # Show help # ./scripts/build-electron.sh --verbose # Enable verbose logging # # Examples: # ./scripts/build-electron.sh --prod --windows # Windows production build # ./scripts/build-electron.sh --test --appimage # Linux AppImage test build # ./scripts/build-electron.sh --dev --mac # macOS development build # # Exit Codes: # 1 - Invalid arguments # 2 - Electron cleanup failed # 3 - Web build failed # 4 - Capacitor sync failed # 5 - TypeScript compilation failed # 6 - Electron packaging failed # 7 - Asset generation failed # 8 - Electron app launch failed # Exit on any error set -e # Source common utilities source "$(dirname "$0")/common.sh" # Default values BUILD_MODE="development" BUILD_PLATFORM="" BUILD_PACKAGE="" BUILD_ACTION="dev" VERBOSE=false # Parse command line arguments parse_electron_args() { while [[ $# -gt 0 ]]; do case $1 in --dev|--development) BUILD_MODE="development" BUILD_ACTION="dev" shift ;; --test) BUILD_MODE="test" BUILD_ACTION="package" shift ;; --prod|--production) BUILD_MODE="production" BUILD_ACTION="package" shift ;; --windows) BUILD_PLATFORM="windows" shift ;; --mac) BUILD_PLATFORM="mac" shift ;; --linux) BUILD_PLATFORM="linux" shift ;; --appimage) BUILD_PACKAGE="appimage" BUILD_PLATFORM="linux" shift ;; --deb) BUILD_PACKAGE="deb" BUILD_PLATFORM="linux" shift ;; --dmg) BUILD_PACKAGE="dmg" BUILD_PLATFORM="mac" shift ;; --help) show_electron_help exit 0 ;; --clean) BUILD_ACTION="clean" shift ;; --verbose) VERBOSE=true shift ;; *) log_error "Unknown argument: $1" show_electron_help exit 1 ;; esac done } # Show help information show_electron_help() { cat << EOF TimeSafari Electron Build Script Usage: $0 [OPTIONS] Build Modes: --dev, --development Development build (runs app) --test Test environment build --prod, --production Production environment build --clean Clean Electron build artifacts only Platforms: --windows Windows build --mac macOS build --linux Linux build Packages: --appimage Linux AppImage --deb Debian package --dmg macOS DMG Options: --verbose Enable verbose logging --help Show this help message Platform Validation: The script validates that the target platform matches the current execution platform. Cross-platform builds are not supported and will fail with an error message. Examples: $0 --prod --windows # Windows production build $0 --test --appimage # Linux AppImage test build $0 --dev --mac # macOS development build $0 --prod # Production build for all platforms $0 --clean # Clean Electron build artifacts only EOF } # Build web assets for Electron build_web_assets() { local mode=$1 log_info "Building web assets for Electron (mode: $mode)" safe_execute "Building web assets" "VITE_GIT_HASH=\$(git log -1 --pretty=format:%h) vite build --mode $mode --config vite.config.electron.mts" } # Sync with Capacitor sync_capacitor() { log_info "Syncing with Capacitor" safe_execute "Capacitor sync" "npx cap sync electron || true" } # Copy web assets to Electron copy_web_assets() { log_info "Copying web assets to Electron" safe_execute "Copying assets" "cp -r dist/* electron/app/" safe_execute "Copying config" "cp capacitor.config.json electron/capacitor.config.json" } # Compile TypeScript compile_typescript() { log_info "Compiling TypeScript" safe_execute "TypeScript compilation" "cd electron && npm run build && cd .." } # Generate assets generate_assets() { log_info "Generating assets" safe_execute "Asset generation" "npx capacitor-assets generate --electron || true" } # Clean Electron build artifacts clean_electron_artifacts() { log_info "Cleaning Electron build artifacts" # Clean Electron build directory if [[ -d "electron/build" ]]; then safe_execute "Cleaning Electron build directory" "rm -rf electron/build" fi # Clean Electron dist directory (packaged apps) if [[ -d "electron/dist" ]]; then safe_execute "Cleaning Electron dist directory" "rm -rf electron/dist" fi # Clean Electron app directory (web assets) if [[ -d "electron/app" ]]; then safe_execute "Cleaning Electron app directory" "rm -rf electron/app" fi # Clean TypeScript compilation artifacts if [[ -d "electron/src" ]]; then safe_execute "Cleaning TypeScript artifacts" "find electron/src -name '*.js' -delete 2>/dev/null || true" safe_execute "Cleaning TypeScript artifacts" "find electron/src -name '*.js.map' -delete 2>/dev/null || true" fi log_info "✅ Electron build artifacts cleaned" } # Detect current platform detect_current_platform() { case "$(uname -s)" in Linux*) echo "linux" ;; Darwin*) echo "mac" ;; CYGWIN*|MINGW32*|MSYS*|MINGW*) echo "windows" ;; *) log_error "Unknown platform: $(uname -s)" exit 1 ;; esac } # Validate platform compatibility validate_platform_compatibility() { local target_platform=$1 local current_platform=$2 if [[ -n "$target_platform" && "$target_platform" != "$current_platform" ]]; then log_error "❌ Platform mismatch detected!" log_error " Target platform: $target_platform" log_error " Current platform: $current_platform" log_error "" log_error "Cross-platform builds are not supported." log_error "Please run this build on the target platform: $target_platform" log_error "" log_error "Examples:" log_error " - For Windows builds: Run on Windows or WSL" log_error " - For macOS builds: Run on macOS" log_error " - For Linux builds: Run on Linux" log_error "" exit 1 fi } # Build Electron package build_electron_package() { local platform=$1 local package=$2 log_info "Building Electron package (platform: $platform, package: $package)" cd electron if [[ -n "$package" ]]; then case "$package" in "appimage") safe_execute "Building AppImage" "npm run build:appimage" ;; "deb") safe_execute "Building DEB package" "npm run build:deb" ;; "dmg") safe_execute "Building DMG package" "npm run build:dmg" ;; *) log_error "Unknown package type: $package" exit 1 ;; esac else case "$platform" in "windows") safe_execute "Building Windows package" "npm run build:windows" ;; "mac") safe_execute "Building macOS package" "npm run build:mac" ;; "linux") safe_execute "Building Linux package" "npm run build:linux" ;; *) log_error "Unknown platform: $platform" exit 1 ;; esac fi cd .. } # Start Electron development start_electron_dev() { log_info "Starting Electron development" safe_execute "Starting Electron" "cd electron && npm run electron:start && cd .." } # Main build function main_electron_build() { # Parse arguments parse_electron_args "$@" # Print build header print_header "TimeSafari Electron Build Process" local current_platform=$(detect_current_platform) log_info "Build mode: $BUILD_MODE" log_info "Build platform: ${BUILD_PLATFORM:-all}" log_info "Build package: ${BUILD_PACKAGE:-none}" log_info "Build action: $BUILD_ACTION" log_info "Current platform: $current_platform" # Early platform validation (before any build work) if [[ "$BUILD_ACTION" == "package" && -n "$BUILD_PLATFORM" ]]; then log_info "Validating platform compatibility..." validate_platform_compatibility "$BUILD_PLATFORM" "$current_platform" log_info "✅ Platform validation passed" fi # Setup environment setup_build_env "electron" setup_app_directories load_env_file ".env" # Step 1: Clean Electron build artifacts clean_electron_artifacts # Step 2: Clean dist directory log_info "Cleaning dist directory..." clean_build_artifacts "dist" "electron/app" # Step 3: Build web assets build_web_assets "$BUILD_MODE" # Step 4: Prepare Electron app directory log_info "Preparing Electron app directory..." mkdir -p electron/app # Step 5: Copy web assets copy_web_assets # Step 6: Compile TypeScript compile_typescript # Step 7: Sync with Capacitor sync_capacitor # Step 8: Generate assets generate_assets # Step 9: Execute build action case $BUILD_ACTION in "clean") clean_electron_artifacts log_success "Electron build artifacts cleaned successfully!" print_footer "Electron Clean" exit 0 ;; "dev") start_electron_dev ;; "package") if [[ -n "$BUILD_PLATFORM" ]]; then build_electron_package "$BUILD_PLATFORM" "$BUILD_PACKAGE" else log_info "No specific platform requested, building for all platforms" build_electron_package "windows" "$BUILD_PACKAGE" build_electron_package "mac" "$BUILD_PACKAGE" build_electron_package "linux" "$BUILD_PACKAGE" fi ;; *) log_error "Unknown build action: $BUILD_ACTION" exit 1 ;; esac # Print build summary case $BUILD_ACTION in "package") log_success "Electron package build completed successfully!" if [[ -d "electron/dist" ]]; then log_info "Package files available in: electron/dist/" ls -la electron/dist/ || true fi ;; "dev") log_success "Electron development build completed successfully!" log_info "Electron app should now be running" ;; esac print_footer "Electron Build" } # Run main function with all arguments main_electron_build "$@" # Exit with success exit 0