#!/usr/bin/env bash # # Build Architecture Guard Script # # Author: Matthew Raymer # Date: 2025-08-22 # Purpose: Protects build-critical files by requiring BUILDING.md updates # Enhanced to protect Android build system including asset validation, # API routing, and resource generation logic # # Usage: # ./scripts/build-arch-guard.sh --staged # Check staged files (pre-commit) # ./scripts/build-arch-guard.sh --range # Check range (pre-push) # ./scripts/build-arch-guard.sh # Check working directory # set -euo pipefail # Sensitive paths that require BUILDING.md updates when modified SENSITIVE=( "vite.config.*" "scripts/**" "electron/**" "android/**" "ios/**" "sw_scripts/**" "sw_combine.js" "Dockerfile" "docker/**" "capacitor.config.ts" "capacitor-assets.config.json" # Critical for Android assets "package.json" "package-lock.json" "yarn.lock" "pnpm-lock.yaml" "resources/**" # Source assets for Android ) # Documentation files that must be updated alongside sensitive changes DOCS_REQUIRED=( "BUILDING.md" "doc/README-BUILD-GUARD.md" # Guard documentation ) # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log_info() { echo -e "${BLUE}[guard]${NC} $1" } log_warn() { echo -e "${YELLOW}[guard]${NC} $1" } log_error() { echo -e "${RED}[guard]${NC} $1" } log_success() { echo -e "${GREEN}[guard]${NC} $1" } # Collect files based on mode collect_files() { if [[ "${1:-}" == "--staged" ]]; then # Pre-commit: check staged files git diff --name-only --cached elif [[ "${1:-}" == "--range" ]]; then # Pre-push: check commits being pushed RANGE="${2:-HEAD~1..HEAD}" git diff --name-only "$RANGE" else # Default: check working directory changes git diff --name-only HEAD fi } # Check if a file matches any sensitive pattern matches_sensitive() { local f="$1" for pat in "${SENSITIVE[@]}"; do # Convert glob pattern to regex local rx="^${pat//\./\.}$" rx="${rx//\*\*/.*}" rx="${rx//\*/[^/]*}" if [[ "$f" =~ $rx ]]; then return 0 fi done return 1 } # Check if documentation was updated check_docs_updated() { local changed_files=("$@") for changed_file in "${changed_files[@]}"; do for required_doc in "${DOCS_REQUIRED[@]}"; do if [[ "$changed_file" == "$required_doc" ]]; then return 0 fi done done return 1 } # Check if Android build system was modified check_android_build_changes() { local changed_files=("$@") for file in "${changed_files[@]}"; do if [[ "$file" =~ ^android/ ]] || [[ "$file" =~ ^scripts/build-android\.sh$ ]]; then return 0 fi done return 1 } # Check if asset configuration was modified check_asset_config_changes() { local changed_files=("$@") for file in "${changed_files[@]}"; do if [[ "$file" =~ ^capacitor-assets\.config\.json$ ]] || [[ "$file" =~ ^resources/ ]]; then return 0 fi done return 1 } # Enhanced validation for Android changes validate_android_changes() { local changed_files=("$@") if check_android_build_changes "${changed_files[@]}"; then log_warn "Android build system changes detected!" echo echo "Android build system changes require enhanced validation:" echo " - Test asset generation: npm run build:android --assets" echo " - Test API routing modes: --dev and --dev --api-ip " echo " - Verify resource fallback mechanisms" echo " - Test across development/test/production modes" echo echo "Please ensure BUILDING.md includes Android-specific testing procedures." echo fi if check_asset_config_changes "${changed_files[@]}"; then log_warn "Asset configuration changes detected!" echo echo "Asset configuration changes require validation:" echo " - Test asset generation across all platforms" echo " - Verify resource files are properly created" echo " - Test asset validation scripts" echo fi } # Feedback collection for continuous improvement collect_feedback_data() { local mode="$1" local sensitive_touched=("${@:2}") local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # Create feedback log entry local feedback_log=".guard-feedback.log" echo "[$timestamp] Guard execution: $mode" >> "$feedback_log" echo " Sensitive files: ${sensitive_touched[*]}" >> "$feedback_log" # Log Android-specific changes for analysis if check_android_build_changes "${sensitive_touched[@]}"; then echo " Android changes detected" >> "$feedback_log" fi # Log asset configuration changes for analysis if check_asset_config_changes "${sensitive_touched[@]}"; then echo " Asset config changes detected" >> "$feedback_log" fi echo "" >> "$feedback_log" } # Enhanced error handling with Android-specific guidance handle_documentation_error() { local sensitive_touched=("$@") log_error "Build-sensitive files changed but BUILDING.md was not updated!" echo echo "The following build-sensitive files were modified:" for file in "${sensitive_touched[@]}"; do echo " - $file" done echo echo "When modifying build-critical files, you must also update BUILDING.md" echo "to document any changes to the build process." echo # Add Android-specific guidance if check_android_build_changes "${sensitive_touched[@]}"; then echo "⚠️ ANDROID BUILD SYSTEM CHANGES DETECTED ⚠️" echo "Android changes require enhanced documentation including:" echo " - Asset validation procedures" echo " - API routing configuration" echo " - Resource generation testing" echo " - Platform-specific build modes" echo fi if check_asset_config_changes "${sensitive_touched[@]}"; then echo "🎨 ASSET CONFIGURATION CHANGES DETECTED 🎨" echo "Asset changes require documentation including:" echo " - Asset generation procedures" echo " - Resource validation steps" echo " - Platform-specific asset requirements" echo fi echo "Please:" echo " 1. Update BUILDING.md with relevant changes" echo " 2. Stage the BUILDING.md changes: git add BUILDING.md" echo " 3. Retry your commit/push" echo echo "💡 Feedback: If this guard is too strict or missing patterns," echo " please report to the development team for continuous improvement." echo echo "📊 Feedback Categories:" echo " - False positives (files flagged that shouldn't be)" echo " - False negatives (sensitive files not caught)" echo " - Missing patterns (new file types to protect)" echo " - Overly strict (patterns too restrictive)" echo " - Documentation gaps (missing guidance)" echo " - Testing improvements (better procedures)" echo echo "📝 Report feedback to: Development team with specific examples" echo } # Main guard logic main() { local mode="${1:-}" local arg="${2:-}" log_info "Running Build Architecture Guard..." # Collect changed files changed_files=() while IFS= read -r line; do [[ -n "$line" ]] && changed_files+=("$line") done < <(collect_files "$mode" "$arg") if [[ ${#changed_files[@]} -eq 0 ]]; then log_info "No files changed, guard check passed" exit 0 fi log_info "Checking ${#changed_files[@]} changed files..." # Find sensitive files that were touched sensitive_touched=() for file in "${changed_files[@]}"; do if matches_sensitive "$file"; then sensitive_touched+=("$file") fi done # If no sensitive files were touched, allow the change if [[ ${#sensitive_touched[@]} -eq 0 ]]; then log_success "No build-sensitive files changed, guard check passed" exit 0 fi # Sensitive files were touched, log them log_warn "Build-sensitive paths changed:" for file in "${sensitive_touched[@]}"; do echo " - $file" done # Enhanced validation for Android changes validate_android_changes "${changed_files[@]}" # Collect feedback data for continuous improvement collect_feedback_data "$mode" "${sensitive_touched[@]}" # Check if required documentation was updated if check_docs_updated "${changed_files[@]}"; then log_success "BUILDING.md updated alongside build changes, guard check passed" exit 0 else # Enhanced error handling with Android-specific guidance handle_documentation_error "${sensitive_touched[@]}" exit 2 fi } # Handle help flag if [[ "${1:-}" =~ ^(-h|--help)$ ]]; then echo "Build Architecture Guard Script" echo echo "Usage:" echo " $0 [--staged|--range [RANGE]]" echo echo "Options:" echo " --staged Check staged files (for pre-commit hook)" echo " --range [RANGE] Check git range (for pre-push hook)" echo " Default range: HEAD~1..HEAD" echo " (no args) Check working directory changes" echo " --feedback Show feedback analysis (for maintainers)" echo echo "Examples:" echo " $0 --staged # Pre-commit check" echo " $0 --range origin/main..HEAD # Pre-push check" echo " $0 # Working directory check" echo " $0 --feedback # Analyze guard effectiveness" exit 0 fi # Handle feedback analysis if [[ "${1:-}" == "--feedback" ]]; then if [[ -f ".guard-feedback.log" ]]; then echo "Build Architecture Guard Feedback Analysis" echo "==========================================" echo echo "Recent guard executions:" echo tail -20 ".guard-feedback.log" | while IFS= read -r line; do if [[ "$line" =~ ^\[ ]]; then echo "📅 $line" elif [[ "$line" =~ ^\s*Sensitive\ files: ]]; then echo "🔍 $line" elif [[ "$line" =~ ^\s*Android\ changes ]]; then echo "🤖 $line" elif [[ "$line" =~ ^\s*Asset\ config ]]; then echo "🎨 $line" elif [[ "$line" =~ ^\s*$ ]]; then echo "" else echo " $line" fi done echo echo "💡 Use this data to improve guard patterns and documentation" echo "📊 Total executions: $(grep -c "Guard execution" .guard-feedback.log 2>/dev/null || echo "0")" else echo "No feedback data available yet. Run the guard to collect data." fi exit 0 fi main "$@"