673 lines
27 KiB
PowerShell
Executable File
673 lines
27 KiB
PowerShell
Executable File
# pack_offline_bundle_airgap.ps1
|
||
# ============================================================================
|
||
# Gradle Offline Bundle Packer
|
||
# ============================================================================
|
||
# Version: 4.0
|
||
#
|
||
# WORKFLOW:
|
||
# 1. [ONLINE] Build project (./gradlew.bat bootJar) - downloads all deps
|
||
# 2. [ONLINE] Test run (./gradlew.bat 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.bat
|
||
# ============================================================================
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
$ProgressPreference = "SilentlyContinue"
|
||
|
||
# ============================================================================
|
||
# Configuration
|
||
# ============================================================================
|
||
$WRAPPER_SEED_PATH = "wrapper_jar_seed"
|
||
$OFFLINE_HOME_NAME = "_offline_gradle_home"
|
||
$BOOTRUN_TIMEOUT_SECONDS = 60
|
||
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host " Gradle Offline Bundle Packer v4.0" -ForegroundColor Cyan
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host " This script will:" -ForegroundColor White
|
||
Write-Host " 1. Build project with internet (download dependencies)" -ForegroundColor Gray
|
||
Write-Host " 2. Test run application (verify it works)" -ForegroundColor Gray
|
||
Write-Host " 3. Test offline build (verify cache is complete)" -ForegroundColor Gray
|
||
Write-Host " 4. Create offline bundle for air-gapped environment" -ForegroundColor Gray
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [1/20] Check Current Directory
|
||
# ============================================================================
|
||
Write-Host "==[1/20] Check Current Directory ==" -ForegroundColor Yellow
|
||
$Root = (Get-Location).Path
|
||
Write-Host ("ROOT_DIR: " + $Root)
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [2/20] Check Required Files
|
||
# ============================================================================
|
||
Write-Host "==[2/20] Check Required Files ==" -ForegroundColor Yellow
|
||
|
||
if (!(Test-Path -LiteralPath ".\gradlew.bat")) {
|
||
throw "ERROR: gradlew.bat not found. Run from project root."
|
||
}
|
||
Write-Host "[OK] gradlew.bat" -ForegroundColor Green
|
||
|
||
$buildFile = $null
|
||
if (Test-Path -LiteralPath ".\build.gradle") { $buildFile = "build.gradle" }
|
||
elseif (Test-Path -LiteralPath ".\build.gradle.kts") { $buildFile = "build.gradle.kts" }
|
||
else { throw "ERROR: build.gradle(.kts) not found." }
|
||
Write-Host ("[OK] " + $buildFile) -ForegroundColor Green
|
||
|
||
$settingsFile = $null
|
||
if (Test-Path -LiteralPath ".\settings.gradle") { $settingsFile = "settings.gradle" }
|
||
elseif (Test-Path -LiteralPath ".\settings.gradle.kts") { $settingsFile = "settings.gradle.kts" }
|
||
if ($settingsFile) { Write-Host ("[OK] " + $settingsFile) -ForegroundColor Green }
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [3/20] Check Gradle Wrapper
|
||
# ============================================================================
|
||
Write-Host "==[3/20] Check Gradle Wrapper ==" -ForegroundColor Yellow
|
||
|
||
$WrapperDir = Join-Path $Root "gradle\wrapper"
|
||
$WrapperJar = Join-Path $WrapperDir "gradle-wrapper.jar"
|
||
$WrapperProp = Join-Path $WrapperDir "gradle-wrapper.properties"
|
||
|
||
New-Item -ItemType Directory -Force -Path $WrapperDir | Out-Null
|
||
|
||
if (!(Test-Path -LiteralPath $WrapperProp)) {
|
||
throw "ERROR: gradle-wrapper.properties not found."
|
||
}
|
||
|
||
if (!(Test-Path -LiteralPath $WrapperJar)) {
|
||
$SeedJar = Join-Path $Root "$WRAPPER_SEED_PATH\gradle-wrapper.jar"
|
||
if (Test-Path -LiteralPath $SeedJar) {
|
||
Copy-Item -Force -LiteralPath $SeedJar -Destination $WrapperJar
|
||
Write-Host "[OK] Wrapper jar injected from seed" -ForegroundColor Green
|
||
} else {
|
||
throw "ERROR: gradle-wrapper.jar missing"
|
||
}
|
||
} else {
|
||
Write-Host "[OK] gradle-wrapper.jar exists" -ForegroundColor Green
|
||
}
|
||
|
||
# Create seed backup
|
||
$SeedDir = Join-Path $Root $WRAPPER_SEED_PATH
|
||
if (!(Test-Path -LiteralPath $SeedDir)) {
|
||
New-Item -ItemType Directory -Force -Path $SeedDir | Out-Null
|
||
Copy-Item -Force -LiteralPath $WrapperJar -Destination (Join-Path $SeedDir "gradle-wrapper.jar")
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [4/20] Set GRADLE_USER_HOME (Project Local)
|
||
# ============================================================================
|
||
Write-Host "==[4/20] Set GRADLE_USER_HOME ==" -ForegroundColor Yellow
|
||
|
||
$OfflineHome = Join-Path $Root $OFFLINE_HOME_NAME
|
||
New-Item -ItemType Directory -Force -Path $OfflineHome | Out-Null
|
||
$env:GRADLE_USER_HOME = $OfflineHome
|
||
|
||
Write-Host ("GRADLE_USER_HOME = " + $env:GRADLE_USER_HOME) -ForegroundColor Cyan
|
||
Write-Host "[INFO] All dependencies will be cached in project folder" -ForegroundColor Gray
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [5/20] Check Internet Connection
|
||
# ============================================================================
|
||
Write-Host "==[5/20] Check Internet Connection ==" -ForegroundColor Yellow
|
||
|
||
$hasInternet = $false
|
||
$testHosts = @("plugins.gradle.org", "repo.maven.apache.org", "repo1.maven.org")
|
||
|
||
foreach ($testHost in $testHosts) {
|
||
try {
|
||
$result = Test-Connection -ComputerName $testHost -Count 1 -Quiet -TimeoutSeconds 3 -ErrorAction SilentlyContinue
|
||
if ($result) {
|
||
$hasInternet = $true
|
||
Write-Host ("[OK] Connected to " + $testHost) -ForegroundColor Green
|
||
break
|
||
}
|
||
} catch { }
|
||
}
|
||
|
||
if (-not $hasInternet) {
|
||
# Try DNS resolution as fallback
|
||
try {
|
||
[System.Net.Dns]::GetHostAddresses("google.com") | Out-Null
|
||
$hasInternet = $true
|
||
Write-Host "[OK] Internet available (DNS)" -ForegroundColor Green
|
||
} catch { }
|
||
}
|
||
|
||
if (-not $hasInternet) {
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host " ERROR: No Internet Connection!" -ForegroundColor Red
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host ""
|
||
Write-Host "This script requires internet for initial build." -ForegroundColor Yellow
|
||
Write-Host "Please connect to internet and run again." -ForegroundColor Yellow
|
||
Write-Host ""
|
||
throw "No internet connection"
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [6/20] Initial Gradle Setup
|
||
# ============================================================================
|
||
Write-Host "==[6/20] Initial Gradle Setup ==" -ForegroundColor Yellow
|
||
Write-Host "[INFO] Downloading Gradle distribution..." -ForegroundColor Gray
|
||
|
||
try {
|
||
$output = cmd /c ".\gradlew.bat --version 2>&1"
|
||
if ($LASTEXITCODE -eq 0) {
|
||
$gradleVersion = $output | Select-String "Gradle\s+(\d+\.\d+)" |
|
||
ForEach-Object { $_.Matches[0].Groups[1].Value }
|
||
Write-Host ("[OK] Gradle " + $gradleVersion) -ForegroundColor Green
|
||
} else {
|
||
throw "Gradle setup failed"
|
||
}
|
||
} catch {
|
||
Write-Host "[ERROR] Gradle setup failed" -ForegroundColor Red
|
||
throw $_
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [7/20] ONLINE BUILD - bootJar (Download All Dependencies)
|
||
# ============================================================================
|
||
Write-Host "==[7/20] ONLINE BUILD - bootJar ==" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host " Building project (downloading all dependencies)" -ForegroundColor Cyan
|
||
Write-Host " This may take several minutes on first run..." -ForegroundColor Cyan
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
$buildSuccess = $false
|
||
|
||
try {
|
||
cmd /c ".\gradlew.bat clean bootJar --no-daemon"
|
||
if ($LASTEXITCODE -eq 0) {
|
||
$buildSuccess = $true
|
||
}
|
||
} catch { }
|
||
|
||
if (-not $buildSuccess) {
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host " BUILD FAILED!" -ForegroundColor Red
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host ""
|
||
Write-Host "Please fix build errors and run this script again." -ForegroundColor Yellow
|
||
throw "Build failed"
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "[OK] bootJar build SUCCESS" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [8/20] ONLINE TEST - bootRun (Verify Application Works)
|
||
# ============================================================================
|
||
Write-Host "==[8/20] ONLINE TEST - bootRun ==" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host " Starting application to verify it works..." -ForegroundColor Cyan
|
||
Write-Host " Will run for $BOOTRUN_TIMEOUT_SECONDS seconds then stop" -ForegroundColor Cyan
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
$bootRunSuccess = $false
|
||
|
||
try {
|
||
# Start bootRun as background job
|
||
$job = Start-Job -ScriptBlock {
|
||
param($projectDir, $gradleHome)
|
||
Set-Location $projectDir
|
||
$env:GRADLE_USER_HOME = $gradleHome
|
||
cmd /c ".\gradlew.bat bootRun --no-daemon 2>&1"
|
||
} -ArgumentList $Root, $OfflineHome
|
||
|
||
Write-Host "[INFO] Application starting..." -ForegroundColor Gray
|
||
|
||
# Wait for startup (check for typical Spring Boot messages)
|
||
$startTime = Get-Date
|
||
$startupDetected = $false
|
||
|
||
while (((Get-Date) - $startTime).TotalSeconds -lt $BOOTRUN_TIMEOUT_SECONDS) {
|
||
Start-Sleep -Seconds 3
|
||
|
||
# Check if job has output
|
||
$jobOutput = Receive-Job -Job $job -Keep -ErrorAction SilentlyContinue
|
||
|
||
if ($jobOutput) {
|
||
$outputText = $jobOutput -join "`n"
|
||
|
||
# Check for Spring Boot startup success indicators
|
||
if ($outputText -match "Started .+ in .+ seconds" -or
|
||
$outputText -match "Tomcat started on port" -or
|
||
$outputText -match "Netty started on port" -or
|
||
$outputText -match "Application .+ started") {
|
||
$startupDetected = $true
|
||
Write-Host "[OK] Application started successfully!" -ForegroundColor Green
|
||
break
|
||
}
|
||
|
||
# Check for errors
|
||
if ($outputText -match "APPLICATION FAILED TO START" -or
|
||
$outputText -match "Error starting ApplicationContext") {
|
||
Write-Host "[ERROR] Application failed to start" -ForegroundColor Red
|
||
break
|
||
}
|
||
}
|
||
|
||
$elapsed = [math]::Round(((Get-Date) - $startTime).TotalSeconds)
|
||
Write-Host ("[INFO] Waiting... " + $elapsed + "s") -ForegroundColor Gray
|
||
}
|
||
|
||
# Stop the job
|
||
Write-Host "[INFO] Stopping application..." -ForegroundColor Gray
|
||
Stop-Job -Job $job -ErrorAction SilentlyContinue
|
||
Remove-Job -Job $job -Force -ErrorAction SilentlyContinue
|
||
|
||
# Also stop any remaining Gradle processes
|
||
cmd /c ".\gradlew.bat --stop 2>&1" | Out-Null
|
||
|
||
if ($startupDetected) {
|
||
$bootRunSuccess = $true
|
||
}
|
||
|
||
} catch {
|
||
Write-Host "[WARN] bootRun test encountered error: $_" -ForegroundColor DarkYellow
|
||
}
|
||
|
||
# Cleanup any remaining processes
|
||
try {
|
||
Get-Process -Name "java" -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.CommandLine -match "bootRun|spring" } |
|
||
Stop-Process -Force -ErrorAction SilentlyContinue
|
||
} catch { }
|
||
|
||
Write-Host ""
|
||
|
||
if ($bootRunSuccess) {
|
||
Write-Host "[OK] bootRun test PASSED" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "[WARN] bootRun test could not verify startup" -ForegroundColor DarkYellow
|
||
Write-Host "[INFO] Continuing anyway - bootJar succeeded" -ForegroundColor Gray
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [9/20] Stop All Gradle Daemons
|
||
# ============================================================================
|
||
Write-Host "==[9/20] Stop Gradle Daemons ==" -ForegroundColor Yellow
|
||
|
||
cmd /c ".\gradlew.bat --stop 2>&1" | Out-Null
|
||
Start-Sleep -Seconds 3
|
||
Write-Host "[OK] Daemons stopped" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [10/20] OFFLINE TEST - Verify Offline Build Works
|
||
# ============================================================================
|
||
Write-Host "==[10/20] OFFLINE TEST - Verify Cache ==" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host " Testing offline build (--offline flag)" -ForegroundColor Cyan
|
||
Write-Host " This verifies all dependencies are cached" -ForegroundColor Cyan
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
$offlineSuccess = $false
|
||
|
||
try {
|
||
cmd /c ".\gradlew.bat --offline clean bootJar --no-daemon"
|
||
if ($LASTEXITCODE -eq 0) {
|
||
$offlineSuccess = $true
|
||
}
|
||
} catch { }
|
||
|
||
Write-Host ""
|
||
|
||
if ($offlineSuccess) {
|
||
Write-Host "[OK] Offline build SUCCESS - Cache is complete!" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host " OFFLINE BUILD FAILED!" -ForegroundColor Red
|
||
Write-Host "============================================================" -ForegroundColor Red
|
||
Write-Host ""
|
||
Write-Host "Some dependencies may not be cached properly." -ForegroundColor Yellow
|
||
Write-Host ""
|
||
|
||
$continue = Read-Host "Continue creating bundle anyway? (y/N)"
|
||
if ($continue -ne "y" -and $continue -ne "Y") {
|
||
throw "Offline verification failed"
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [11/20] Backup Original settings.gradle
|
||
# ============================================================================
|
||
Write-Host "==[11/20] Backup settings.gradle ==" -ForegroundColor Yellow
|
||
|
||
if ($settingsFile) {
|
||
$settingsPath = Join-Path $Root $settingsFile
|
||
$settingsBackup = Join-Path $Root "${settingsFile}.original.bak"
|
||
|
||
if (!(Test-Path -LiteralPath $settingsBackup)) {
|
||
Copy-Item -Force -LiteralPath $settingsPath -Destination $settingsBackup
|
||
Write-Host "[OK] Backup: ${settingsFile}.original.bak" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "[OK] Backup exists" -ForegroundColor Green
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [12/20] Modify settings.gradle for Offline
|
||
# ============================================================================
|
||
Write-Host "==[12/20] Configure settings.gradle for Offline ==" -ForegroundColor Yellow
|
||
|
||
if ($settingsFile) {
|
||
$settingsPath = Join-Path $Root $settingsFile
|
||
$content = Get-Content -LiteralPath $settingsPath -Raw
|
||
|
||
# --- Always strip BOM if present (prevents Groovy 'Unexpected character: ')
|
||
$hadBom = $false
|
||
if ($content.Length -gt 0 -and $content[0] -eq [char]0xFEFF) {
|
||
$hadBom = $true
|
||
$content = $content -replace "^\uFEFF", ""
|
||
}
|
||
|
||
$isOfflineConfigured =
|
||
($content -match "mavenLocal\(\)") -and
|
||
($content -match "pluginManagement[\s\S]*repositories")
|
||
|
||
if ($isOfflineConfigured) {
|
||
# Even if already configured, re-save without BOM if needed
|
||
if ($hadBom) {
|
||
[System.IO.File]::WriteAllText(
|
||
$settingsPath,
|
||
$content,
|
||
(New-Object System.Text.UTF8Encoding($false))
|
||
)
|
||
Write-Host "[FIX] settings.gradle BOM removed (saved as UTF-8 without BOM)" -ForegroundColor Green
|
||
} else {
|
||
Write-Host "[OK] Already configured for offline" -ForegroundColor Green
|
||
}
|
||
} else {
|
||
$newHeader = @"
|
||
// ============================================================================
|
||
// OFFLINE BUILD CONFIGURATION (Auto-generated by pack script)
|
||
// Original backup: ${settingsFile}.original.bak
|
||
// ============================================================================
|
||
pluginManagement {
|
||
repositories {
|
||
mavenLocal()
|
||
gradlePluginPortal()
|
||
}
|
||
}
|
||
|
||
"@
|
||
|
||
# Remove existing pluginManagement
|
||
$cleaned = $content -replace '(?s)pluginManagement\s*\{[^{}]*(\{[^{}]*\}[^{}]*)*\}\s*', ''
|
||
$final = $newHeader + $cleaned.Trim()
|
||
|
||
# --- Write as UTF-8 WITHOUT BOM
|
||
[System.IO.File]::WriteAllText(
|
||
$settingsPath,
|
||
$final,
|
||
(New-Object System.Text.UTF8Encoding($false))
|
||
)
|
||
|
||
Write-Host "[OK] settings.gradle updated for offline (UTF-8 without BOM)" -ForegroundColor Green
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [13/20] Copy Maven Local Repository
|
||
# ============================================================================
|
||
Write-Host "==[13/20] Copy Maven Local (.m2) ==" -ForegroundColor Yellow
|
||
|
||
$m2Repo = Join-Path $env:USERPROFILE ".m2\repository"
|
||
$localM2 = Join-Path $OfflineHome "m2_repository"
|
||
|
||
if (Test-Path -LiteralPath $m2Repo) {
|
||
$m2Size = (Get-ChildItem -Path $m2Repo -Recurse -File -ErrorAction SilentlyContinue |
|
||
Measure-Object -Property Length -Sum).Sum
|
||
|
||
if ($m2Size -gt 1MB) {
|
||
$m2SizeMB = [math]::Round($m2Size / 1MB, 2)
|
||
Write-Host ("[INFO] .m2 size: " + $m2SizeMB + " MB") -ForegroundColor Cyan
|
||
|
||
# Copy important plugin directories
|
||
$pluginDirs = @(
|
||
"org\springframework\boot",
|
||
"io\spring",
|
||
"com\diffplug"
|
||
)
|
||
|
||
foreach ($dir in $pluginDirs) {
|
||
$src = Join-Path $m2Repo $dir
|
||
if (Test-Path -LiteralPath $src) {
|
||
$dst = Join-Path $localM2 $dir
|
||
New-Item -ItemType Directory -Force -Path (Split-Path $dst -Parent) | Out-Null
|
||
if (!(Test-Path -LiteralPath $dst)) {
|
||
Copy-Item -Recurse -Force -LiteralPath $src -Destination $dst -ErrorAction SilentlyContinue
|
||
Write-Host ("[OK] Copied " + $dir) -ForegroundColor Green
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
Write-Host "[INFO] No .m2 repository found" -ForegroundColor Gray
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [14/20] Create Helper Scripts
|
||
# ============================================================================
|
||
Write-Host "==[14/20] Create Helper Scripts ==" -ForegroundColor Yellow
|
||
|
||
# run_offline_build.ps1
|
||
$runScript = @'
|
||
# run_offline_build.ps1 - Quick offline build script
|
||
$env:GRADLE_USER_HOME = Join-Path (Get-Location).Path "_offline_gradle_home"
|
||
Write-Host "GRADLE_USER_HOME = $env:GRADLE_USER_HOME" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
.\gradlew.bat --offline bootJar --no-daemon
|
||
if ($LASTEXITCODE -eq 0) {
|
||
Write-Host ""
|
||
Write-Host "BUILD SUCCESS!" -ForegroundColor Green
|
||
Write-Host ""
|
||
Write-Host "JAR files:" -ForegroundColor Cyan
|
||
Get-ChildItem .\build\libs\*.jar | ForEach-Object { Write-Host (" " + $_.Name) }
|
||
} else {
|
||
Write-Host "BUILD FAILED" -ForegroundColor Red
|
||
}
|
||
'@
|
||
|
||
[System.IO.File]::WriteAllText((Join-Path $Root "run_offline_build.ps1"), $runScript, (New-Object System.Text.UTF8Encoding($false)))
|
||
Write-Host "[OK] run_offline_build.ps1" -ForegroundColor Green
|
||
|
||
# run_offline_bootrun.ps1
|
||
$bootRunScript = @'
|
||
# run_offline_bootrun.ps1 - Run application offline
|
||
$env:GRADLE_USER_HOME = Join-Path (Get-Location).Path "_offline_gradle_home"
|
||
Write-Host "GRADLE_USER_HOME = $env:GRADLE_USER_HOME" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "Starting application (Ctrl+C to stop)..." -ForegroundColor Yellow
|
||
Write-Host ""
|
||
.\gradlew.bat --offline bootRun --no-daemon
|
||
'@
|
||
|
||
[System.IO.File]::WriteAllText((Join-Path $Root "run_offline_bootrun.ps1"), $bootRunScript, (New-Object System.Text.UTF8Encoding($false)))
|
||
Write-Host "[OK] run_offline_bootrun.ps1" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [15/20] Stop Daemons Again
|
||
# ============================================================================
|
||
Write-Host "==[15/20] Final Daemon Cleanup ==" -ForegroundColor Yellow
|
||
|
||
cmd /c ".\gradlew.bat --stop 2>&1" | Out-Null
|
||
Start-Sleep -Seconds 2
|
||
Write-Host "[OK] Daemons stopped" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [16/20] Clean Lock Files
|
||
# ============================================================================
|
||
Write-Host "==[16/20] Clean Lock Files ==" -ForegroundColor Yellow
|
||
|
||
try {
|
||
$DaemonDir = Join-Path $OfflineHome "daemon"
|
||
if (Test-Path -LiteralPath $DaemonDir) {
|
||
Remove-Item -Recurse -Force -LiteralPath $DaemonDir -ErrorAction SilentlyContinue
|
||
}
|
||
|
||
Get-ChildItem -Path $OfflineHome -Recurse -Include "*.lock","*.log","*.tmp" -File -ErrorAction SilentlyContinue |
|
||
ForEach-Object { Remove-Item -Force -LiteralPath $_.FullName -ErrorAction SilentlyContinue }
|
||
|
||
Write-Host "[OK] Lock files cleaned" -ForegroundColor Green
|
||
} catch {
|
||
Write-Host "[WARN] Some files could not be cleaned" -ForegroundColor DarkYellow
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [17/20] Calculate Cache Size
|
||
# ============================================================================
|
||
Write-Host "==[17/20] Cache Summary ==" -ForegroundColor Yellow
|
||
|
||
$CachesDir = Join-Path $OfflineHome "caches"
|
||
$WrapperDists = Join-Path $OfflineHome "wrapper\dists"
|
||
|
||
$totalSize = 0
|
||
|
||
if (Test-Path -LiteralPath $CachesDir) {
|
||
$size = (Get-ChildItem -Path $CachesDir -Recurse -File -ErrorAction SilentlyContinue |
|
||
Measure-Object -Property Length -Sum).Sum
|
||
$totalSize += $size
|
||
Write-Host ("[INFO] Dependencies: " + [math]::Round($size/1MB, 2) + " MB") -ForegroundColor Cyan
|
||
}
|
||
|
||
if (Test-Path -LiteralPath $WrapperDists) {
|
||
$size = (Get-ChildItem -Path $WrapperDists -Recurse -File -ErrorAction SilentlyContinue |
|
||
Measure-Object -Property Length -Sum).Sum
|
||
$totalSize += $size
|
||
Write-Host ("[INFO] Gradle dist: " + [math]::Round($size/1MB, 2) + " MB") -ForegroundColor Cyan
|
||
}
|
||
|
||
Write-Host ("[INFO] Total cache: " + [math]::Round($totalSize/1MB, 2) + " MB") -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [18/20] Create Archive
|
||
# ============================================================================
|
||
Write-Host "==[18/20] Create Archive ==" -ForegroundColor Yellow
|
||
|
||
$BaseName = Split-Path $Root -Leaf
|
||
$Ts = Get-Date -Format "yyyyMMdd_HHmmss"
|
||
$Parent = Split-Path $Root -Parent
|
||
$ArchivePath = Join-Path $Parent "${BaseName}_offline_bundle_${Ts}.tar.gz"
|
||
|
||
Write-Host ("Archive: " + $ArchivePath)
|
||
|
||
$tar = Get-Command tar.exe -ErrorAction SilentlyContinue
|
||
if (-not $tar) { throw "ERROR: tar.exe not found" }
|
||
|
||
Write-Host "[INFO] Creating archive (this may take several minutes)..." -ForegroundColor Gray
|
||
|
||
& tar.exe -czf $ArchivePath `
|
||
--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 ($LASTEXITCODE -ne 0) { throw "ERROR: tar failed" }
|
||
|
||
$archiveSize = (Get-Item -LiteralPath $ArchivePath).Length
|
||
$archiveSizeMB = [math]::Round($archiveSize / 1MB, 2)
|
||
Write-Host ("[OK] Archive created: " + $archiveSizeMB + " MB") -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [19/20] Verify Archive
|
||
# ============================================================================
|
||
Write-Host "==[19/20] Verify Archive ==" -ForegroundColor Yellow
|
||
|
||
$listOutput = & tar.exe -tzf $ArchivePath 2>&1
|
||
|
||
$checks = @(
|
||
"gradle/wrapper/gradle-wrapper.jar",
|
||
"gradlew.bat",
|
||
"_offline_gradle_home/caches",
|
||
"run_offline_build.ps1"
|
||
)
|
||
|
||
foreach ($check in $checks) {
|
||
$found = $listOutput | Select-String -SimpleMatch $check
|
||
if ($found) {
|
||
Write-Host (" [OK] " + $check) -ForegroundColor Green
|
||
} else {
|
||
Write-Host (" [WARN] " + $check) -ForegroundColor DarkYellow
|
||
}
|
||
}
|
||
Write-Host ""
|
||
|
||
# ============================================================================
|
||
# [20/20] Complete
|
||
# ============================================================================
|
||
Write-Host "============================================================" -ForegroundColor Green
|
||
Write-Host " BUNDLE CREATION COMPLETE!" -ForegroundColor Green
|
||
Write-Host "============================================================" -ForegroundColor Green
|
||
Write-Host ""
|
||
Write-Host ("Archive: " + $ArchivePath) -ForegroundColor Cyan
|
||
Write-Host ("Size: " + $archiveSizeMB + " MB") -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host " Test Results" -ForegroundColor Cyan
|
||
Write-Host "============================================================" -ForegroundColor Cyan
|
||
Write-Host (" Online build (bootJar): " + $(if($buildSuccess){"PASSED"}else{"FAILED"})) -ForegroundColor $(if($buildSuccess){"Green"}else{"Red"})
|
||
Write-Host (" Online test (bootRun): " + $(if($bootRunSuccess){"PASSED"}else{"SKIPPED"})) -ForegroundColor $(if($bootRunSuccess){"Green"}else{"Yellow"})
|
||
Write-Host (" Offline build test: " + $(if($offlineSuccess){"PASSED"}else{"FAILED"})) -ForegroundColor $(if($offlineSuccess){"Green"}else{"Red"})
|
||
Write-Host ""
|
||
|
||
Write-Host "============================================================" -ForegroundColor Yellow
|
||
Write-Host " Usage in Air-gapped Environment" -ForegroundColor Yellow
|
||
Write-Host "============================================================" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
Write-Host "Option 1: Use unpack script" -ForegroundColor White
|
||
Write-Host " .\unpack_and_offline_build_airgap.ps1" -ForegroundColor Gray
|
||
Write-Host ""
|
||
Write-Host "Option 2: Manual extraction" -ForegroundColor White
|
||
Write-Host " tar -xzf <archive>.tar.gz" -ForegroundColor Gray
|
||
Write-Host " cd <project>" -ForegroundColor Gray
|
||
Write-Host " .\run_offline_build.ps1" -ForegroundColor Gray
|
||
Write-Host ""
|
||
Write-Host "Option 3: Direct commands" -ForegroundColor White
|
||
Write-Host ' $env:GRADLE_USER_HOME = ".\\_offline_gradle_home"' -ForegroundColor Gray
|
||
Write-Host " .\gradlew.bat --offline bootJar --no-daemon" -ForegroundColor Gray
|
||
Write-Host ""
|