Files
2026-10-02 07:19:13 +02:00

127 lines
4.0 KiB
PowerShell

# Build script: packages the CLI as a single self-executing .exe
#
# Usage:
# .\build.ps1 -> dist\mitsubishi-label-converter.exe
# .\build.ps1 -Clean -> remove build artifacts first
# .\build.ps1 -Onefile -> single-file exe (slower start, one file)
# default is one-folder mode (fast start)
# .\build.ps1 -Test -> run the exe against the real assets afterwards
#
# Requirements: pyinstaller installed in the active environment
# pip install pyinstaller
[CmdletBinding()]
param(
[switch]$Clean,
[switch]$Onefile,
[switch]$Test,
# Explicit interpreter, e.g. -Python C:\Path\To\python.exe
[string]$Python
)
$ErrorActionPreference = "Stop"
$root = $PSScriptRoot
$exename = "mitsubishi-label-converter"
$dist = Join-Path $root "dist"
# Resolve a working Python interpreter -------------------------------
# The Microsoft Store 'python' alias can shadow a real install, so verify
# each candidate by actually running it.
function Test-Python([string]$cmd) {
if (-not $cmd) { return $false }
try {
& $cmd -c "import sys; sys.exit(0)" 2>$null
return ($LASTEXITCODE -eq 0)
} catch {
return $false
}
}
if (-not $Python) {
$candidates = @(
(Join-Path $root ".venv\Scripts\python.exe"), # project venv first
"python",
"py"
)
foreach ($c in $candidates) {
if (Test-Python $c) { $Python = $c; break }
}
}
if (-not $Python -or -not (Test-Python $Python)) {
Write-Error @"
No working Python interpreter found.
Tried: project .venv, 'python' on PATH, 'py' launcher.
Create a venv (python -m venv .venv) or pass one explicitly:
.\build.ps1 -Python C:\Path\To\python.exe
"@
}
Write-Host "==> Using Python: $Python"
# Sanity checks ------------------------------------------------------------
& $Python -m PyInstaller --version 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "PyInstaller not found in '$Python'. Run: $Python -m pip install pyinstaller"
}
if ($Clean) {
Write-Host "==> Cleaning build artifacts..."
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue `
(Join-Path $root "build"), $dist
# remove the egg-info generated by editable installs
Get-ChildItem $root -Filter "*.egg-info" -Directory -ErrorAction SilentlyContinue |
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
# Build --------------------------------------------------------------------
$modeArgs = @()
if ($Onefile) { $modeArgs += "--onefile" } else { $modeArgs += "--onedir" }
Write-Host "==> Building $exename ($($modeArgs -join ' '))..."
& $Python -m PyInstaller @modeArgs `
--name $exename `
--noconfirm `
--clean `
--console `
--paths "$root\src" `
"$root\run.py"
if ($LASTEXITCODE -ne 0) {
Write-Error "PyInstaller failed with exit code $LASTEXITCODE"
}
# Locate the exe -----------------------------------------------------------
if ($Onefile) {
$exe = Join-Path $dist "$exename.exe"
} else {
$exe = Join-Path $dist "$exename\$exename.exe"
}
if (-not (Test-Path $exe)) {
Write-Error "Build finished but exe not found at $exe"
}
$size = "{0:N1} MB" -f ((Get-Item $exe).Length / 1MB)
Write-Host "==> Built: $exe ($size)"
# Optional smoke test -------------------------------------------------------
if ($Test) {
Write-Host "==> Smoke testing against assets/Global.xml..."
$testOut = Join-Path $dist "smoketest.xlsx"
& $exe to-xlsx (Join-Path $root "assets\Global.xml") `
--sdt (Join-Path $root "assets\SDT.xml") `
-o $testOut --force
if ($LASTEXITCODE -ne 0) {
Write-Error "Smoke test failed"
}
& $exe report (Join-Path $root "assets\Global.xml") --sdt (Join-Path $root "assets\SDT.xml")
if ($LASTEXITCODE -ne 0) {
Write-Error "Smoke test (report) failed"
}
Remove-Item $testOut -Force -ErrorAction SilentlyContinue
Write-Host "==> Smoke test OK"
}
Write-Host ""
Write-Host "Done. Distribute: $exe"
if (-not $Onefile) {
Write-Host "Note: one-folder mode requires the whole dist\$exename folder."
}