refactor: 公共面补 BakNRet 前缀,产品名大小写全仓统一
16 个没有前缀的公共函数补上 BakNRet(Write-Log → Write-BakNRetLog、Resolve-BackupEntry → Resolve-BakNRetBackupEntry、Find-ChildDirectoryByName → Find-BakNRetChildDirectoryByName 等), 另外把全仓的 Baknret 统一成 BakNRet(47 个文件、940 处、65 个定义文件重命名)。 这不是审美问题:静态分析直接拓出一条实据 —— Write-Log 与本机某个已装模块导出的命令 **重名**(PSAvoidOverwritingBuiltInCmdlets),而重名的后果是导入两个模块时有一方的命令被 静默遮蔽。补前缀正是这条规则的解法,改名后它归零。 为什么敢做这个规模:PowerShell 的函数名解析大小写不敏感,所以 Baknret → BakNRet 在功能 上是零风险;真正要验证的是 16 个补前缀的调用点,而 276 个断言几乎覆盖了每个函数。另外 "名字与文件名一致"这条不变式有断言盯着(加载器点源的文件集合 vs 磁盘)。 踩到并记下的坑:Windows 文件系统大小写不敏感,所以**只改大小写**的重命名会被 Move-Item 当成同一个文件而静默跳过 —— 同一批里同时改了名字的那 16 个文件却成功了,于是"看起来能跑"。 最后用"先移到临时名、再移到目标名"的两步走解决,判断与替换全部改用显式大小写敏感的形式 (-creplace / -cmatch)。 顺带把名录指纹缓存从 MD5 换成 SHA256(PSAvoidUsingBrokenHashAlgorithms):它只是缓存键, 没有兼容负担。 验收:test.ps1 9/9 全绿(7 与 5.1)、100 个文件两版解析零错、276 个断言全过、 构建工具仍能合回单文件(3300 行)。
This commit is contained in:
1 parent
187d2759fd
commit
42f02d0eca
84 files changed
+1043
-1043
No files matched your search
@@ -101,7 +101,7 @@ function Get-SecurityFingerprint {
|
||||
return ('O={0} G={1} P={2} [{3}]' -f $acl.GetOwner($sid).Value, $acl.GetGroup($sid).Value, $acl.AreAccessRulesProtected, ($aces -join ' '))
|
||||
}
|
||||
|
||||
function Invoke-BaknretChild {
|
||||
function Invoke-BakNRetChild {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
用独立进程跑 Backup.ps1 / Restore.ps1(两个脚本结尾都会 exit)。
|
||||
@@ -190,7 +190,7 @@ function Remove-TreeHard {
|
||||
Where-Object { $_.Attributes -band [IO.FileAttributes]::ReparsePoint })
|
||||
foreach ($link in $links) {
|
||||
$null = Invoke-NativeTolerant -FilePath 'cmd.exe' -ArgumentList @('/c', ('rmdir "{0}"' -f $link.FullName))
|
||||
Remove-BaknretJunction -Path $link.FullName
|
||||
Remove-BakNRetJunction -Path $link.FullName
|
||||
}
|
||||
|
||||
$null = Invoke-NativeTolerant -FilePath 'cmd.exe' -ArgumentList @('/c', ('rmdir /s /q "{0}"' -f $Path))
|
||||
@@ -217,7 +217,7 @@ else {
|
||||
$BackupDir = Join-Path $WorkRoot 'backups'
|
||||
New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null
|
||||
|
||||
$privileges = Enable-BaknretPrivilege -Name @('SeRestorePrivilege', 'SeBackupPrivilege')
|
||||
$privileges = Enable-BakNRetPrivilege -Name @('SeRestorePrivilege', 'SeBackupPrivilege')
|
||||
if ($privileges.Missing.Count -gt 0) {
|
||||
Write-Host ('[acl] 警告:{0} 不在令牌里 —— 属主无法恢复,B 段会失败(应以管理员/SYSTEM 运行)' -f ($privileges.Missing -join '、')) -ForegroundColor Yellow
|
||||
}
|
||||
@@ -398,7 +398,7 @@ $configText = @"
|
||||
|
||||
Write-Host ''
|
||||
Write-Host '[备份] Backup.ps1' -ForegroundColor Yellow
|
||||
$backup = Invoke-BaknretChild -Script (Join-Path $RepoPath 'Backup.ps1') -Parameters @{
|
||||
$backup = Invoke-BakNRetChild -Script (Join-Path $RepoPath 'Backup.ps1') -Parameters @{
|
||||
BackupListPath = $listPath
|
||||
ConfigPath = $configPath
|
||||
BackupDir = $BackupDir
|
||||
@@ -420,7 +420,7 @@ Test-Scenario '源已删除(模拟真的丢了)' ($leftovers.Count -eq 0) ($
|
||||
|
||||
Write-Host ''
|
||||
Write-Host '[恢复] Restore.ps1' -ForegroundColor Yellow
|
||||
$restore = Invoke-BaknretChild -Script (Join-Path $RepoPath 'Restore.ps1') -Parameters @{
|
||||
$restore = Invoke-BakNRetChild -Script (Join-Path $RepoPath 'Restore.ps1') -Parameters @{
|
||||
BackupListPath = $listPath
|
||||
ConfigPath = $configPath
|
||||
BackupDir = $BackupDir
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
在 VM 内以 UTF-8 控制台编码运行一个测试套件(不改仓库里的任何测试代码)。
|
||||
|
||||
.DESCRIPTION
|
||||
为什么需要它 —— tests\BakNRet*.Tests.ps1 的 Invoke-BaknretScript 是这么抓子进程输出的:
|
||||
为什么需要它 —— tests\BakNRet*.Tests.ps1 的 Invoke-BakNRetScript 是这么抓子进程输出的:
|
||||
|
||||
cmd /c pwsh -File Backup.ps1 ... > out.txt 2>&1
|
||||
Get-Content -LiteralPath out.txt -Encoding UTF8
|
||||
|
||||
而 Backup.ps1 / Restore.ps1 的 Write-Log 走 Write-Host,写进 out.txt 的字节用的是
|
||||
而 Backup.ps1 / Restore.ps1 的 Write-BakNRetLog 走 Write-Host,写进 out.txt 的字节用的是
|
||||
`[Console]::OutputEncoding`:
|
||||
|
||||
* 宿主机上它是 utf-8 -> 文件是 UTF-8 -> 按 UTF-8 读回,中文正确,套件全绿;
|
||||
|
||||
Reference in new issue
Block a user