87 lines
3.8 KiB
PowerShell
87 lines
3.8 KiB
PowerShell
# Package nl-pms-api for desktop "package" task.
|
|
# Rebuilds only when sources change; pass -Force to always rebuild.
|
|
# Output: view/bin/nl-pms-api/ (linux/amd64 binary + init.sql + migrations + config.example.yaml)
|
|
|
|
param(
|
|
[switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$ViewRoot = Split-Path -Parent $PSScriptRoot
|
|
$ApiRoot = Join-Path (Split-Path -Parent $ViewRoot) 'nl-pms-api'
|
|
$OutDir = Join-Path $ViewRoot 'bin\nl-pms-api'
|
|
$StampFile = Join-Path $OutDir '.stamp'
|
|
$BinPath = Join-Path $OutDir 'nl-pms-api'
|
|
|
|
if (-not (Test-Path $ApiRoot)) {
|
|
Write-Error "API dir not found: $ApiRoot (expected sibling of view)"
|
|
}
|
|
|
|
function Get-ApiFingerprint {
|
|
$files = @()
|
|
$files += Get-ChildItem -Path $ApiRoot -Filter 'go.mod' -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path $ApiRoot -Filter 'go.sum' -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path $ApiRoot -Filter 'main.go' -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path $ApiRoot -Filter 'init.sql' -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path $ApiRoot -Filter 'config.example.yaml' -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path (Join-Path $ApiRoot 'internal') -Recurse -Include *.go -File -ErrorAction SilentlyContinue
|
|
$files += Get-ChildItem -Path (Join-Path $ApiRoot 'migrations') -Recurse -Include *.sql -File -ErrorAction SilentlyContinue
|
|
$sha = [System.Security.Cryptography.SHA256]::Create()
|
|
$ms = New-Object System.IO.MemoryStream
|
|
foreach ($f in ($files | Sort-Object FullName)) {
|
|
$rel = $f.FullName.Substring($ApiRoot.Length).TrimStart('\', '/')
|
|
$bytes = [System.Text.Encoding]::UTF8.GetBytes($rel + "`n")
|
|
$ms.Write($bytes, 0, $bytes.Length)
|
|
$content = [System.IO.File]::ReadAllBytes($f.FullName)
|
|
$ms.Write($content, 0, $content.Length)
|
|
}
|
|
$hash = $sha.ComputeHash($ms.ToArray())
|
|
($hash | ForEach-Object { $_.ToString('x2') }) -join ''
|
|
}
|
|
|
|
$fp = Get-ApiFingerprint
|
|
$prev = ''
|
|
if (Test-Path $StampFile) { $prev = (Get-Content -Raw $StampFile).Trim() }
|
|
|
|
if (-not $Force -and $prev -eq $fp -and (Test-Path $BinPath)) {
|
|
Write-Host "api: up to date ($fp)"
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "api: packaging -> $OutDir"
|
|
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
|
|
$migOut = Join-Path $OutDir 'migrations'
|
|
New-Item -ItemType Directory -Force -Path $migOut | Out-Null
|
|
|
|
$prevGoos = $env:GOOS
|
|
$prevGoarch = $env:GOARCH
|
|
$prevCgo = $env:CGO_ENABLED
|
|
$env:CGO_ENABLED = '0'
|
|
$env:GOOS = 'linux'
|
|
$env:GOARCH = 'amd64'
|
|
Push-Location $ApiRoot
|
|
try {
|
|
& go build -trimpath -ldflags '-s -w' -o $BinPath .
|
|
if ($LASTEXITCODE -ne 0) { throw "go build failed: $LASTEXITCODE" }
|
|
} finally {
|
|
Pop-Location
|
|
if ($null -eq $prevGoos) { Remove-Item Env:GOOS -ErrorAction SilentlyContinue } else { $env:GOOS = $prevGoos }
|
|
if ($null -eq $prevGoarch) { Remove-Item Env:GOARCH -ErrorAction SilentlyContinue } else { $env:GOARCH = $prevGoarch }
|
|
if ($null -eq $prevCgo) { Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue } else { $env:CGO_ENABLED = $prevCgo }
|
|
}
|
|
|
|
Copy-Item -Force (Join-Path $ApiRoot 'init.sql') (Join-Path $OutDir 'init.sql')
|
|
Copy-Item -Force (Join-Path $ApiRoot 'config.example.yaml') (Join-Path $OutDir 'config.example.yaml')
|
|
Get-ChildItem -Path (Join-Path $ApiRoot 'migrations') -Filter '*.sql' -File -ErrorAction SilentlyContinue |
|
|
ForEach-Object { Copy-Item -Force $_.FullName (Join-Path $migOut $_.Name) }
|
|
|
|
# Must be linux ELF (not Windows PE). Magic: 7F 45 4C 46
|
|
$hdr = Get-Content -Path $BinPath -Encoding Byte -TotalCount 4
|
|
if ($hdr.Count -lt 4 -or $hdr[0] -ne 0x7F -or $hdr[1] -ne 0x45 -or $hdr[2] -ne 0x4C -or $hdr[3] -ne 0x46) {
|
|
Remove-Item -Force $BinPath -ErrorAction SilentlyContinue
|
|
throw "api binary is not linux ELF (GOOS=linux GOARCH=amd64 required). Got header: $($hdr -join ',')"
|
|
}
|
|
|
|
Set-Content -Path $StampFile -Value $fp -NoNewline
|
|
Write-Host "api: done linux/amd64 ELF -> $BinPath"
|