#!/bin/bash # compile.sh - Compile installer sources into a single distributable script # This script is run during the build process to create the final installer set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" OUTPUT_FILE="${1:-install-usm.sh}" VERSION="${2:-0.1.0}" USM_SOURCE_DIR="${3:-$SCRIPT_DIR/../src}" # Temporary directory for building WORK_DIR=$(mktemp -d) trap "rm -rf $WORK_DIR" EXIT echo "Compiling USM installer..." echo " Version: $VERSION" echo " Output: $OUTPUT_FILE" echo " USM Source: $USM_SOURCE_DIR" # Step 1: Clone external repositories echo "Cloning external repositories..." SOURCES_DIR="$WORK_DIR/sources" mkdir -p "$SOURCES_DIR" # Clone Invercargill if [[ ! -d "$SOURCES_DIR/Invercargill" ]]; then echo " Cloning Invercargill..." git clone --depth 1 https://fabrica.unitatem.net/Tilo15/Invercargill.git "$SOURCES_DIR/Invercargill" 2>/dev/null || { echo "Warning: Could not clone Invercargill, will try without --depth 1" git clone https://fabrica.unitatem.net/Tilo15/Invercargill.git "$SOURCES_DIR/Invercargill" 2>/dev/null || { echo "Error: Could not clone Invercargill repository" exit 1 } } fi # Clone Invercargill-Json if [[ ! -d "$SOURCES_DIR/Invercargill-Json" ]]; then echo " Cloning Invercargill-Json..." git clone --depth 1 https://git.sr.ht/~tilo15/Invercargill-Json "$SOURCES_DIR/Invercargill-Json" 2>/dev/null || { echo "Warning: Could not clone Invercargill-Json, will try without --depth 1" git clone https://git.sr.ht/~tilo15/Invercargill-Json "$SOURCES_DIR/Invercargill-Json" 2>/dev/null || { echo "Error: Could not clone Invercargill-Json repository" exit 1 } } fi # Copy USM source (USM's meson.build is in src/, not project root) echo "Copying USM source..." mkdir -p "$SOURCES_DIR/usm" # USM_SOURCE_DIR points to the src/ directory which contains meson.build # Copy the entire src directory contents to usm/ cp -r "$USM_SOURCE_DIR"/* "$SOURCES_DIR/usm/" 2>/dev/null || true # Copy additional root level files for reference cp "$USM_SOURCE_DIR/../MANIFEST.usm" "$SOURCES_DIR/usm/" 2>/dev/null || true cp "$USM_SOURCE_DIR/../usm.config" "$SOURCES_DIR/usm/" 2>/dev/null || true # Step 2: Create the combined script header echo "Building combined script..." HEADER_FILE="$WORK_DIR/header.sh" cat > "$HEADER_FILE" << SCRIPT_HEADER #!/bin/bash # USM Installer - self-contained installation script # This script was automatically generated. Do not edit. # Version: $VERSION # Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC") set -e SCRIPT_HEADER # Step 3: Auto-detect package manager implementations PM_IMPLEMENTATIONS=() for pm_file in "$SCRIPT_DIR"/pm_*.sh; do if [[ -f "$pm_file" ]]; then # Extract PM name from filename (pm_apt.sh -> apt) pm_name=$(basename "$pm_file" .sh | sed 's/^pm_//') # Skip pm_base.sh - it's the interface, not an implementation if [[ "$pm_name" != "base" ]]; then PM_IMPLEMENTATIONS+=("$pm_name") fi fi done echo " Detected package managers: ${PM_IMPLEMENTATIONS[*]}" # Step 4: Combine all shell scripts COMBINED_FILE="$WORK_DIR/combined.sh" # Build the PM implementations array initialization PM_ARRAY_FILE="$WORK_DIR/pm_array.sh" cat > "$PM_ARRAY_FILE" << PM_ARRAY # Auto-detected package manager implementations PM_IMPLEMENTATIONS=(${PM_IMPLEMENTATIONS[*]}) PM_ARRAY # Function to process a script file process_script() { local file="$1" local section="$2" echo "# === $section ===" cat "$file" } # Combine scripts in order { process_script "$SCRIPT_DIR/utils.sh" "Utils" echo "" process_script "$SCRIPT_DIR/ui.sh" "UI" echo "" # Include PM implementations first for pm_name in "${PM_IMPLEMENTATIONS[@]}"; do process_script "$SCRIPT_DIR/pm_${pm_name}.sh" "Package Manager ${pm_name}" echo "" done # Include PM array initialization cat "$PM_ARRAY_FILE" echo "" # Include pm_base which uses the array process_script "$SCRIPT_DIR/pm_base.sh" "Package Manager Base" echo "" process_script "$SCRIPT_DIR/build_config.sh" "Build Config" echo "" process_script "$SCRIPT_DIR/main.sh" "Main" echo "" # Add the main call at the very end echo "# Run main function" echo 'main "$@"' } > "$COMBINED_FILE" # Replace version placeholder in combined file sed -i "s/@VERSION@/$VERSION/g" "$COMBINED_FILE" # Step 5: Create the payload echo "Creating compressed payload..." PAYLOAD_FILE="$WORK_DIR/payload.tar.xz" # Use highest compression for smaller file size tar -C "$SOURCES_DIR" -cf - . | xz -9 -T0 > "$PAYLOAD_FILE" # Step 6: Assemble final installer echo "Assembling final installer..." { cat "$HEADER_FILE" cat "$COMBINED_FILE" echo "" echo "__PAYLOAD_START__" cat "$PAYLOAD_FILE" } > "$OUTPUT_FILE" # Make executable chmod +x "$OUTPUT_FILE" # Calculate output size OUTPUT_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1) echo "" echo "✓ Installer created successfully!" echo " Output: $OUTPUT_FILE" echo " Size: $OUTPUT_SIZE"