From 8d4392ee5a2b363de2a217fafc3ceb2cdc51eb15 Mon Sep 17 00:00:00 2001 From: Brandon Zhang Date: Fri, 27 Mar 2026 18:06:52 +0800 Subject: [PATCH] Add Go rebuild helper script --- build-go-server.ps1 | 193 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 build-go-server.ps1 diff --git a/build-go-server.ps1 b/build-go-server.ps1 new file mode 100644 index 0000000..2dd1fb7 --- /dev/null +++ b/build-go-server.ps1 @@ -0,0 +1,193 @@ +<# +.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" + +