# README 多è¯è¨€åˆ‡æ¢è¡ŒåŒæ¥ä¸Žæ ¡éªŒ
#
# å•一事实æºï¼šreadme-languages.json。数组顺åºå³å±•示顺åºï¼Œå‰ä¸‰ä½å›ºå®šä¸º English(默认è½åœ°é¡µï¼‰ã€ç®€ä½“䏿–‡ï¼ˆåŒæƒå¨ï¼‰ä¸Žç¹é«”䏿–‡ã€‚
# å„ README åªæœ‰ <!-- lang:start --> 与 <!-- lang:end --> 之间的内容由本脚本生æˆï¼Œ
# å¹¶çœç•¥å½“å‰è¯ç§è‡ªèº«ï¼Œä¸Žæ–°è¯ç§è¿½åŠ åˆ°æœ«å°¾çš„çº¦å®šé…套。
#
# 用法:
# pwsh -File sync-readme-languages.ps1 # 按é…ç½®é‡å†™å„ README 的切æ¢å—
# pwsh -File sync-readme-languages.ps1 -Check # åªæ ¡éªŒä¸å†™å…¥ï¼Œä¸ä¸€è‡´é€€å‡ºç 1(CI 使用)
# pwsh -File sync-readme-languages.ps1 -Root D:\src\MyLib # ä¸‹æ¸¸åœ¨è‡ªå·±çš„ä»“æ ¹è¿è¡Œ
param(
[Switch]$Check,
[String]$Root = $PSScriptRoot,
[String]$Config = "readme-languages.json"
)
$ErrorActionPreference = "Stop"
$StartMarker = "<!-- lang:start -->"
$EndMarker = "<!-- lang:end -->"
$configPath = Join-Path $Root $Config
if (!(Test-Path -LiteralPath $configPath)) { throw "未找到è¯è¨€é…置:$configPath" }
$configData = Get-Content -LiteralPath $configPath -Raw -Encoding UTF8 | ConvertFrom-Json
$langs = @($configData.languages)
if ($langs.Count -eq 0) { throw "$Config 未é…置任何è¯ç§" }
$missing = @($langs | Where-Object { -not (Test-Path -Path (Join-Path $Root $_.file)) })
if ($missing.Count -gt 0) { throw "é…置的è¯ç§æ–‡ä»¶ä¸å˜åœ¨ï¼š$($missing.file -join ', ')" }
# 新增翻译若忘记登记,切æ¢è¡Œä¼šé™é»˜æ¼æŽ‰å®ƒï¼Œè¿™é‡Œç›´æŽ¥æ‹¦ä¸‹
$registered = @($langs.file)
$unregistered = @(Get-ChildItem -Path $Root -File | Where-Object { $_.Name -match '^(README|Readme)(\.[A-Za-z-]+)?\.md$' -and $_.Name -notmatch '\.nuget\.md$' -and $registered -notcontains $_.Name })
if ($unregistered.Count -gt 0) { throw "æ ¹ç›®å½•å˜åœ¨æœªç™»è®°çš„ README:$($unregistered.Name -join ', ')ï¼Œè¯·å…ˆåŠ å…¥ $Config" }
# ç”ŸæˆæŸä¸ª README 的切æ¢è¡Œï¼ˆçœç•¥è‡ªèº«ï¼‰
function Get-SwitcherLine($current) {
$parts = @()
foreach ($item in $langs) {
if ($item.file -eq $current.file) { continue }
$parts += "[$($item.name)]($($item.file))"
}
return "🌠" + ($parts -join " | ")
}
# æå–文件ä¸çŽ°æœ‰çš„åˆ‡æ¢å†…容,用于 -Check 的差异æç¤º
function Get-CurrentSwitcher($text, $pattern) {
$m = [regex]::Match($text, $pattern)
if (-not $m.Success) { return "<未找到切æ¢è¡Œ>" }
$lines = @($m.Value -split "`r?`n" | Where-Object { $_ -notlike '<!-- lang:*' })
return ($lines -join " / ")
}
$errors = 0
$changed = 0
foreach ($item in $langs) {
$path = Join-Path $Root $item.file
$text = [IO.File]::ReadAllText($path)
$line = Get-SwitcherLine $item
$newline = if ($text.Contains("`r`n")) { "`r`n" } else { "`n" }
$block = $StartMarker + $newline + $line + $newline + $EndMarker
if ($text.Contains($StartMarker) -and $text.Contains($EndMarker)) {
$pattern = "(?s)" + [regex]::Escape($StartMarker) + ".*?" + [regex]::Escape($EndMarker)
}
else {
# 首次è¿ç§»ï¼šç”¨æ ‡è®°å—包ä½åŽŸåˆ‡æ¢è¡Œ
$pattern = "(?m)^ðŸŒ[^\r\n]*"
if (-not [regex]::IsMatch($text, $pattern)) { throw "$($item.file) æ—¢æ— $StartMarker æ ‡è®°ï¼Œä¹Ÿæ‰¾ä¸åˆ° 🌠切æ¢è¡Œ" }
}
# æ›¿æ¢æ–‡æœ¬ä¸çš„ $ 需è¦è½¬ä¹‰ï¼Œé¿å…被当作æ£åˆ™æ›¿æ¢ç»„引用
$updated = [regex]::Replace($text, $pattern, $block.Replace('$', '$$'))
if ($updated -eq $text) { continue }
$changed++
if ($Check) {
$errors++
Write-Host "✗ $($item.file)"
Write-Host " 期望:$line"
Write-Host " 实际:$(Get-CurrentSwitcher $text $pattern)"
}
else {
[IO.File]::WriteAllText($path, $updated, (New-Object System.Text.UTF8Encoding($false)))
Write-Host "✓ $($item.file)"
}
}
if ($Check) {
if ($errors -gt 0) {
Write-Host "`nè¯è¨€åˆ‡æ¢è¡Œä¸ä¸€è‡´ï¼š$errors / $($langs.Count) 个文件。请è¿è¡Œ pwsh -File sync-readme-languages.ps1 åŽæäº¤ã€‚"
exit 1
}
Write-Host "è¯è¨€åˆ‡æ¢è¡Œä¸€è‡´ï¼ˆ$($langs.Count) 个è¯ç§ï¼‰"
}
elseif ($changed -eq 0) {
Write-Host "è¯è¨€åˆ‡æ¢è¡Œå·²æ˜¯æœ€æ–°ï¼ˆ$($langs.Count) 个è¯ç§ï¼‰"
}
|