#requires -Version 5.1 [CmdletBinding()] param( [switch]$OneFile, [switch]$SkipInstaller ) $ErrorActionPreference = "Stop" $Root = Split-Path -Parent $MyInvocation.MyCommand.Path Set-Location $Root function Get-Python { $candidates = @("py -3.11", "py -3", "python") foreach ($candidate in $candidates) { try { $parts = $candidate.Split(" ") $exe = $parts[0] $exeArgs = @($parts | Select-Object -Skip 1) $output = & $exe @exeArgs -c "import sys; print(sys.executable); print(sys.version_info[:2])" 2>$null if ($LASTEXITCODE -eq 0 -and $output -match "3\.11") { return $parts } } catch { } } throw "Python 3.11 x64 is required. Install it from python.org and retry." } $version = "1.0.0" $venv = Join-Path $Root ".venv-build" $python = Get-Python if (-not (Test-Path $venv)) { Write-Host "Creating build environment..." $pythonExe = $python[0] $pythonArgs = @($python | Select-Object -Skip 1) & $pythonExe @pythonArgs -m venv $venv } $py = Join-Path $venv "Scripts\python.exe" if (-not (Test-Path $py)) { throw "The build virtual environment could not be created." } & $py -m pip install --upgrade pip & $py -m pip install -r (Join-Path $Root "requirements-dev.txt") if ($LASTEXITCODE -ne 0) { throw "Dependency installation failed." } if ($OneFile) { $env:BOLTCLAM_ONEFILE = "1" } else { Remove-Item Env:BOLTCLAM_ONEFILE -ErrorAction SilentlyContinue } Write-Host "Building BoltClam $version..." & $py -m PyInstaller --noconfirm --clean (Join-Path $Root "BoltClam.spec") if ($LASTEXITCODE -ne 0) { throw "PyInstaller failed." } $dist = Join-Path $Root "dist" $artifacts = @() if ($OneFile) { $exe = Join-Path $dist "BoltClam.exe" if (-not (Test-Path $exe)) { throw "Expected $exe was not produced." } $artifacts += $exe } else { $folder = Join-Path $dist "BoltClam" $exe = Join-Path $folder "BoltClam.exe" if (-not (Test-Path $exe)) { throw "Expected $exe was not produced." } $zip = Join-Path $dist "BoltClam-$version-windows-x64.zip" if (Test-Path $zip) { Remove-Item $zip -Force } Compress-Archive -Path (Join-Path $folder "*") -DestinationPath $zip -CompressionLevel Optimal $artifacts += $zip if (-not $SkipInstaller) { $isccCandidates = @( "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe", "$env:ProgramFiles\Inno Setup 6\ISCC.exe" ) $iscc = $isccCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1 if ($iscc) { Write-Host "Building installer with $iscc..." & $iscc "/DMyAppVersion=$version" (Join-Path $Root "installer\BoltClam.iss") if ($LASTEXITCODE -ne 0) { throw "Inno Setup failed." } $setup = Join-Path $dist "BoltClam-$version-Setup.exe" if (Test-Path $setup) { $artifacts += $setup } } else { Write-Warning "Inno Setup 6 was not found; skipping the installer." } } } $checksumPath = Join-Path $dist "SHA256SUMS.txt" $lines = foreach ($artifact in $artifacts) { $hash = (Get-FileHash -Algorithm SHA256 $artifact).Hash.ToLowerInvariant() "$hash $(Split-Path -Leaf $artifact)" } $lines | Set-Content -Encoding ASCII $checksumPath Write-Host "" Write-Host "Built:" $artifacts | ForEach-Object { Write-Host " $_" } Write-Host "Checksums: $checksumPath"