feat: configure startup ports from local config (#30)
This commit is contained in:
@@ -81,6 +81,43 @@ function Read-DatabaseConfig {
|
||||
}
|
||||
}
|
||||
|
||||
function Read-PortConfig {
|
||||
param([string]$Path)
|
||||
|
||||
$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 }
|
||||
}
|
||||
|
||||
function Resolve-MySqlClient {
|
||||
$services = Get-CimInstance Win32_Service -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -match '^MySQL' -and $_.State -eq 'Running' }
|
||||
@@ -115,6 +152,7 @@ try {
|
||||
}
|
||||
$ConfigPath = [IO.Path]::GetFullPath($ConfigPath)
|
||||
$databaseConfig = Read-DatabaseConfig $ConfigPath
|
||||
$portConfig = Read-PortConfig $ConfigPath
|
||||
|
||||
if (-not $PSBoundParameters.ContainsKey('DatabaseHost')) {
|
||||
$DatabaseHost = $databaseConfig.Host
|
||||
@@ -133,8 +171,9 @@ try {
|
||||
Write-Host "GoAuto local server" -ForegroundColor Cyan
|
||||
Write-Host "Config: $ConfigPath"
|
||||
Write-Host "MySQL: ${DatabaseUser}@${DatabaseHost}:${DatabasePort}/${DatabaseName}"
|
||||
Write-Host "Ports: server=$($portConfig.Server), web=$($portConfig.Web)"
|
||||
if ($ValidateConfigOnly) {
|
||||
Write-Host "Local database configuration is valid." -ForegroundColor Green
|
||||
Write-Host "Local database and port configuration is valid." -ForegroundColor Green
|
||||
return
|
||||
}
|
||||
|
||||
@@ -159,6 +198,7 @@ try {
|
||||
|
||||
$env:GOAUTO_DB_DRIVER = "mysql"
|
||||
$env:GOAUTO_DB_DSN = "${DatabaseUser}:${plainPassword}@tcp(${DatabaseHost}:${DatabasePort})/${DatabaseName}?charset=utf8mb4&parseTime=True&loc=Local&timeout=5s"
|
||||
$env:GOAUTO_SERVER_PORT = [string]$portConfig.Server
|
||||
|
||||
Push-Location $serverDirectory
|
||||
try {
|
||||
@@ -185,8 +225,8 @@ try {
|
||||
}
|
||||
|
||||
Write-Host "[3/3] Starting server..." -ForegroundColor Green
|
||||
Write-Host "Local URL: http://127.0.0.1:8000"
|
||||
Write-Host "Android URL: use this computer's LAN IP on port 8000"
|
||||
Write-Host "Local URL: http://127.0.0.1:$($portConfig.Server)"
|
||||
Write-Host "Android URL: use this computer's LAN IP on port $($portConfig.Server)"
|
||||
Write-Host "Press Ctrl+C to stop." -ForegroundColor DarkYellow
|
||||
& go run . server -c config/settings.yml
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
@@ -201,5 +241,6 @@ finally {
|
||||
Remove-Item Env:MYSQL_PWD -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:GOAUTO_DB_DSN -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:GOAUTO_DB_DRIVER -ErrorAction SilentlyContinue
|
||||
Remove-Item Env:GOAUTO_SERVER_PORT -ErrorAction SilentlyContinue
|
||||
$plainPassword = $null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$ConfigPath,
|
||||
[switch]$ValidateConfigOnly
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$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
|
||||
}
|
||||
Reference in New Issue
Block a user