Files
goauto/scripts/start-web.ps1
T
QiuSWandClaude Opus 5 72ecf25291 fix(#48): find config.yaml from server/ and stop diagnostics looking like errors
The startup log proved config.yaml was not being found during migrate.
Lookup covered the working directory and the executable's directory, but
the server runs from server/ while config.yaml sits at the repository
root — so it was found only when a launcher happened to export
GOAUTO_CONFIG. Anyone running `go run .` by hand got no local config at
all. Search the parent directory too, with the working directory still
winning.

The diagnostics also wrote to stderr, and the launcher pipes the server
through `2>&1 | Tee-Object`, which turns every stderr write into a
PowerShell NativeCommandError. The informational line I added to make
this debuggable was itself rendering as a red error block. They go to
stdout now.

Launchers set the console to UTF-8: Go writes UTF-8 while the console
decodes as the ANSI code page, which turned every Chinese log line into
mojibake.

Verified by running the built binary from server/ with no GOAUTO_CONFIG
set: it loads ../config.yaml and the lines survive 2>/dev/null.

Not verified: the two PowerShell edits, which need a Windows run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:44:03 +08:00

111 lines
3.6 KiB
PowerShell

[CmdletBinding()]
param(
[string]$ConfigPath,
[switch]$ValidateConfigOnly
)
$ErrorActionPreference = "Stop"
# Go 进程输出 UTF-8。不显式设定的话,中文日志会按控制台的 ANSI 代码页(简中为
# GBK)解码,显示成乱码——见 #48 启动日志。
try { [Console]::OutputEncoding = [Text.Encoding]::UTF8 } catch { }
$workspaceRoot = Split-Path -Parent $PSScriptRoot
$webDirectory = Join-Path $workspaceRoot "web"
function ConvertFrom-YamlScalar {
param([string]$Value)
$value = $Value.Trim()
if ($value.Length -ge 2) {
if ($value.StartsWith('"') -and $value.EndsWith('"')) {
return $value.Substring(1, $value.Length - 2).Replace('\"', '"').Replace('\\', '\')
}
if ($value.StartsWith("'") -and $value.EndsWith("'")) {
return $value.Substring(1, $value.Length - 2).Replace("''", "'")
}
}
return $value
}
function Read-PortConfig {
param([string]$Path)
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
throw "Local configuration file was not found: $Path. Copy config.example.yaml to config.yaml."
}
$values = @{}
$insidePorts = $false
foreach ($line in Get-Content -LiteralPath $Path) {
if ($line -match '^\s*(#.*)?$') {
continue
}
if ($line -match '^ports\s*:\s*$') {
$insidePorts = $true
continue
}
if ($insidePorts -and $line -match '^\S') {
break
}
if ($insidePorts -and $line -match '^\s+(server|web)\s*:\s*(.*?)\s*$') {
$values[$Matches[1]] = ConvertFrom-YamlScalar $Matches[2]
}
}
foreach ($key in 'server', 'web') {
$parsedPort = 0
if (-not $values.ContainsKey($key) -or
-not [int]::TryParse([string]$values[$key], [ref]$parsedPort) -or
$parsedPort -lt 1 -or $parsedPort -gt 65535) {
throw "ports.$key must be an integer between 1 and 65535 in: $Path"
}
$values[$key] = $parsedPort
}
if ($values.server -eq $values.web) {
throw "ports.server and ports.web must be different in: $Path"
}
return @{ Server = [int]$values.server; Web = [int]$values.web }
}
if ([string]::IsNullOrWhiteSpace($ConfigPath)) {
$ConfigPath = Join-Path $workspaceRoot "config.yaml"
}
elseif (-not [IO.Path]::IsPathRooted($ConfigPath)) {
$ConfigPath = Join-Path $workspaceRoot $ConfigPath
}
$ConfigPath = [IO.Path]::GetFullPath($ConfigPath)
$ports = Read-PortConfig $ConfigPath
Write-Host "GoAuto web UI" -ForegroundColor Cyan
Write-Host "Config: $ConfigPath"
Write-Host "Ports: server=$($ports.Server), web=$($ports.Web)"
if ($ValidateConfigOnly) {
Write-Host "Local port configuration is valid." -ForegroundColor Green
return
}
$pnpm = Get-Command pnpm.cmd -ErrorAction SilentlyContinue
if (-not $pnpm) {
throw "pnpm was not found. Install pnpm and try again."
}
Push-Location $webDirectory
try {
if (-not (Test-Path -LiteralPath "node_modules" -PathType Container)) {
Write-Host "Installing frontend dependencies..." -ForegroundColor Cyan
& $pnpm.Source install --frozen-lockfile
if ($LASTEXITCODE -ne 0) {
throw "Frontend dependency installation failed."
}
}
$env:VUE_APP_BASE_API = "http://127.0.0.1:$($ports.Server)"
Write-Host "Starting GoAuto web UI at http://127.0.0.1:$($ports.Web)" -ForegroundColor Green
& $pnpm.Source exec vite --host 127.0.0.1 --port $ports.Web --strictPort
if ($LASTEXITCODE -ne 0) {
throw "Frontend exited with code $LASTEXITCODE."
}
}
finally {
Remove-Item Env:VUE_APP_BASE_API -ErrorAction SilentlyContinue
Pop-Location
}