139 lines
5.5 KiB
PowerShell
139 lines
5.5 KiB
PowerShell
# Compila jail-launcher con Nuitka y empaqueta un release para Windows.
|
|
# - jail-launcher.exe (onefile, GUI sin consola, con icono) + games.toml + .zip.
|
|
# Equivalente nativo de build.sh (que cubre Linux/macOS).
|
|
# Requisitos del sistema (no los instala el script):
|
|
# - Python 3.10+ (con el launcher «py» o «python» en el PATH).
|
|
# - Un compilador C: Nuitka usa MSVC (Build Tools de Visual Studio) si existe;
|
|
# si no, ofrece descargar MinGW automáticamente (-AssumeYesForDownloads).
|
|
# - git en el PATH (lo usa la app en tiempo de ejecución, no el build).
|
|
#
|
|
# Uso: pwsh -File build.ps1 (o: .\build.ps1 desde PowerShell)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
Set-StrictMode -Version Latest
|
|
|
|
# Situarnos en la carpeta del script.
|
|
$Here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
Set-Location $Here
|
|
|
|
# --- Versión (leída de jail_launcher/__init__.py) ---------------------------------
|
|
$initPath = Join-Path $Here 'jail_launcher\__init__.py'
|
|
$verMatch = Select-String -Path $initPath -Pattern '^__version__\s*=\s*"([^"]*)"' |
|
|
Select-Object -First 1
|
|
if (-not $verMatch) {
|
|
Write-Error '[build] no se pudo leer __version__ de jail_launcher/__init__.py'
|
|
}
|
|
$Version = $verMatch.Matches[0].Groups[1].Value
|
|
|
|
# Arquitectura al estilo uname -m (x86_64 / arm64).
|
|
$Arch = switch ($env:PROCESSOR_ARCHITECTURE) {
|
|
'AMD64' { 'x86_64' }
|
|
'ARM64' { 'arm64' }
|
|
default { $env:PROCESSOR_ARCHITECTURE.ToLower() }
|
|
}
|
|
|
|
# --- Intérprete de Python -----------------------------------------------------
|
|
# Preferimos el launcher «py -3»; si no, «python».
|
|
function Resolve-Python {
|
|
if (Get-Command py -ErrorAction SilentlyContinue) { return @('py', '-3') }
|
|
if (Get-Command python -ErrorAction SilentlyContinue) { return @('python') }
|
|
Write-Error '[build] no se encontró Python (ni «py» ni «python» en el PATH).'
|
|
}
|
|
$Py = Resolve-Python
|
|
|
|
# Comprueba si un módulo se puede importar en el venv, SIN abortar el script:
|
|
# bajo $ErrorActionPreference='Stop', un código de salida ≠ 0 (módulo ausente)
|
|
# se trataría como error terminante. Aquí relajamos eso solo para la sonda.
|
|
function Test-PyModule([string]$Module) {
|
|
$prev = $ErrorActionPreference
|
|
$ErrorActionPreference = 'Continue'
|
|
try {
|
|
& $VenvPython -c "import $Module" 2>&1 | Out-Null
|
|
return ($LASTEXITCODE -eq 0)
|
|
}
|
|
finally {
|
|
$ErrorActionPreference = $prev
|
|
}
|
|
}
|
|
|
|
# --- venv (en Windows los ejecutables viven en .venv\Scripts) -----------------
|
|
$VenvPython = Join-Path $Here '.venv\Scripts\python.exe'
|
|
if (-not (Test-Path $VenvPython)) {
|
|
Write-Host '[build] creando venv…'
|
|
& $Py[0] $Py[1..($Py.Count - 1)] -m venv .venv
|
|
& $VenvPython -m pip install --quiet --upgrade pip
|
|
}
|
|
|
|
Write-Host '[build] sincronizando dependencias…'
|
|
& $VenvPython -m pip install --quiet -r requirements.txt
|
|
|
|
# Nuitka + zstandard (compresión del onefile → binario más pequeño).
|
|
if (-not (Test-PyModule 'nuitka')) {
|
|
Write-Host '[build] instalando nuitka en el venv…'
|
|
& $VenvPython -m pip install --quiet 'nuitka[onefile]'
|
|
}
|
|
if (-not (Test-PyModule 'zstandard')) {
|
|
Write-Host '[build] instalando zstandard (compresión onefile)…'
|
|
& $VenvPython -m pip install --quiet zstandard
|
|
}
|
|
|
|
Write-Host "[build] versión: v$Version"
|
|
Write-Host '[build] limpiando artefactos previos…'
|
|
foreach ($d in 'dist', 'build', 'app.build', 'app.dist', 'app.onefile-build') {
|
|
if (Test-Path $d) { Remove-Item -Recurse -Force $d }
|
|
}
|
|
|
|
$IconIco = 'icon\icon.ico'
|
|
$IconPng = 'icon\icon.png'
|
|
if (-not (Test-Path $IconIco)) {
|
|
Write-Error "[build] falta $IconIco"
|
|
}
|
|
|
|
# --- Compilación onefile ------------------------------------------------------
|
|
Write-Host '[build] compilando jail-launcher.exe (PySide6 onefile; puede tardar varios minutos)…'
|
|
& $VenvPython -m nuitka `
|
|
--onefile `
|
|
--assume-yes-for-downloads `
|
|
--enable-plugin=pyside6 `
|
|
--include-package=jail_launcher `
|
|
--windows-icon-from-ico=$IconIco `
|
|
--windows-console-mode=disable `
|
|
--company-name=jailgames `
|
|
--product-name=jail-launcher `
|
|
--product-version=$Version `
|
|
--file-version=$Version `
|
|
--output-dir=dist `
|
|
--output-filename=jail-launcher `
|
|
--remove-output `
|
|
app.py
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error '[build] Nuitka falló.'
|
|
}
|
|
|
|
$Exe = 'dist\jail-launcher.exe'
|
|
if (-not (Test-Path $Exe)) {
|
|
Write-Error '[build] Nuitka no produjo dist\jail-launcher.exe'
|
|
}
|
|
|
|
# games.toml junto al .exe (la app lo lee desde ahí: base_dir junto al binario).
|
|
Write-Host '[build] copiando games.toml junto al ejecutable…'
|
|
Copy-Item games.toml dist\games.toml -Force
|
|
|
|
# icon.png para el diálogo «Quant a» (paths.app_icon_path → base_dir()\icon\icon.png).
|
|
Write-Host '[build] sembrando icon\icon.png para el diálogo «Quant a»…'
|
|
New-Item -ItemType Directory -Force -Path dist\icon | Out-Null
|
|
Copy-Item $IconPng dist\icon\icon.png -Force
|
|
|
|
# --- Empaquetado .zip ---------------------------------------------------------
|
|
$ReleaseName = "jail-launcher-v$Version-windows-$Arch"
|
|
$Zip = "dist\$ReleaseName.zip"
|
|
Write-Host "[build] empaquetando release $ReleaseName.zip…"
|
|
Compress-Archive -Path dist\jail-launcher.exe, dist\games.toml, dist\icon `
|
|
-DestinationPath $Zip -Force
|
|
|
|
Write-Host '[build] hecho:'
|
|
Get-Item dist\jail-launcher.exe, dist\games.toml, $Zip |
|
|
Format-Table -AutoSize Name, @{Name = 'Size'; Expression = { '{0:N0} B' -f $_.Length } }
|
|
Write-Host '[build] el binario crea jail_launcher_data\ y settings.json junto a sí mismo.'
|
|
Write-Host '[build] distribuir: descomprimir el .zip (jail-launcher.exe + games.toml + icon\ juntos).'
|