You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
3.9 KiB
76 lines
3.9 KiB
[CmdletBinding()]
|
|
param(
|
|
[string]$EnvFile = '.env',
|
|
[switch]$SkipBuild,
|
|
[switch]$CheckOnly
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
# 仅载入此脚本允许的配置名,不把 .env 当成可执行脚本。
|
|
$examplePath = Join-Path $PSScriptRoot '.env.example'
|
|
$allowedNames = @{}
|
|
foreach ($line in Get-Content -LiteralPath $examplePath -Encoding UTF8) {
|
|
if ($line -match '^([A-Z][A-Z0-9_]*)=') { $allowedNames[$Matches[1]] = $true }
|
|
}
|
|
$envPath = if ([IO.Path]::IsPathRooted($EnvFile)) { $EnvFile } else { Join-Path $PSScriptRoot $EnvFile }
|
|
if (-not (Test-Path -LiteralPath $envPath -PathType Leaf)) {
|
|
throw '缺少本地 .env;请从 .env.example 复制到 .env 并填写,不要覆盖现有文件。'
|
|
}
|
|
$settings = @{}
|
|
foreach ($line in Get-Content -LiteralPath $envPath -Encoding UTF8) {
|
|
if ([string]::IsNullOrWhiteSpace($line) -or $line.TrimStart().StartsWith('#')) { continue }
|
|
if ($line -notmatch '^([A-Z][A-Z0-9_]*)=(.*)$') { throw '环境文件格式错误:请使用 KEY=value,不使用 export 或引号。' }
|
|
$settingName = $Matches[1]
|
|
$settingValue = $Matches[2]
|
|
if (-not $allowedNames.ContainsKey($settingName)) { throw "环境文件包含未知配置名:$settingName" }
|
|
if ($settings.ContainsKey($settingName)) { throw "环境文件包含重复配置名:$settingName" }
|
|
if ($settingValue -match '^["'']' -or $settingValue -match '\s#' -or $settingValue.Contains('$')) {
|
|
throw "配置 $settingName 必须使用未加引号的单行原文,不能包含变量引用或行尾注释。"
|
|
}
|
|
$settings[$settingName] = $settingValue
|
|
}
|
|
foreach ($requiredName in @('DB_PASSWORD','MYSQL_ROOT_PASSWORD','REDIS_PASSWORD','RABBITMQ_PASSWORD','JWT_SECRET')) {
|
|
if (-not $settings.ContainsKey($requiredName) -or [string]::IsNullOrWhiteSpace($settings[$requiredName]) -or $settings[$requiredName].StartsWith('replace-me-')) {
|
|
throw "请为 $requiredName 设置自己的非示例值。"
|
|
}
|
|
}
|
|
if ([Text.Encoding]::UTF8.GetByteCount($settings['JWT_SECRET']) -lt 32) { throw 'JWT_SECRET 至少需要 32 字节。' }
|
|
if ($CheckOnly) {
|
|
Write-Host '本地配置格式与必填项检查通过(未连接任何服务、未构建或启动)。'
|
|
return
|
|
}
|
|
|
|
$savedEnvironment = @{}
|
|
foreach ($settingName in $allowedNames.Keys) {
|
|
$savedEnvironment[$settingName] = [Environment]::GetEnvironmentVariable($settingName, 'Process')
|
|
}
|
|
Push-Location $PSScriptRoot
|
|
try {
|
|
# 清除继承的同名云凭据,只接受该 .env 中填写的值;空项回落到模板的占位值。
|
|
foreach ($settingName in $allowedNames.Keys) {
|
|
$settingValue = if ($settings.ContainsKey($settingName) -and $settings[$settingName] -ne '') { $settings[$settingName] } else { $null }
|
|
if ($null -eq $settingValue) {
|
|
Remove-Item -LiteralPath "Env:$settingName" -ErrorAction SilentlyContinue
|
|
} else {
|
|
[Environment]::SetEnvironmentVariable($settingName, $settingValue, 'Process')
|
|
}
|
|
}
|
|
if (-not $SkipBuild) {
|
|
& mvn -Pportable clean verify
|
|
if ($LASTEXITCODE -ne 0) { throw '构建或测试失败,未启动后端。' }
|
|
}
|
|
$jarPath = Join-Path $PSScriptRoot 'target/portable/campus-server-1.0.0.jar'
|
|
if (-not (Test-Path -LiteralPath $jarPath -PathType Leaf)) { throw '缺少 portable JAR,请先执行 mvn -Pportable clean verify。' }
|
|
$configPath = (Join-Path $PSScriptRoot 'src/main/resources/application.example.yml').Replace('\', '/')
|
|
& java -Duser.timezone=GMT+08 -jar $jarPath "--spring.config.location=file:$configPath"
|
|
if ($LASTEXITCODE -ne 0) { throw '后端退出异常,请检查启动日志。' }
|
|
} finally {
|
|
foreach ($settingName in $allowedNames.Keys) {
|
|
if ($null -eq $savedEnvironment[$settingName]) {
|
|
Remove-Item -LiteralPath "Env:$settingName" -ErrorAction SilentlyContinue
|
|
} else {
|
|
[Environment]::SetEnvironmentVariable($settingName, $savedEnvironment[$settingName], 'Process')
|
|
}
|
|
}
|
|
Pop-Location
|
|
}
|
|
|