param( [Parameter(Mandatory = $true)][string]$EnvPath, [Parameter(Mandatory = $true)][string]$ProjectRoot ) $ErrorActionPreference = "Stop" $migrationsDir = if ([string]::IsNullOrWhiteSpace($env:UPDATE_ENV_MIGRATIONS_DIR)) { Join-Path $ProjectRoot "scripts\update-env.d" } else { $env:UPDATE_ENV_MIGRATIONS_DIR } if (-not (Test-Path $EnvPath -PathType Leaf)) { throw "环境配置文件不存在: $EnvPath" } if (-not (Test-Path $migrationsDir -PathType Container)) { Write-Host "ℹ️ 未发现环境配置迁移目录,跳过" return } function Get-EnvValue { param([string]$Path, [string]$Key) foreach ($line in [System.IO.File]::ReadAllLines($Path)) { if ($line.StartsWith("$Key=")) { return $line.Substring($Key.Length + 1).Trim().Trim('"').Trim("'") } } return "" } function Set-EnvValue { param([string]$Path, [string]$Key, [string]$Value) $output = New-Object System.Collections.Generic.List[string] $replaced = $false foreach ($line in [System.IO.File]::ReadAllLines($Path)) { if ($line.StartsWith("$Key=")) { if (-not $replaced) { $output.Add("$Key=$Value") $replaced = $true } } else { $output.Add($line) } } if (-not $replaced) { $output.Add("$Key=$Value") } [System.IO.File]::WriteAllLines($Path, $output, (New-Object System.Text.UTF8Encoding($false))) } function Set-EnvDefault { param([string]$Key, [string]$Value) if (-not [string]::IsNullOrWhiteSpace((Get-EnvValue -Path $EnvPath -Key $Key))) { return } Set-EnvValue -Path $EnvPath -Key $Key -Value $Value Write-Host " ✓ 已补充环境配置: $Key" } function Add-EnvListItem { param([string]$Key, [string]$Item) $current = Get-EnvValue -Path $EnvPath -Key $Key $items = @($current.Split(',') | ForEach-Object { $_.Trim() } | Where-Object { $_ }) if ($items -contains $Item) { return } $next = if ($items.Count -eq 0) { $Item } else { (@($items) + $Item) -join ',' } Set-EnvValue -Path $EnvPath -Key $Key -Value $next Write-Host " ✓ 已补充环境配置项: $Key" } $manifests = @(Get-ChildItem -Path $migrationsDir -Filter "*.env" -File | Sort-Object Name) if ($manifests.Count -eq 0) { Write-Host "ℹ️ 未发现环境配置迁移文件,跳过" return } foreach ($manifest in $manifests) { $lineNumber = 0 foreach ($rawLine in [System.IO.File]::ReadAllLines($manifest.FullName)) { $lineNumber++ $line = $rawLine.TrimEnd("`r") if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith('#')) { continue } if ($line -match '^@skip-if\s+[A-Z][A-Z0-9_]*=.+$') { continue } if ($line -notmatch '^[A-Z][A-Z0-9_]*(\+)?=.+$') { throw "无效的环境配置迁移: $($manifest.FullName):$lineNumber" } } } foreach ($manifest in $manifests) { $skipManifest = $false foreach ($rawLine in [System.IO.File]::ReadAllLines($manifest.FullName)) { $line = $rawLine.TrimEnd("`r") if ($line -match '^@skip-if\s+([A-Z][A-Z0-9_]*)=(.+)$') { if ((Get-EnvValue -Path $EnvPath -Key $Matches[1]) -eq $Matches[2]) { Write-Host "ℹ️ 保留现有更新模式,跳过环境配置迁移: $($manifest.Name)" $skipManifest = $true break } } } if ($skipManifest) { continue } Write-Host "📝 应用环境配置迁移: $($manifest.Name)" foreach ($rawLine in [System.IO.File]::ReadAllLines($manifest.FullName)) { $line = $rawLine.TrimEnd("`r") if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith('#')) { continue } if ($line.StartsWith('@skip-if')) { continue } if ($line.Contains('+=')) { $parts = $line.Split(@('+='), 2, [System.StringSplitOptions]::None) Add-EnvListItem -Key $parts[0] -Item $parts[1] } else { $parts = $line.Split(@('='), 2, [System.StringSplitOptions]::None) Set-EnvDefault -Key $parts[0] -Value $parts[1] } } }