fix: 源文件改存 UTF-8 with BOM,让 Windows PowerShell 5.1 真正可用
改造前:全仓 6/6 个源文件在 5.1 上解析失败(README 却承诺支持 5.1)。原因是文件是无 BOM 的 UTF-8,而 5.1 没有 BOM 就按 ANSI 代码页解码源码,中文变乱码、全角问号吃掉引号,整块语法塌掉。 现在 28/28 个文件在 5.1 与 7 上都解析零错误,E2E 36 项在 5.1 上全绿。 顺带修掉一个被 5.1 掩盖的缺陷:带 [CmdletBinding()] 的脚本在 5.1 上,param() 默认值里 拿不到 $PSScriptRoot(实测为空串,7 上正常)。于是 Backup.ps1 / Restore.ps1 在 5.1 上不传 路径参数就报错退出 —— 而计划任务恰恰不传。E2E 之所以看不见,是因为它总是显式传路径。 8 处默认值全部移到 param() 之后的解析段,沿用本仓库对 -BackupDir 一直在用的写法。 新增三条可重放的约定,让编码不再是一次性动作: .gitattributes 接管行尾(本机 core.autocrlf=true,会把工作区改成 CRLF 制造伪 diff) .editorconfig 用 charset = utf-8-bom 锁住 BOM tools\Set-SourceEncoding.ps1 是规范化脚本,tools\Invoke-* 之外的任何改动之后都能重放 test.ps1 是唯一验收入口:Encode + Parse + Unit + Smoke + E2E,在 7 与 5.1 上各跑一遍 test.ps1 的 Encode 层直接检查"必须有 BOM"这条规则。加它的原因很实际:实测本仓库用的 编辑工具在保存时会悄悄去掉 BOM,而丢了 BOM 的文件只在 5.1 上出错、在 7 上完全正常, 没有这条检查就会一直漏过去。 已知未修(下一步处理):5.1 上 Unit 有 6 项、Smoke 有 1 项失败,全部源于测试夹具写 临时文件时没指定编码(5.1 的 Set-Content 默认 ANSI),与产品代码无关。
This commit is contained in:
1 parent
dda36cfae5
commit
2d26f78d15
24 files changed
+457
-28
No files matched your search
@@ -0,0 +1,79 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
把受管文本文件规范成仓库约定的编码:UTF-8 with BOM、LF 行尾。
|
||||
|
||||
.DESCRIPTION
|
||||
为什么需要一个可重放的脚本,而不是"改一次就完了":
|
||||
|
||||
* Windows PowerShell 5.1 在没有 BOM 时会按 ANSI 代码页解码源码文件,
|
||||
中文变乱码,而全角问号之类的字节序列会吃掉字符串引号、整块语法失效。
|
||||
* 但很多编辑器与工具在保存时会**悄悄去掉 BOM**。实测本仓库用的编辑工具就会
|
||||
(改过一次 test.ps1 之后它只在 5.1 上解析失败,在 7 上完全正常,极其隐蔽)。
|
||||
* 所以"加过 BOM"必须是一次能在任何改动之后重放的规范化操作。
|
||||
|
||||
受管范围与 .editorconfig 一致:
|
||||
* *.ps1 / *.psm1 / *.psd1 —— PowerShell 引擎直接读取,必须有 BOM
|
||||
* BackupList.txt —— 被 Get-Content 读取,必须有 BOM
|
||||
|
||||
只做两件事:补 BOM、把 CRLF 归一成 LF。不动缩进、不动内容、不换编码以外的东西。
|
||||
文件按 UTF-8 解码:本仓库的所有文本文件都是 UTF-8(见 .editorconfig)。
|
||||
|
||||
.PARAMETER WhatIf
|
||||
只报告将要改动什么,不写任何文件。
|
||||
|
||||
.EXAMPLE
|
||||
.\tools\Set-SourceEncoding.ps1 -WhatIf
|
||||
|
||||
.EXAMPLE
|
||||
.\tools\Set-SourceEncoding.ps1
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess = $true)]
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||||
|
||||
$excluded = '\\(\.git|\.tools|Backups|logs|dist|snapshots)\\'
|
||||
$targets = @(Get-ChildItem -LiteralPath $projectRoot -Recurse -File |
|
||||
Where-Object { $_.Extension -in '.ps1', '.psm1', '.psd1' -or $_.Name -eq 'BackupList.txt' } |
|
||||
Where-Object { $_.FullName -notmatch $excluded })
|
||||
|
||||
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
||||
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
||||
|
||||
$addedBom = @()
|
||||
$normalizedLf = @()
|
||||
|
||||
foreach ($file in $targets) {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($file.FullName)
|
||||
$hasBom = $bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF
|
||||
$text = if ($hasBom) { $utf8NoBom.GetString($bytes, 3, $bytes.Length - 3) } else { $utf8NoBom.GetString($bytes) }
|
||||
|
||||
$normalized = ($text -split "`r?`n") -join "`n"
|
||||
$needsWrite = (-not $hasBom) -or ($normalized -ne $text)
|
||||
|
||||
if (-not $hasBom) { $addedBom += $file.FullName.Substring($projectRoot.Length).TrimStart('\') }
|
||||
if ($normalized -ne $text) { $normalizedLf += $file.FullName.Substring($projectRoot.Length).TrimStart('\') }
|
||||
|
||||
if ($needsWrite -and $PSCmdlet.ShouldProcess($file.FullName, '规范成 UTF-8 with BOM 与 LF')) {
|
||||
[System.IO.File]::WriteAllText($file.FullName, $normalized, $utf8Bom)
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host ("受管文件 {0} 个" -f $targets.Count)
|
||||
if ($addedBom.Count -gt 0) {
|
||||
Write-Host ("补上 BOM {0} 个:" -f $addedBom.Count) -ForegroundColor Yellow
|
||||
$addedBom | ForEach-Object { Write-Host " $_" }
|
||||
} else {
|
||||
Write-Host '所有文件都已经带 BOM。' -ForegroundColor Green
|
||||
}
|
||||
if ($normalizedLf.Count -gt 0) {
|
||||
Write-Host ("行尾归一成 LF {0} 个:" -f $normalizedLf.Count) -ForegroundColor Yellow
|
||||
$normalizedLf | ForEach-Object { Write-Host " $_" }
|
||||
}
|
||||
|
||||
if (-not $WhatIfPreference) {
|
||||
Write-Host ''
|
||||
Write-Host '下一步:.\test.ps1 -Suite Parse 确认两个版本都能解析。' -ForegroundColor Cyan
|
||||
}
|
||||
Reference in new issue
Block a user