hotfix(v3.0.10): Base64 '-or' 括号 bug + dry-run 实跑验证护栏
v3.0.9 Base64 脚本启动即报:
Test-Path: A parameter cannot be found that matches parameter name 'or'.
claude.exe not found
根因: 'Test-Path (Join-Path $p claude.ps1) -or (Test-Path ...)' 中 -or
被当成 Test-Path 的命名参数. PSParser 静态检查看合法, 运行时炸.
修复:
F1: 括号修正 — $hasClaude 抽为独立变量, 三元 -or 每项带外括号
F2: gen-launcher-bats.ps1 强制加 dry-run 实跑验证护栏
解码后的 Base64 脚本必须被 pwsh -File 实跑到底部 __BW_DRYRUN_OK__
才算通过. 检查 ErrorRecord / ParameterBindingException / 未知命令.
任何未来 Base64 改动都被此验证拦截.
验证层级教训:
PSParser = 抓语法 / 抓不到参数绑定错
dry-run = 抓运行时 / 抓不到业务逻辑
smoke = 抓业务 / 需要前两层通过
EXE 220160 → 220672 bytes (+512)
This commit is contained in:
parent
a3b4ff3a78
commit
609e82bac0
@ -48,7 +48,7 @@ trap {
|
||||
}
|
||||
|
||||
# ─── 版本号 (每次更新递增, build.ps1 自动读取) ──────
|
||||
$BWVersion = "3.0.9" # 根治: Claude 装完固化 npm prefix 到 User PATH + Base64 三层 PATH + 快捷方式前 claude 自验证
|
||||
$BWVersion = "3.0.10" # hotfix: Base64 脚本 -or 括号导致 Test-Path 参数错 (gen-launcher-bats 加实跑 dry-run 防护)
|
||||
|
||||
# DryRun 模式日志标记
|
||||
if ($DryRun) { $global:BWDryRun = $DryRun } else { $global:BWDryRun = $null }
|
||||
|
||||
@ -29,7 +29,9 @@ $npmCandidates = @(
|
||||
"$env:LOCALAPPDATA\npm"
|
||||
)
|
||||
foreach ($p in $npmCandidates) {
|
||||
if ((Test-Path $p) -and (Test-Path (Join-Path $p 'claude.ps1') -or (Test-Path (Join-Path $p 'claude.cmd'))) -and ($env:Path -notlike "*$p*")) {
|
||||
if (-not (Test-Path $p)) { continue }
|
||||
$hasClaude = (Test-Path (Join-Path $p 'claude.ps1')) -or (Test-Path (Join-Path $p 'claude.cmd')) -or (Test-Path (Join-Path $p 'claude'))
|
||||
if ($hasClaude -and ($env:Path -notlike "*$p*")) {
|
||||
$env:Path = "$p;$env:Path"
|
||||
}
|
||||
}
|
||||
@ -175,9 +177,42 @@ if %errorlevel% neq 0 (
|
||||
Write-Host "[gen-launcher-bats] ✓ 启动Bookworm.bat ($((Get-Item $launchBat).Length) bytes)" -ForegroundColor Green
|
||||
Write-Host "[gen-launcher-bats] ✓ 更新并启动Bookworm.bat ($((Get-Item $updateBat).Length) bytes)" -ForegroundColor Green
|
||||
|
||||
# ─── Round-trip 验证 ─────────────────────────────────────
|
||||
# ─── Round-trip 验证 (v3.0.10: 除了 PARSE 还要 lint + 实跑不启动 claude) ────
|
||||
$decoded = [System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($enc))
|
||||
$err = $null
|
||||
[void][System.Management.Automation.Language.Parser]::ParseInput($decoded, [ref]$null, [ref]$err)
|
||||
if ($err) { throw "解码后脚本 PARSE ERR: $($err[0])" }
|
||||
Write-Host "[gen-launcher-bats] ✓ Round-trip PARSE OK ($($decoded.Length) chars)" -ForegroundColor Green
|
||||
Write-Host "[gen-launcher-bats] ✓ PARSE OK ($($decoded.Length) chars)" -ForegroundColor Green
|
||||
|
||||
# 实跑验证 (v3.0.10: 截断到 & claude 之前, 只跑 PATH 修复 + DPAPI 加载, 不启动 claude)
|
||||
# 这能抓出 PARSE 通过但运行时报错的 bug (例如 -or 被当 Test-Path 参数)
|
||||
$runnable = $decoded -replace '& claude --dangerously-skip-permissions', 'Write-Host "__BW_DRYRUN_OK__"'
|
||||
$tmpPs1 = Join-Path $env:TEMP "bw-launcher-dryrun-$(Get-Random).ps1"
|
||||
Set-Content -Path $tmpPs1 -Value $runnable -Encoding UTF8
|
||||
try {
|
||||
$dryRunOutput = (& pwsh -NoProfile -ExecutionPolicy Bypass -File $tmpPs1 2>&1 | Out-String)
|
||||
# 只抓真正的 PS 错误 (ErrorRecord / cannot be found / parameter name / 等)
|
||||
$errorPatterns = @(
|
||||
'cannot be found that matches parameter name',
|
||||
'A parameter cannot be found',
|
||||
'CommandNotFoundException',
|
||||
'ParameterBindingException',
|
||||
'is not recognized as',
|
||||
'cannot find.*because it does not exist',
|
||||
'RuntimeException'
|
||||
)
|
||||
$hasError = $false
|
||||
foreach ($pat in $errorPatterns) {
|
||||
if ($dryRunOutput -match $pat) { $hasError = $true; break }
|
||||
}
|
||||
# 必须看到 dry-run 成功标记才算通过
|
||||
$reachedEnd = $dryRunOutput -match '__BW_DRYRUN_OK__'
|
||||
if ($hasError -or -not $reachedEnd) {
|
||||
Write-Host "[gen-launcher-bats] ✗ 实跑验证失败:" -ForegroundColor Red
|
||||
Write-Host $dryRunOutput -ForegroundColor DarkRed
|
||||
throw "Base64 解码后脚本运行时错误 (hasError=$hasError, reachedEnd=$reachedEnd)"
|
||||
}
|
||||
Write-Host "[gen-launcher-bats] ✓ 实跑通过 (dry-run 到达 __BW_DRYRUN_OK__ 标记)" -ForegroundColor Green
|
||||
} finally {
|
||||
Remove-Item $tmpPs1 -Force -EA SilentlyContinue
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user