compile.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/bin/bash
  2. # compile.sh - Compile installer sources into a single distributable script
  3. # This script is run during the build process to create the final installer
  4. set -e
  5. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  6. OUTPUT_FILE="${1:-install-usm.sh}"
  7. VERSION="${2:-0.1.0}"
  8. USM_SOURCE_DIR="${3:-$SCRIPT_DIR/../src}"
  9. # Temporary directory for building
  10. WORK_DIR=$(mktemp -d)
  11. trap "rm -rf $WORK_DIR" EXIT
  12. echo "Compiling USM installer..."
  13. echo " Version: $VERSION"
  14. echo " Output: $OUTPUT_FILE"
  15. echo " USM Source: $USM_SOURCE_DIR"
  16. # Step 1: Clone external repositories
  17. echo "Cloning external repositories..."
  18. SOURCES_DIR="$WORK_DIR/sources"
  19. mkdir -p "$SOURCES_DIR"
  20. # Clone Invercargill
  21. if [[ ! -d "$SOURCES_DIR/Invercargill" ]]; then
  22. echo " Cloning Invercargill..."
  23. git clone --depth 1 https://fabrica.unitatem.net/Tilo15/Invercargill.git "$SOURCES_DIR/Invercargill" 2>/dev/null || {
  24. echo "Warning: Could not clone Invercargill, will try without --depth 1"
  25. git clone https://fabrica.unitatem.net/Tilo15/Invercargill.git "$SOURCES_DIR/Invercargill" 2>/dev/null || {
  26. echo "Error: Could not clone Invercargill repository"
  27. exit 1
  28. }
  29. }
  30. fi
  31. # Clone Invercargill-Json
  32. if [[ ! -d "$SOURCES_DIR/Invercargill-Json" ]]; then
  33. echo " Cloning Invercargill-Json..."
  34. git clone --depth 1 https://git.sr.ht/~tilo15/Invercargill-Json "$SOURCES_DIR/Invercargill-Json" 2>/dev/null || {
  35. echo "Warning: Could not clone Invercargill-Json, will try without --depth 1"
  36. git clone https://git.sr.ht/~tilo15/Invercargill-Json "$SOURCES_DIR/Invercargill-Json" 2>/dev/null || {
  37. echo "Error: Could not clone Invercargill-Json repository"
  38. exit 1
  39. }
  40. }
  41. fi
  42. # Copy USM source (USM's meson.build is in src/, not project root)
  43. echo "Copying USM source..."
  44. mkdir -p "$SOURCES_DIR/usm"
  45. # USM_SOURCE_DIR points to the src/ directory which contains meson.build
  46. # Copy the entire src directory contents to usm/
  47. cp -r "$USM_SOURCE_DIR"/* "$SOURCES_DIR/usm/" 2>/dev/null || true
  48. # Copy additional root level files for reference
  49. cp "$USM_SOURCE_DIR/../MANIFEST.usm" "$SOURCES_DIR/usm/" 2>/dev/null || true
  50. cp "$USM_SOURCE_DIR/../usm.config" "$SOURCES_DIR/usm/" 2>/dev/null || true
  51. # Step 2: Create the combined script header
  52. echo "Building combined script..."
  53. HEADER_FILE="$WORK_DIR/header.sh"
  54. cat > "$HEADER_FILE" << SCRIPT_HEADER
  55. #!/bin/bash
  56. # USM Installer - self-contained installation script
  57. # This script was automatically generated. Do not edit.
  58. # Version: $VERSION
  59. # Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
  60. set -e
  61. SCRIPT_HEADER
  62. # Step 3: Auto-detect package manager implementations
  63. PM_IMPLEMENTATIONS=()
  64. for pm_file in "$SCRIPT_DIR"/pm_*.sh; do
  65. if [[ -f "$pm_file" ]]; then
  66. # Extract PM name from filename (pm_apt.sh -> apt)
  67. pm_name=$(basename "$pm_file" .sh | sed 's/^pm_//')
  68. # Skip pm_base.sh - it's the interface, not an implementation
  69. if [[ "$pm_name" != "base" ]]; then
  70. PM_IMPLEMENTATIONS+=("$pm_name")
  71. fi
  72. fi
  73. done
  74. echo " Detected package managers: ${PM_IMPLEMENTATIONS[*]}"
  75. # Step 4: Combine all shell scripts
  76. COMBINED_FILE="$WORK_DIR/combined.sh"
  77. # Build the PM implementations array initialization
  78. PM_ARRAY_FILE="$WORK_DIR/pm_array.sh"
  79. cat > "$PM_ARRAY_FILE" << PM_ARRAY
  80. # Auto-detected package manager implementations
  81. PM_IMPLEMENTATIONS=(${PM_IMPLEMENTATIONS[*]})
  82. PM_ARRAY
  83. # Function to process a script file
  84. process_script() {
  85. local file="$1"
  86. local section="$2"
  87. echo "# === $section ==="
  88. cat "$file"
  89. }
  90. # Combine scripts in order
  91. {
  92. process_script "$SCRIPT_DIR/utils.sh" "Utils"
  93. echo ""
  94. process_script "$SCRIPT_DIR/ui.sh" "UI"
  95. echo ""
  96. # Include PM implementations first
  97. for pm_name in "${PM_IMPLEMENTATIONS[@]}"; do
  98. process_script "$SCRIPT_DIR/pm_${pm_name}.sh" "Package Manager ${pm_name}"
  99. echo ""
  100. done
  101. # Include PM array initialization
  102. cat "$PM_ARRAY_FILE"
  103. echo ""
  104. # Include pm_base which uses the array
  105. process_script "$SCRIPT_DIR/pm_base.sh" "Package Manager Base"
  106. echo ""
  107. process_script "$SCRIPT_DIR/build_config.sh" "Build Config"
  108. echo ""
  109. process_script "$SCRIPT_DIR/main.sh" "Main"
  110. echo ""
  111. # Add the main call at the very end
  112. echo "# Run main function"
  113. echo 'main "$@"'
  114. echo ""
  115. echo "# Exit before payload"
  116. echo "exit 0"
  117. } > "$COMBINED_FILE"
  118. # Replace version placeholder in combined file
  119. sed -i "s/@VERSION@/$VERSION/g" "$COMBINED_FILE"
  120. # Step 5: Create the payload
  121. echo "Creating compressed payload..."
  122. PAYLOAD_FILE="$WORK_DIR/payload.tar.xz"
  123. # Use highest compression for smaller file size
  124. tar -C "$SOURCES_DIR" -cf - . | xz -9 -T0 > "$PAYLOAD_FILE"
  125. # Step 6: Assemble final installer
  126. echo "Assembling final installer..."
  127. {
  128. cat "$HEADER_FILE"
  129. cat "$COMBINED_FILE"
  130. echo ""
  131. echo "__PAYLOAD_START__"
  132. cat "$PAYLOAD_FILE"
  133. } > "$OUTPUT_FILE"
  134. # Make executable
  135. chmod +x "$OUTPUT_FILE"
  136. # Calculate output size
  137. OUTPUT_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
  138. echo ""
  139. echo "✓ Installer created successfully!"
  140. echo " Output: $OUTPUT_FILE"
  141. echo " Size: $OUTPUT_SIZE"