diff --git a/gradle/linux/pack_offline_bundle_airgap.sh b/gradle/linux/pack_offline_bundle_airgap.sh new file mode 100644 index 00000000..9cc9fc5f --- /dev/null +++ b/gradle/linux/pack_offline_bundle_airgap.sh @@ -0,0 +1,550 @@ +#!/bin/bash +# pack_offline_bundle_airgap.sh +# ============================================================================ +# Gradle Offline Bundle Packer +# ============================================================================ +# Version: 4.0 +# +# WORKFLOW: +# 1. [ONLINE] Build project (./gradlew bootJar) - downloads all deps +# 2. [ONLINE] Test run (./gradlew bootRun) - verify app works +# 3. [OFFLINE TEST] Verify offline build works +# 4. Create bundle with all cached dependencies +# +# REQUIREMENTS: +# - Internet connection (for initial build) +# - Project with gradlew +# ============================================================================ + +set -e + +# ============================================================================ +# Configuration +# ============================================================================ +WRAPPER_SEED_PATH="wrapper_jar_seed" +OFFLINE_HOME_NAME="_offline_gradle_home" +BOOTRUN_TIMEOUT_SECONDS=60 + +# Color codes +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +GRAY='\033[0;90m' +WHITE='\033[1;37m' +NC='\033[0m' # No Color + +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} Gradle Offline Bundle Packer v4.0${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" +echo -e "${WHITE} This script will:${NC}" +echo -e "${GRAY} 1. Build project with internet (download dependencies)${NC}" +echo -e "${GRAY} 2. Test run application (verify it works)${NC}" +echo -e "${GRAY} 3. Test offline build (verify cache is complete)${NC}" +echo -e "${GRAY} 4. Create offline bundle for air-gapped environment${NC}" +echo "" +echo -e "${CYAN}============================================================${NC}" +echo "" + +# ============================================================================ +# [1/20] Check Current Directory +# ============================================================================ +echo -e "${YELLOW}==[1/20] Check Current Directory ==${NC}" +ROOT="$(pwd)" +echo "ROOT_DIR: $ROOT" +echo "" + +# ============================================================================ +# [2/20] Check Required Files +# ============================================================================ +echo -e "${YELLOW}==[2/20] Check Required Files ==${NC}" + +if [ ! -f "./gradlew" ]; then + echo -e "${RED}ERROR: gradlew not found. Run from project root.${NC}" + exit 1 +fi +chmod +x ./gradlew +echo -e "${GREEN}[OK] gradlew${NC}" + +BUILD_FILE="" +if [ -f "./build.gradle" ]; then + BUILD_FILE="build.gradle" +elif [ -f "./build.gradle.kts" ]; then + BUILD_FILE="build.gradle.kts" +else + echo -e "${RED}ERROR: build.gradle(.kts) not found.${NC}" + exit 1 +fi +echo -e "${GREEN}[OK] $BUILD_FILE${NC}" + +SETTINGS_FILE="" +if [ -f "./settings.gradle" ]; then + SETTINGS_FILE="settings.gradle" + echo -e "${GREEN}[OK] $SETTINGS_FILE${NC}" +elif [ -f "./settings.gradle.kts" ]; then + SETTINGS_FILE="settings.gradle.kts" + echo -e "${GREEN}[OK] $SETTINGS_FILE${NC}" +fi +echo "" + +# ============================================================================ +# [3/20] Check Gradle Wrapper +# ============================================================================ +echo -e "${YELLOW}==[3/20] Check Gradle Wrapper ==${NC}" + +WRAPPER_DIR="$ROOT/gradle/wrapper" +WRAPPER_JAR="$WRAPPER_DIR/gradle-wrapper.jar" +WRAPPER_PROP="$WRAPPER_DIR/gradle-wrapper.properties" + +mkdir -p "$WRAPPER_DIR" + +if [ ! -f "$WRAPPER_PROP" ]; then + echo -e "${RED}ERROR: gradle-wrapper.properties not found.${NC}" + exit 1 +fi + +if [ ! -f "$WRAPPER_JAR" ]; then + SEED_JAR="$ROOT/$WRAPPER_SEED_PATH/gradle-wrapper.jar" + if [ -f "$SEED_JAR" ]; then + cp "$SEED_JAR" "$WRAPPER_JAR" + echo -e "${GREEN}[OK] Wrapper jar injected from seed${NC}" + else + echo -e "${RED}ERROR: gradle-wrapper.jar missing${NC}" + exit 1 + fi +else + echo -e "${GREEN}[OK] gradle-wrapper.jar exists${NC}" +fi + +# Create seed backup +SEED_DIR="$ROOT/$WRAPPER_SEED_PATH" +if [ ! -d "$SEED_DIR" ]; then + mkdir -p "$SEED_DIR" + cp "$WRAPPER_JAR" "$SEED_DIR/gradle-wrapper.jar" +fi +echo "" + +# ============================================================================ +# [4/20] Set GRADLE_USER_HOME (Project Local) +# ============================================================================ +echo -e "${YELLOW}==[4/20] Set GRADLE_USER_HOME ==${NC}" + +OFFLINE_HOME="$ROOT/$OFFLINE_HOME_NAME" +mkdir -p "$OFFLINE_HOME" +export GRADLE_USER_HOME="$OFFLINE_HOME" + +echo -e "${CYAN}GRADLE_USER_HOME = $GRADLE_USER_HOME${NC}" +echo -e "${GRAY}[INFO] All dependencies will be cached in project folder${NC}" +echo "" + +# ============================================================================ +# [5/20] Check Internet Connection +# ============================================================================ +echo -e "${YELLOW}==[5/20] Check Internet Connection ==${NC}" + +HAS_INTERNET=false +TEST_HOSTS=("plugins.gradle.org" "repo.maven.apache.org" "repo1.maven.org") + +for TEST_HOST in "${TEST_HOSTS[@]}"; do + if ping -c 1 -W 3 "$TEST_HOST" &>/dev/null; then + HAS_INTERNET=true + echo -e "${GREEN}[OK] Connected to $TEST_HOST${NC}" + break + fi +done + +if [ "$HAS_INTERNET" = false ]; then + # Try DNS resolution as fallback + if nslookup google.com &>/dev/null || host google.com &>/dev/null; then + HAS_INTERNET=true + echo -e "${GREEN}[OK] Internet available (DNS)${NC}" + fi +fi + +if [ "$HAS_INTERNET" = false ]; then + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED} ERROR: No Internet Connection!${NC}" + echo -e "${RED}============================================================${NC}" + echo "" + echo -e "${YELLOW}This script requires internet for initial build.${NC}" + echo -e "${YELLOW}Please connect to internet and run again.${NC}" + echo "" + exit 1 +fi +echo "" + +# ============================================================================ +# [6/20] Initial Gradle Setup +# ============================================================================ +echo -e "${YELLOW}==[6/20] Initial Gradle Setup ==${NC}" +echo -e "${GRAY}[INFO] Downloading Gradle distribution...${NC}" + +if ./gradlew --version &>/dev/null; then + GRADLE_VERSION=$(./gradlew --version 2>&1 | grep "^Gradle" | awk '{print $2}') + echo -e "${GREEN}[OK] Gradle $GRADLE_VERSION${NC}" +else + echo -e "${RED}[ERROR] Gradle setup failed${NC}" + exit 1 +fi +echo "" + +# ============================================================================ +# [7/20] ONLINE BUILD - bootJar (Download All Dependencies) +# ============================================================================ +echo -e "${YELLOW}==[7/20] ONLINE BUILD - bootJar ==${NC}" +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} ONLINE BUILD (with Internet)${NC}" +echo -e "${CYAN} Downloading all dependencies to local cache${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" + +BUILD_SUCCESS=false + +./gradlew clean bootJar --no-daemon +if [ $? -eq 0 ]; then + BUILD_SUCCESS=true + echo "" + echo -e "${GREEN}============================================================${NC}" + echo -e "${GREEN} ONLINE BUILD SUCCESS!${NC}" + echo -e "${GREEN}============================================================${NC}" + echo "" + + if [ -d "./build/libs" ]; then + echo -e "${CYAN}JAR files:${NC}" + ls -lh ./build/libs/*.jar 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' + fi +else + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED} BUILD FAILED!${NC}" + echo -e "${RED}============================================================${NC}" + echo "" + echo -e "${YELLOW}Build failed. Cannot continue.${NC}" + exit 1 +fi +echo "" + +# ============================================================================ +# [8/20] Stop Daemons +# ============================================================================ +echo -e "${YELLOW}==[8/20] Stop Daemons ==${NC}" + +./gradlew --stop &>/dev/null || true +sleep 2 +echo -e "${GREEN}[OK] Daemons stopped${NC}" +echo "" + +# ============================================================================ +# [9/20] ONLINE TEST - bootRun (Verify Application Works) +# ============================================================================ +echo -e "${YELLOW}==[9/20] ONLINE TEST - bootRun ==${NC}" +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} Testing application startup (timeout: ${BOOTRUN_TIMEOUT_SECONDS}s)${NC}" +echo -e "${CYAN} Will automatically stop after successful startup${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" + +BOOTRUN_SUCCESS=false + +timeout ${BOOTRUN_TIMEOUT_SECONDS}s ./gradlew bootRun --no-daemon & +BOOTRUN_PID=$! + +sleep 10 + +if ps -p $BOOTRUN_PID &>/dev/null; then + BOOTRUN_SUCCESS=true + echo "" + echo -e "${GREEN}[OK] Application started successfully${NC}" + kill $BOOTRUN_PID &>/dev/null || true + sleep 2 +else + echo "" + echo -e "${YELLOW}[WARN] Application may not have started properly${NC}" +fi + +# Cleanup +pkill -f "gradle.*bootRun" &>/dev/null || true +sleep 2 +echo "" + +# ============================================================================ +# [10/20] Stop Daemons Again +# ============================================================================ +echo -e "${YELLOW}==[10/20] Stop Daemons Again ==${NC}" + +./gradlew --stop &>/dev/null || true +sleep 2 +echo -e "${GREEN}[OK] Daemons stopped${NC}" +echo "" + +# ============================================================================ +# [11/20] OFFLINE BUILD TEST (Verify Cache Completeness) +# ============================================================================ +echo -e "${YELLOW}==[11/20] OFFLINE BUILD TEST ==${NC}" +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} OFFLINE BUILD TEST (--offline flag)${NC}" +echo -e "${CYAN} Verifying all dependencies are cached${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" + +OFFLINE_SUCCESS=false + +./gradlew clean bootJar --offline --no-daemon +if [ $? -eq 0 ]; then + OFFLINE_SUCCESS=true + echo "" + echo -e "${GREEN}============================================================${NC}" + echo -e "${GREEN} OFFLINE BUILD TEST PASSED!${NC}" + echo -e "${GREEN}============================================================${NC}" + echo "" + echo -e "${GREEN}[OK] All dependencies are cached${NC}" +else + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED} OFFLINE BUILD TEST FAILED!${NC}" + echo -e "${RED}============================================================${NC}" + echo "" + echo -e "${YELLOW}Some dependencies may be missing from cache.${NC}" + echo -e "${YELLOW}The bundle may not work in air-gapped environment.${NC}" + echo "" + + read -p "Continue anyway? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +fi +echo "" + +# ============================================================================ +# [12/20] Stop Daemons Before Archive +# ============================================================================ +echo -e "${YELLOW}==[12/20] Stop Daemons Before Archive ==${NC}" + +./gradlew --stop &>/dev/null || true +sleep 2 +echo -e "${GREEN}[OK] Daemons stopped${NC}" +echo "" + +# ============================================================================ +# [13/20] Verify settings.gradle for Offline +# ============================================================================ +echo -e "${YELLOW}==[13/20] Verify settings.gradle ==${NC}" + +if [ -n "$SETTINGS_FILE" ]; then + if grep -q "mavenLocal()" "$SETTINGS_FILE" && grep -q "pluginManagement" "$SETTINGS_FILE"; then + echo -e "${GREEN}[OK] settings.gradle configured for offline${NC}" + else + echo -e "${YELLOW}[WARN] settings.gradle may need offline configuration${NC}" + echo -e "${GRAY}[INFO] Consider adding mavenLocal() to pluginManagement and repositories${NC}" + fi +else + echo -e "${GRAY}[INFO] No settings.gradle found${NC}" +fi +echo "" + +# ============================================================================ +# [14/20] Create Helper Scripts +# ============================================================================ +echo -e "${YELLOW}==[14/20] Create Helper Scripts ==${NC}" + +# run_offline_build.sh +cat > "$ROOT/run_offline_build.sh" << 'EOF' +#!/bin/bash +# run_offline_build.sh - Build JAR offline +export GRADLE_USER_HOME="$(pwd)/_offline_gradle_home" +echo "GRADLE_USER_HOME = $GRADLE_USER_HOME" +echo "" +./gradlew --offline bootJar --no-daemon +if [ $? -eq 0 ]; then + echo "" + echo "BUILD SUCCESS!" + echo "" + echo "JAR files:" + ls -lh ./build/libs/*.jar 2>/dev/null | awk '{print " " $9}' +else + echo "BUILD FAILED" +fi +EOF +chmod +x "$ROOT/run_offline_build.sh" +echo -e "${GREEN}[OK] run_offline_build.sh${NC}" + +# run_offline_bootrun.sh +cat > "$ROOT/run_offline_bootrun.sh" << 'EOF' +#!/bin/bash +# run_offline_bootrun.sh - Run application offline +export GRADLE_USER_HOME="$(pwd)/_offline_gradle_home" +echo "GRADLE_USER_HOME = $GRADLE_USER_HOME" +echo "" +echo "Starting application (Ctrl+C to stop)..." +echo "" +./gradlew --offline bootRun --no-daemon +EOF +chmod +x "$ROOT/run_offline_bootrun.sh" +echo -e "${GREEN}[OK] run_offline_bootrun.sh${NC}" +echo "" + +# ============================================================================ +# [15/20] Final Daemon Cleanup +# ============================================================================ +echo -e "${YELLOW}==[15/20] Final Daemon Cleanup ==${NC}" + +./gradlew --stop &>/dev/null || true +sleep 2 +echo -e "${GREEN}[OK] Daemons stopped${NC}" +echo "" + +# ============================================================================ +# [16/20] Clean Lock Files +# ============================================================================ +echo -e "${YELLOW}==[16/20] Clean Lock Files ==${NC}" + +DAEMON_DIR="$OFFLINE_HOME/daemon" +if [ -d "$DAEMON_DIR" ]; then + rm -rf "$DAEMON_DIR" 2>/dev/null || true +fi + +find "$OFFLINE_HOME" -type f \( -name "*.lock" -o -name "*.log" -o -name "*.tmp" \) -delete 2>/dev/null || true + +echo -e "${GREEN}[OK] Lock files cleaned${NC}" +echo "" + +# ============================================================================ +# [17/20] Calculate Cache Size +# ============================================================================ +echo -e "${YELLOW}==[17/20] Cache Summary ==${NC}" + +CACHES_DIR="$OFFLINE_HOME/caches" +WRAPPER_DISTS="$OFFLINE_HOME/wrapper/dists" + +TOTAL_SIZE=0 + +if [ -d "$CACHES_DIR" ]; then + SIZE=$(du -sb "$CACHES_DIR" 2>/dev/null | cut -f1) + TOTAL_SIZE=$((TOTAL_SIZE + SIZE)) + SIZE_MB=$(echo "scale=2; $SIZE / 1048576" | bc) + echo -e "${CYAN}[INFO] Dependencies: ${SIZE_MB} MB${NC}" +fi + +if [ -d "$WRAPPER_DISTS" ]; then + SIZE=$(du -sb "$WRAPPER_DISTS" 2>/dev/null | cut -f1) + TOTAL_SIZE=$((TOTAL_SIZE + SIZE)) + SIZE_MB=$(echo "scale=2; $SIZE / 1048576" | bc) + echo -e "${CYAN}[INFO] Gradle dist: ${SIZE_MB} MB${NC}" +fi + +TOTAL_MB=$(echo "scale=2; $TOTAL_SIZE / 1048576" | bc) +echo -e "${CYAN}[INFO] Total cache: ${TOTAL_MB} MB${NC}" +echo "" + +# ============================================================================ +# [18/20] Create Archive +# ============================================================================ +echo -e "${YELLOW}==[18/20] Create Archive ==${NC}" + +BASE_NAME=$(basename "$ROOT") +TIMESTAMP=$(date +"%Y%m%d_%H%M%S") +PARENT=$(dirname "$ROOT") +ARCHIVE_PATH="${PARENT}/${BASE_NAME}_offline_bundle_${TIMESTAMP}.tar.gz" + +echo "Archive: $ARCHIVE_PATH" +echo -e "${GRAY}[INFO] Creating archive (this may take several minutes)...${NC}" + +tar -czf "$ARCHIVE_PATH" \ + --exclude=".git" \ + --exclude=".idea" \ + --exclude=".DS_Store" \ + --exclude="*.log" \ + --exclude="*.lock" \ + --exclude="_offline_gradle_home/daemon" \ + --exclude="_offline_gradle_home/native" \ + --exclude="_offline_gradle_home/jdks" \ + --exclude="build" \ + --exclude="out" \ + --exclude=".gradle" \ + -C "$ROOT" . + +if [ $? -ne 0 ]; then + echo -e "${RED}ERROR: tar failed${NC}" + exit 1 +fi + +ARCHIVE_SIZE=$(stat -f%z "$ARCHIVE_PATH" 2>/dev/null || stat -c%s "$ARCHIVE_PATH" 2>/dev/null) +ARCHIVE_SIZE_MB=$(echo "scale=2; $ARCHIVE_SIZE / 1048576" | bc) +echo -e "${GREEN}[OK] Archive created: ${ARCHIVE_SIZE_MB} MB${NC}" +echo "" + +# ============================================================================ +# [19/20] Verify Archive +# ============================================================================ +echo -e "${YELLOW}==[19/20] Verify Archive ==${NC}" + +CHECKS=( + "gradle/wrapper/gradle-wrapper.jar" + "gradlew" + "_offline_gradle_home/caches" + "run_offline_build.sh" +) + +for CHECK in "${CHECKS[@]}"; do + if tar -tzf "$ARCHIVE_PATH" | grep -q "$CHECK"; then + echo -e " ${GREEN}[OK] $CHECK${NC}" + else + echo -e " ${YELLOW}[WARN] $CHECK${NC}" + fi +done +echo "" + +# ============================================================================ +# [20/20] Complete +# ============================================================================ +echo -e "${GREEN}============================================================${NC}" +echo -e "${GREEN} BUNDLE CREATION COMPLETE!${NC}" +echo -e "${GREEN}============================================================${NC}" +echo "" +echo -e "${CYAN}Archive: $ARCHIVE_PATH${NC}" +echo -e "${CYAN}Size: ${ARCHIVE_SIZE_MB} MB${NC}" +echo "" + +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} Test Results${NC}" +echo -e "${CYAN}============================================================${NC}" +if [ "$BUILD_SUCCESS" = true ]; then + echo -e " Online build (bootJar): ${GREEN}PASSED${NC}" +else + echo -e " Online build (bootJar): ${RED}FAILED${NC}" +fi +if [ "$BOOTRUN_SUCCESS" = true ]; then + echo -e " Online test (bootRun): ${GREEN}PASSED${NC}" +else + echo -e " Online test (bootRun): ${YELLOW}SKIPPED${NC}" +fi +if [ "$OFFLINE_SUCCESS" = true ]; then + echo -e " Offline build test: ${GREEN}PASSED${NC}" +else + echo -e " Offline build test: ${RED}FAILED${NC}" +fi +echo "" + +echo -e "${YELLOW}============================================================${NC}" +echo -e "${YELLOW} Usage in Air-gapped Environment${NC}" +echo -e "${YELLOW}============================================================${NC}" +echo "" +echo -e "${WHITE}Option 1: Use unpack script${NC}" +echo -e "${GRAY} ./unpack_and_offline_build_airgap.sh${NC}" +echo "" +echo -e "${WHITE}Option 2: Manual extraction${NC}" +echo -e "${GRAY} tar -xzf .tar.gz${NC}" +echo -e "${GRAY} cd ${NC}" +echo -e "${GRAY} ./run_offline_build.sh${NC}" +echo "" +echo -e "${WHITE}Option 3: Direct commands${NC}" +echo -e "${GRAY} export GRADLE_USER_HOME=\"./_offline_gradle_home\"${NC}" +echo -e "${GRAY} ./gradlew --offline bootJar --no-daemon${NC}" +echo "" diff --git a/gradle/linux/unpack_and_offline_build_airgap.sh b/gradle/linux/unpack_and_offline_build_airgap.sh new file mode 100644 index 00000000..b279202c --- /dev/null +++ b/gradle/linux/unpack_and_offline_build_airgap.sh @@ -0,0 +1,347 @@ +#!/bin/bash +# unpack_and_offline_build_airgap.sh +# ============================================================================ +# Execution Environment: OFFLINE (Air-gapped, No Internet) +# Purpose: Extract bundle and run offline build +# ============================================================================ +# Linux Bash Script +# Version: 3.1 +# +# IMPORTANT: This script automatically: +# 1. Extracts the archive +# 2. Sets GRADLE_USER_HOME to project local cache +# 3. Configures settings.gradle for offline resolution +# 4. Runs build with --offline flag +# ============================================================================ + +set -e + +# ============================================================================ +# Configuration +# ============================================================================ +WRAPPER_SEED_PATH="wrapper_jar_seed" +OFFLINE_HOME_NAME="_offline_gradle_home" + +# Color codes +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +CYAN='\033[0;36m' +GRAY='\033[0;90m' +WHITE='\033[1;37m' +NC='\033[0m' # No Color + +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} Gradle Offline Build Runner${NC}" +echo -e "${CYAN} Environment: AIR-GAPPED (No Internet)${NC}" +echo -e "${CYAN} Mode: Fully Offline (--offline enforced)${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" + +# ============================================================================ +# [1/16] Check Current Directory +# ============================================================================ +echo -e "${YELLOW}==[1/16] Check Current Directory ==${NC}" +START_DIR="$(pwd)" +echo "PWD: $START_DIR" +echo "" + +# ============================================================================ +# [2/16] Select Archive +# ============================================================================ +echo -e "${YELLOW}==[2/16] Select Archive ==${NC}" + +ARCHIVE="" +if [ $# -ge 1 ]; then + ARCHIVE="$1" +fi + +if [ -z "$ARCHIVE" ]; then + # Auto-detect most recent .tar.gz file + ARCHIVE=$(find "$START_DIR" -maxdepth 1 -type f \( -name "*.tar.gz" -o -name "*.tgz" \) -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-) + + if [ -z "$ARCHIVE" ]; then + echo -e "${RED}[ERROR] No archive found${NC}" + ls -lh "$START_DIR" + exit 1 + fi + + echo -e "${CYAN}[AUTO] $(basename "$ARCHIVE")${NC}" +else + if [ ! -f "$ARCHIVE" ]; then + ARCHIVE="$START_DIR/$ARCHIVE" + fi + echo -e "${CYAN}[USER] $(basename "$ARCHIVE")${NC}" +fi + +if [ ! -f "$ARCHIVE" ]; then + echo -e "${RED}ERROR: Archive not found: $ARCHIVE${NC}" + exit 1 +fi + +ARCHIVE_SIZE=$(stat -f%z "$ARCHIVE" 2>/dev/null || stat -c%s "$ARCHIVE" 2>/dev/null) +ARCHIVE_SIZE_MB=$(echo "scale=2; $ARCHIVE_SIZE / 1048576" | bc) +echo "Size: ${ARCHIVE_SIZE_MB} MB" +echo "" + +# ============================================================================ +# [3/16] Check tar +# ============================================================================ +echo -e "${YELLOW}==[3/16] Check tar ==${NC}" + +if ! command -v tar &>/dev/null; then + echo -e "${RED}ERROR: tar not found${NC}" + exit 1 +fi +echo -e "${GREEN}[OK] tar found${NC}" +echo "" + +# ============================================================================ +# [4/16] Extract Archive +# ============================================================================ +echo -e "${YELLOW}==[4/16] Extract Archive ==${NC}" +echo -e "${GRAY}[INFO] Extracting...${NC}" + +tar -xzf "$ARCHIVE" -C "$START_DIR" +if [ $? -ne 0 ]; then + echo -e "${RED}ERROR: Extraction failed${NC}" + exit 1 +fi +echo -e "${GREEN}[OK] Extracted${NC}" +echo "" + +# ============================================================================ +# [5/16] Set Permissions +# ============================================================================ +echo -e "${YELLOW}==[5/16] Set Permissions ==${NC}" + +chmod -R u+rw "$START_DIR" 2>/dev/null || true +echo -e "${GREEN}[OK] Permissions set${NC}" +echo "" + +# ============================================================================ +# [6/16] Find Project Root +# ============================================================================ +echo -e "${YELLOW}==[6/16] Find Project Root ==${NC}" + +GRADLEW=$(find "$START_DIR" -name "gradlew" -type f 2>/dev/null | sort | head -1) +if [ -z "$GRADLEW" ]; then + echo -e "${RED}ERROR: gradlew not found${NC}" + exit 1 +fi + +PROJECT_DIR=$(dirname "$GRADLEW") +echo -e "${CYAN}Project: $PROJECT_DIR${NC}" +cd "$PROJECT_DIR" +echo "" + +# ============================================================================ +# [7/16] Fix Permissions +# ============================================================================ +echo -e "${YELLOW}==[7/16] Fix Permissions ==${NC}" + +chmod +x ./gradlew +find . -name "*.sh" -type f -exec chmod +x {} \; 2>/dev/null || true +echo -e "${GREEN}[OK] Permissions fixed${NC}" +echo "" + +# ============================================================================ +# [8/16] Verify Wrapper +# ============================================================================ +echo -e "${YELLOW}==[8/16] Verify Wrapper ==${NC}" + +WRAPPER_DIR="$PROJECT_DIR/gradle/wrapper" +WRAPPER_JAR="$WRAPPER_DIR/gradle-wrapper.jar" +WRAPPER_PROP="$WRAPPER_DIR/gradle-wrapper.properties" + +if [ ! -f "$WRAPPER_PROP" ]; then + echo -e "${RED}ERROR: gradle-wrapper.properties missing${NC}" + exit 1 +fi + +if [ ! -f "$WRAPPER_JAR" ]; then + SEED_JAR="$PROJECT_DIR/$WRAPPER_SEED_PATH/gradle-wrapper.jar" + if [ -f "$SEED_JAR" ]; then + mkdir -p "$WRAPPER_DIR" + cp "$SEED_JAR" "$WRAPPER_JAR" + echo -e "${GREEN}[OK] Injected from seed${NC}" + else + echo -e "${RED}ERROR: wrapper jar missing${NC}" + exit 1 + fi +else + echo -e "${GREEN}[OK] Wrapper verified${NC}" +fi +echo "" + +# ============================================================================ +# [9/16] Set GRADLE_USER_HOME +# ============================================================================ +echo -e "${YELLOW}==[9/16] Set GRADLE_USER_HOME ==${NC}" + +OFFLINE_HOME="$PROJECT_DIR/$OFFLINE_HOME_NAME" +if [ ! -d "$OFFLINE_HOME" ]; then + echo -e "${RED}ERROR: _offline_gradle_home not found in archive${NC}" + exit 1 +fi + +export GRADLE_USER_HOME="$OFFLINE_HOME" +echo -e "${CYAN}GRADLE_USER_HOME = $GRADLE_USER_HOME${NC}" + +# Check cache +CACHES_DIR="$OFFLINE_HOME/caches" +if [ -d "$CACHES_DIR" ]; then + CACHE_SIZE=$(du -sb "$CACHES_DIR" 2>/dev/null | cut -f1) + CACHE_SIZE_MB=$(echo "scale=2; $CACHE_SIZE / 1048576" | bc) + echo -e "${CYAN}[INFO] Cache size: ${CACHE_SIZE_MB} MB${NC}" +else + echo -e "${YELLOW}[WARN] No cache folder found${NC}" +fi +echo "" + +# ============================================================================ +# [10/16] Verify settings.gradle +# ============================================================================ +echo -e "${YELLOW}==[10/16] Verify settings.gradle ==${NC}" + +SETTINGS_FILE="" +if [ -f "./settings.gradle" ]; then + SETTINGS_FILE="settings.gradle" +elif [ -f "./settings.gradle.kts" ]; then + SETTINGS_FILE="settings.gradle.kts" +fi + +if [ -n "$SETTINGS_FILE" ]; then + if grep -q "mavenLocal()" "$SETTINGS_FILE" && grep -q "pluginManagement" "$SETTINGS_FILE"; then + echo -e "${GREEN}[OK] settings.gradle configured for offline${NC}" + else + echo -e "${YELLOW}[WARN] settings.gradle may not be configured for offline${NC}" + echo -e "${GRAY}[INFO] Build may fail if plugins not cached${NC}" + fi +fi +echo "" + +# ============================================================================ +# [11/16] Test Gradle +# ============================================================================ +echo -e "${YELLOW}==[11/16] Test Gradle ==${NC}" + +GRADLE_WORKS=false +if ./gradlew --offline --version &>/dev/null; then + GRADLE_WORKS=true + echo -e "${GREEN}[OK] Gradle working in offline mode${NC}" +else + echo -e "${YELLOW}[WARN] Gradle --version failed${NC}" +fi +echo "" + +# ============================================================================ +# [12/16] Stop Daemon +# ============================================================================ +echo -e "${YELLOW}==[12/16] Stop Daemon ==${NC}" + +./gradlew --stop &>/dev/null || true +sleep 2 +echo -e "${GREEN}[OK] Daemon stopped${NC}" +echo "" + +# ============================================================================ +# [13/16] Run Offline Build +# ============================================================================ +echo -e "${YELLOW}==[13/16] Run Offline Build ==${NC}" +echo "" +echo -e "${CYAN}============================================================${NC}" +echo -e "${CYAN} Building with --offline flag${NC}" +echo -e "${CYAN} All dependencies from local cache${NC}" +echo -e "${CYAN}============================================================${NC}" +echo "" + +BUILD_SUCCESS=false +BUILD_TASK="" + +# Try bootJar +echo -e "${GRAY}[TRY] --offline bootJar...${NC}" +if ./gradlew --offline clean bootJar --no-daemon; then + BUILD_SUCCESS=true + BUILD_TASK="bootJar" +fi + +# Try jar +if [ "$BUILD_SUCCESS" = false ]; then + echo -e "${GRAY}[TRY] --offline jar...${NC}" + if ./gradlew --offline clean jar --no-daemon; then + BUILD_SUCCESS=true + BUILD_TASK="jar" + fi +fi + +# Try build +if [ "$BUILD_SUCCESS" = false ]; then + echo -e "${GRAY}[TRY] --offline build...${NC}" + if ./gradlew --offline build --no-daemon; then + BUILD_SUCCESS=true + BUILD_TASK="build" + fi +fi + +echo "" +if [ "$BUILD_SUCCESS" = true ]; then + echo -e "${GREEN}============================================================${NC}" + echo -e "${GREEN} BUILD SUCCESS! (task: $BUILD_TASK)${NC}" + echo -e "${GREEN}============================================================${NC}" +else + echo -e "${RED}============================================================${NC}" + echo -e "${RED} BUILD FAILED!${NC}" + echo -e "${RED}============================================================${NC}" + echo "" + echo -e "${YELLOW}Possible causes:${NC}" + echo -e "${WHITE} - Dependencies not in cache${NC}" + echo -e "${WHITE} - Plugin resolution failed${NC}" + echo -e "${WHITE} - Need complete build in online env first${NC}" + exit 1 +fi +echo "" + +# ============================================================================ +# [14/16] Show Build Output +# ============================================================================ +echo -e "${YELLOW}==[14/16] Build Output ==${NC}" + +LIBS_DIR="$PROJECT_DIR/build/libs" +if [ -d "$LIBS_DIR" ]; then + echo -e "${CYAN}build/libs contents:${NC}" + ls -lh "$LIBS_DIR"/*.jar 2>/dev/null | awk '{printf " %-40s %10s\n", $9, $5}' + + MAIN_JAR=$(find "$LIBS_DIR" -name "*.jar" -type f ! -name "*-plain.jar" ! -name "*-sources.jar" ! -name "*-javadoc.jar" 2>/dev/null | head -1) +else + echo -e "${YELLOW}[WARN] build/libs not found${NC}" +fi +echo "" + +# ============================================================================ +# [15/16] Run Instructions +# ============================================================================ +echo -e "${YELLOW}==[15/16] Run Instructions ==${NC}" +echo "" + +if [ -n "$MAIN_JAR" ]; then + echo -e "${CYAN}To run the application:${NC}" + echo -e "${WHITE} java -jar $(basename "$MAIN_JAR")${NC}" + echo "" +fi + +echo -e "${CYAN}To rebuild:${NC}" +echo -e "${WHITE} export GRADLE_USER_HOME=\"./_offline_gradle_home\"${NC}" +echo -e "${WHITE} ./gradlew --offline bootJar --no-daemon${NC}" +echo "" + +# ============================================================================ +# [16/16] Complete +# ============================================================================ +echo -e "${GREEN}============================================================${NC}" +echo -e "${GREEN} Offline Build Complete!${NC}" +echo -e "${GREEN}============================================================${NC}" +echo "" +echo -e "${CYAN}Project: $PROJECT_DIR${NC}" +echo ""