Files
local-mcp/build-go-server.ps1
2026-03-27 18:06:52 +08:00

194 lines
6.2 KiB
PowerShell

<#
.SYNOPSIS
Rebuilds the Go local-mcp binary from the repository root.
.DESCRIPTION
This script:
1. Detects and stops any running Go local-mcp server processes.
2. Copies root static assets into go-server\static for //go:embed.
3. Removes any previous build outputs.
4. Builds a fresh Go binary.
5. Removes the temporary go-server\static copy.
6. Moves the new binary into the repository root.
7. Restarts the Go server only if one was running before the rebuild.
If go-server\static already exists, it is backed up and restored after the
build so the workspace is not left dirty just from executing this script.
.USAGE
.\build-go-server.ps1
#>
[CmdletBinding()]
param()
$ErrorActionPreference = "Stop"
$RootDir = $PSScriptRoot
$GoServerDir = Join-Path $RootDir "go-server"
$RootStaticDir = Join-Path $RootDir "static"
$GoStaticDir = Join-Path $GoServerDir "static"
$RootBinaryPath = Join-Path $RootDir "local-mcp.exe"
$BuildBinaryPath = Join-Path $GoServerDir "local-mcp.exe"
$StdoutLogPath = Join-Path $GoServerDir "server.stdout.log"
$StderrLogPath = Join-Path $GoServerDir "server.stderr.log"
$StaticBackupDir = Join-Path ([System.IO.Path]::GetTempPath()) ("local-mcp-go-static-" + [guid]::NewGuid().ToString("N"))
function Write-Step([string]$Message, [string]$Color = "Cyan") {
Write-Host $Message -ForegroundColor $Color
}
function Get-NormalizedPath([string]$Path) {
return [System.IO.Path]::GetFullPath($Path).TrimEnd('\\').ToLowerInvariant()
}
function Get-GoServerProcesses {
$candidatePaths = @(
(Get-NormalizedPath $RootBinaryPath),
(Get-NormalizedPath $BuildBinaryPath)
)
$processes = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
Where-Object {
$_.Name -ieq 'local-mcp.exe' -and $_.ExecutablePath -and ($candidatePaths -contains (Get-NormalizedPath $_.ExecutablePath))
}
return @($processes)
}
function Stop-GoServerProcesses([array]$Processes) {
foreach ($proc in $Processes) {
Write-Step ("Stopping Go server PID {0} ({1})" -f $proc.ProcessId, $proc.ExecutablePath) "Yellow"
Stop-Process -Id $proc.ProcessId -Force -ErrorAction Stop
}
if ($Processes.Count -gt 0) {
Start-Sleep -Seconds 1
}
}
function Remove-BinaryIfPresent([string]$Path, [string]$Label) {
if (-not (Test-Path $Path)) {
return
}
try {
Write-Step "Removing existing $Label."
Remove-Item -Path $Path -Force
return
}
catch {
$lockingProcesses = Get-GoServerProcesses | Where-Object {
$_.ExecutablePath -and ((Get-NormalizedPath $_.ExecutablePath) -eq (Get-NormalizedPath $Path))
}
if ($lockingProcesses.Count -eq 0) {
throw
}
$script:wasRunning = $true
Write-Step "Detected locked $Label; stopping matching Go server process(es) and retrying." "Yellow"
Stop-GoServerProcesses -Processes $lockingProcesses
Remove-Item -Path $Path -Force
}
}
function Start-GoServer {
if (-not (Test-Path $RootBinaryPath)) {
throw "Cannot restart Go server because the rebuilt binary was not found at $RootBinaryPath"
}
$timestamp = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [build-go-server.ps1] ---- starting rebuilt Go server ----"
Add-Content -Path $StdoutLogPath -Value $timestamp
Add-Content -Path $StderrLogPath -Value $timestamp
$proc = Start-Process `
-FilePath $RootBinaryPath `
-WorkingDirectory $RootDir `
-RedirectStandardOutput $StdoutLogPath `
-RedirectStandardError $StderrLogPath `
-WindowStyle Hidden `
-PassThru
Write-Step ("Restarted Go server with PID {0}" -f $proc.Id) "Green"
}
if (-not (Test-Path $GoServerDir)) {
throw "Go server directory not found: $GoServerDir"
}
if (-not (Test-Path $RootStaticDir)) {
throw "Root static directory not found: $RootStaticDir"
}
$runningProcesses = Get-GoServerProcesses
$wasRunning = $runningProcesses.Count -gt 0
$backedUpExistingStatic = $false
$buildSucceeded = $false
try {
if ($wasRunning) {
Write-Step "Detected running Go server process(es); stopping them before rebuild."
Stop-GoServerProcesses -Processes $runningProcesses
} else {
Write-Step "No running Go server processes found."
}
if (Test-Path $GoStaticDir) {
Write-Step "Backing up existing go-server\\static before staging build assets."
Move-Item -Path $GoStaticDir -Destination $StaticBackupDir
$backedUpExistingStatic = $true
}
Write-Step "Copying root static assets into go-server\\static for the Go build."
Copy-Item -Path $RootStaticDir -Destination $GoStaticDir -Recurse
Remove-BinaryIfPresent -Path $RootBinaryPath -Label "root binary"
Remove-BinaryIfPresent -Path $BuildBinaryPath -Label "Go build output"
Write-Step "Building Go binary from go-server..."
Push-Location $GoServerDir
try {
& go build -o $BuildBinaryPath .
}
finally {
Pop-Location
}
if (-not (Test-Path $BuildBinaryPath)) {
throw "Go build completed without producing $BuildBinaryPath"
}
Write-Step "Build succeeded; removing staged go-server\\static copy."
Remove-Item -Path $GoStaticDir -Recurse -Force -ErrorAction SilentlyContinue
Write-Step "Moving rebuilt binary into repository root."
Move-Item -Path $BuildBinaryPath -Destination $RootBinaryPath -Force
$buildSucceeded = $true
if ($wasRunning) {
Write-Step "Restarting Go server with rebuilt binary."
Start-GoServer
} else {
Write-Step "Go server was not running before rebuild; leaving it stopped." "Green"
}
}
finally {
if (Test-Path $GoStaticDir) {
Remove-Item -Path $GoStaticDir -Recurse -Force -ErrorAction SilentlyContinue
}
if ($backedUpExistingStatic -and (Test-Path $StaticBackupDir)) {
Move-Item -Path $StaticBackupDir -Destination $GoStaticDir -Force
}
if ((-not $buildSucceeded) -and (Test-Path $BuildBinaryPath)) {
Remove-Item -Path $BuildBinaryPath -Force -ErrorAction SilentlyContinue
}
}
Write-Step "Go build workflow completed successfully." "Green"