fix: 让 5.1 真正可用(显式编码 + 原生 stderr 处理 + .psd1 夹具带 BOM)
上一提交让 5.1 能解析源码,但 Unit 与 Smoke 在 5.1 上仍然是红的。根因是三类彼此 无关的 5.1/7 行为差,全部实测确认: 1) 不写 -Encoding 时,5.1 的 Get-Content / Set-Content 默认是 ANSI,7 是 UTF-8。 症状是 UTF-8 字节被按 GBK 解出「璇存槑」这类乱码。62 处补上显式 -Encoding UTF8。 用 AST 而不是正则定位,避免把注释里的散文也改掉。 2) .psd1 夹具用无 BOM 写,而引擎的 .psd1 读取器(Import-PowerShellDataFile)只能靠 BOM 判断编码、没有参数可传,于是 5.1 按 ANSI 解。40 处夹具改为带 BOM 写 —— 这正是 .editorconfig 里 [*.psd1] charset = utf-8-bom 本来就要求的,是夹具违反了自己的约定。 .cmd 批次文件刻意保持无 BOM:cmd.exe 会被 BOM 弄坏。 3) 5.1 在 $ErrorActionPreference = Stop 下会把原生命令写到 stderr 的内容升级成终止性 NativeCommandError,7 改了这条。takeown/icacls 的 ACL 复位调用、以及 test.ps1 自己 调子进程的地方,都需要在 Continue 下跑。 验收:test.ps1 9/9 全绿(Encode + Parse + Unit + Smoke + E2E,在 7 与 5.1 上各跑一遍)。 已知未处理(留待后续提交):tools/lab/** 里还有若干「原生命令 + 2>&1 + Stop」的同类 写法(takeown / icacls / scoop / code / Get-WimInfo)。它们要 Hyper-V 实验机才跑得到, 不在验收门槛内。
This commit is contained in:
1 parent
2d26f78d15
commit
e10503be76
13 files changed
+122
-104
No files matched your search
@@ -79,7 +79,7 @@ BeforeAll {
|
||||
|
||||
function Write-ListFile {
|
||||
param([Parameter(Mandatory = $true)][string]$Path, [Parameter(Mandatory = $true)][string]$Content)
|
||||
[System.IO.File]::WriteAllText($Path, $Content, [System.Text.UTF8Encoding]::new($false))
|
||||
[System.IO.File]::WriteAllText($Path, $Content, [System.Text.UTF8Encoding]::new($true))
|
||||
return $Path
|
||||
}
|
||||
}
|
||||
@@ -102,18 +102,18 @@ Describe '软件名录:Slot 形状(新契约)' {
|
||||
$script:DirB = Join-Path $script:FormatRoot 'dirB'
|
||||
foreach ($directory in $script:DirA, $script:DirB) {
|
||||
New-Item -ItemType Directory -Path $directory -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $directory 'keep.txt') "keep-$directory"
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $directory 'keep.txt') "keep-$directory"
|
||||
}
|
||||
New-Item -ItemType Directory -Path (Join-Path $script:DirA 'Cache') -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $script:DirA 'Cache\c.bin') 'cache'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:DirA 'Cache\c.bin') 'cache'
|
||||
$script:CfgFile = Join-Path $script:FormatRoot 'settings.json'
|
||||
Set-Content -LiteralPath $script:CfgFile '{"a":1}'
|
||||
Set-Content -Encoding UTF8 -LiteralPath $script:CfgFile '{"a":1}'
|
||||
|
||||
# 两个不同父目录下各有一个**同名**子目录 —— 供"归档内同名"冲突测试用
|
||||
$script:CollideRoot = Join-Path $script:FormatRoot 'collide'
|
||||
foreach ($parent in 'p1', 'p2') {
|
||||
New-Item -ItemType Directory -Path (Join-Path $script:CollideRoot "$parent\dupdir") -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $script:CollideRoot "$parent\dupdir\x.txt") $parent
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:CollideRoot "$parent\dupdir\x.txt") $parent
|
||||
}
|
||||
|
||||
$script:MissingDir = Join-Path $script:FormatRoot 'not-here'
|
||||
@@ -324,12 +324,12 @@ Describe '集成:Slot 布局的打包与恢复' -Skip:(-not ($script:HasSevenZ
|
||||
New-Item -ItemType Directory -Path $script:SlotCfgDir -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $script:SlotInclude -Force | Out-Null
|
||||
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotAppOne 'one.txt') 'one'
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotAppOne 'sub\deep.txt') 'deep'
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotAppOne 'Cache\c.bin') 'cache'
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotAppTwo 'two.txt') 'two'
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotCfgDir 'settings.json') '{"a":1}'
|
||||
Set-Content -LiteralPath (Join-Path $script:SlotInclude 'mod.txt') 'mod'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppOne 'one.txt') 'one'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppOne 'sub\deep.txt') 'deep'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppOne 'Cache\c.bin') 'cache'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppTwo 'two.txt') 'two'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotCfgDir 'settings.json') '{"a":1}'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotInclude 'mod.txt') 'mod'
|
||||
|
||||
$appOne = $script:SlotAppOne
|
||||
$appTwo = $script:SlotAppTwo
|
||||
@@ -388,7 +388,7 @@ Describe '集成:Slot 布局的打包与恢复' -Skip:(-not ($script:HasSevenZ
|
||||
Test-Path -LiteralPath (Join-Path $verify 'Extra\two.txt') | Should -BeTrue
|
||||
Test-Path -LiteralPath (Join-Path $verify 'Modules\mod.txt') | Should -BeTrue
|
||||
Test-Path -LiteralPath (Join-Path $verify 'Cfg') -PathType Leaf | Should -BeTrue
|
||||
(Get-Content -LiteralPath (Join-Path $verify 'Cfg') -Raw).Trim() | Should -Be '{"a":1}'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $verify 'Cfg') -Raw).Trim() | Should -Be '{"a":1}'
|
||||
}
|
||||
|
||||
It '真实恢复:目录 Slot、文件 Slot 与 Include 都落回各自的原位' {
|
||||
@@ -404,10 +404,10 @@ Describe '集成:Slot 布局的打包与恢复' -Skip:(-not ($script:HasSevenZ
|
||||
$run.ExitCode | Should -Be 0
|
||||
$run.Output | Should -Match '恢复成功: appkit'
|
||||
|
||||
(Get-Content -LiteralPath (Join-Path $script:SlotAppOne 'one.txt') -Raw).Trim() | Should -Be 'one'
|
||||
(Get-Content -LiteralPath (Join-Path $script:SlotAppOne 'sub\deep.txt') -Raw).Trim() | Should -Be 'deep'
|
||||
(Get-Content -LiteralPath (Join-Path $script:SlotAppTwo 'two.txt') -Raw).Trim() | Should -Be 'two'
|
||||
(Get-Content -LiteralPath (Join-Path $script:SlotInclude 'mod.txt') -Raw).Trim() | Should -Be 'mod'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppOne 'one.txt') -Raw).Trim() | Should -Be 'one'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppOne 'sub\deep.txt') -Raw).Trim() | Should -Be 'deep'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotAppTwo 'two.txt') -Raw).Trim() | Should -Be 'two'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SlotInclude 'mod.txt') -Raw).Trim() | Should -Be 'mod'
|
||||
|
||||
# 被 Slot 排除的缓存没有进过归档,自然也不会被恢复出来
|
||||
Test-Path -LiteralPath (Join-Path $script:SlotAppOne 'Cache\c.bin') | Should -BeFalse
|
||||
@@ -417,7 +417,7 @@ Describe '集成:Slot 布局的打包与恢复' -Skip:(-not ($script:HasSevenZ
|
||||
# 目标文件被删掉了,名录解析只能得到 IsFile=false;判据要靠 manifest 的 layouts。
|
||||
$restored = Join-Path $script:SlotCfgDir 'settings.json'
|
||||
(Test-Path -LiteralPath $restored -PathType Leaf) | Should -BeTrue
|
||||
(Get-Content -LiteralPath $restored -Raw).Trim() | Should -Be '{"a":1}'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath $restored -Raw).Trim() | Should -Be '{"a":1}'
|
||||
}
|
||||
|
||||
It '恢复之后 manifest 记下 lastRestoreAt' {
|
||||
@@ -440,7 +440,7 @@ Describe '集成:旧布局归档的回退恢复' -Skip:(-not ($script:HasSeven
|
||||
$script:LegacyLeaf = 'My Code Space'
|
||||
New-Item -ItemType Directory -Path (Join-Path $script:LegacyHolder $script:LegacyLeaf) -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $script:LegacyDestParent -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $script:LegacyHolder "$script:LegacyLeaf\legacy.txt") 'old-layout'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:LegacyHolder "$script:LegacyLeaf\legacy.txt") 'old-layout'
|
||||
|
||||
$destPath = Join-Path $script:LegacyDestParent $script:LegacyLeaf
|
||||
$script:LegacyCatalog = Write-ListFile -Path (Join-Path $script:LegacyRoot 'cat.psd1') -Content @"
|
||||
@@ -480,7 +480,7 @@ Describe '集成:旧布局归档的回退恢复' -Skip:(-not ($script:HasSeven
|
||||
$run.ExitCode | Should -Be 0
|
||||
$run.Output | Should -Match '按旧布局回退'
|
||||
Test-Path -LiteralPath (Join-Path $script:LegacyDestParent "$script:LegacyLeaf\legacy.txt") | Should -BeTrue
|
||||
(Get-Content -LiteralPath (Join-Path $script:LegacyDestParent "$script:LegacyLeaf\legacy.txt") -Raw).Trim() | Should -Be 'old-layout'
|
||||
(Get-Content -Encoding UTF8 -LiteralPath (Join-Path $script:LegacyDestParent "$script:LegacyLeaf\legacy.txt") -Raw).Trim() | Should -Be 'old-layout'
|
||||
}
|
||||
|
||||
It '归档里既没有 Slot 层、也没有旧布局名字时明确失败(不再"成功地什么都没恢复")' {
|
||||
@@ -513,7 +513,7 @@ Describe '集成:归档内路径冲突会被拒绝执行' -Skip:(-not ($script
|
||||
$p2 = Join-Path $script:RejectRoot 'p2\dupdir'
|
||||
foreach ($directory in $p1, $p2) {
|
||||
New-Item -ItemType Directory -Path $directory -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $directory 'x.txt') 'x'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $directory 'x.txt') 'x'
|
||||
}
|
||||
# Slot 叫 Data,Include 也要放进包内的 Data -> 同一个位置,必须报错
|
||||
Write-ListFile -Path $script:RejectCatalog -Content "@{`n 'collide' = @{ Data = @{ Path = '$p1' } }`n}`n" | Out-Null
|
||||
@@ -556,7 +556,7 @@ Describe '条目从清单里消失后,旧归档必须被点名为孤儿' -Skip
|
||||
$script:OrphanRoot = Join-Path $script:Sandbox 'orphan-e2e'
|
||||
$script:OrphanSource = Join-Path $script:OrphanRoot 'src\My App'
|
||||
New-Item -ItemType Directory -Path $script:OrphanSource -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $script:OrphanSource 'data.txt') 'hello'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:OrphanSource 'data.txt') 'hello'
|
||||
|
||||
$script:OrphanCatalog = Write-ListFile -Path (Join-Path $script:OrphanRoot 'cat.psd1') `
|
||||
-Content "@{ 'my-app' = @{ Default = @{ Path = '$script:OrphanSource' } } }`n"
|
||||
@@ -606,7 +606,7 @@ Describe 'manifest 一致性:archive 字段只在文件真的存在时才写'
|
||||
BeforeAll {
|
||||
$script:SyncRoot = Join-Path $script:Sandbox 'sync'
|
||||
New-Item -ItemType Directory -Path $script:SyncRoot -Force | Out-Null
|
||||
Set-Content -LiteralPath (Join-Path $script:SyncRoot 'real.7z') 'x'
|
||||
Set-Content -Encoding UTF8 -LiteralPath (Join-Path $script:SyncRoot 'real.7z') 'x'
|
||||
|
||||
$script:SyncManifestPath = Join-Path $script:SyncRoot 'manifest.json'
|
||||
$manifest = Read-BaknretManifest -Path $script:SyncManifestPath
|
||||
|
||||
Reference in new issue
Block a user