Commit Graph
2 Commits
Author SHA1 Message Date
Shuery e114cae8c8 P0-P3 全量重构:退出码 / 解析修复、manifest 与 7z t 校验、干跑、排除规则、日志、测试与计划任务
P0 正确性
- 退出码:改用 .NET Process 直接启动、让子进程继承控制台,不再用 Start-Process -PassThru
  (在 7.7.0-preview.4 上 ExitCode 恒为 $null,会把成功的压缩判成失败);
  7z / RAR / tar 三条解压分支统一走同一个取退出码的封装。
- BackupList 解析:先按第一个 :: 切段再处理引号(整行被一对引号包住的写法不再把排除表
  吞进路径);排除表同时接受 , 与 ;(旧实现只认 ;,导致排除从未生效);支持 :- / :+ / @flag。
- 补回 .ssh 与孤儿归档:.ssh 进清单;孤儿归档在备份端也做审计并点名;
  带 -Only / -Skip 时不再把未选中的归档误报成孤儿。
- Resolve-BackupEntry 里 $rootName 在赋值前被引用(会读到外层作用域残留值),已提前赋值。

P1 归档可靠性
- 每个条目写进 manifest.json:源、归档、时间、退出码、校验结果、失败原因,
  并区分 warnings(在位归档)与 attemptWarnings(本次尝试)。
- 归档后做 7z t 内容校验,先写 .tmp、校验通过再原子替换(File.Move overwrite)。
- manifest.roots 记录归档内**真实**的顶层条目名(原先记的是软件名,Edge 实际是 "User Data")。

P2 可用性
- Restore 支持 -WhatIf / -DryRun / -VerifyOnly / -Only / -Skip;
  这三种"只看不写"的模式一个字节都不写(原先会写回 manifest.json)。
- Edge 等高缓存条目加排除规则并实测:1781 MB / 27961 项 -> 72 MB / 2294 项;
  书签、密码、Cookies、偏好、历史、IndexedDB、Local Storage 全部保留。
  普通模式是相对归档根目录锚定的,嵌套的那些(如 OneAuth\WebView2 里的 Crashpad)
  改用 ! 组件形式才会命中。
- 日志落盘 logs/<backup|restore>-<时间戳>.log;退出码按失败数返回。
- tools/Register-BackupTask.ps1 注册每日计划任务;tools/Rename-Archives.ps1 迁移旧归档名。
- root= 标记此前静默失效,现在明确告警(该功能尚未实现)。

P3 测试与验证
- tests/BakNRet.Tests.ps1:Pester 5 套件 62 项(含用子进程跑 Backup.ps1 / Restore.ps1
  的端到端与针对上述缺陷的回归)。
- tests/Run-Pester.ps1 + tools/Install-TestDependencies.ps1:把 Pester 装到仓库内 .tools/,
  不动机器上的全局模块(系统自带的 3.4.0 缺 Should -Be)。
- tests/Restore-Drill.ps1:真实归档恢复演练,明确区分"源在备份后变过"与"归档/解压有问题"。
- tests/Run-Tests.ps1(49 项,零依赖)与 tests/Run-E2E.ps1(23 项)继续可用;三套共 134 项全通过。

真实机器验证
- 生产归档 22/22 通过 7z t;-VerifyOnly 不再改动 manifest.json(SHA256 前后一致)。
- 真实恢复演练 12/12 通过,27,670 个文件与活源逐字节一致。
- 修复了生产 scoop-persist.7z:原先只有 90 字节(空归档)而源有 1.3 GB,
  重打包后 233 MB,恢复演练 26981/26981 全部一致。
2026-09-21 23:02:47 +08:00
Shuery dbc0c00554 重构为可核对、可恢复的备份工具(P0-P3)
修复(P0)
- 退出码:改用 .NET Process 继承控制台启动外部命令。Start-Process -PassThru 的
  ExitCode 在 PowerShell 7.7.0-preview.4 上恒为 $null,会把成功的压缩判成失败,
  并让 "exit 2 -> 删档重试" 的自愈分支永远不可达。
- BackupList.txt 解析:先按第一个 :: 切开再处理引号,修正整行被引号包住时
  排除表被吞进路径的问题(该条目此前被静默跳过,其 2.8 GB 归档成了孤儿)。
- 排除分隔符同时接受 , 与 ;:此前解析器只认 ; 而清单里写的是 ,,
  等于所有排除规则都没生效。
- 7z 排除参数不再嵌引号,含空格的模式自动转成 ?:旧写法 -x!"路径" 会让引号
  成为模式的一部分,导致排除对所有条目都失效。

加固(P1)
- 先写临时归档 -> 7z t 校验 -> 原子替换,中断不再污染正式归档。
- 放弃 7z 的更新模式 u:固实压缩下收益极小,却让排除规则改动与已删文件
  永远进不了归档。
- 新增 Backups/manifest.json 与 logs/*.log,跳过/失败有据可查。
- 结尾按失败数 exit;恢复支持 -WhatIf / -DryRun / -VerifyOnly / -Only。
- 恢复优先用 manifest 定位归档,并精确比较 BaseName(不再用 -Filter 通配)。
- 修正 tar 分支用 $LASTEXITCODE 判断成功与否的缺陷。
- 有警告(文件被占用)时拒绝用不完整的归档覆盖完整归档,需显式 -AcceptWarnings。

策略与安全(P2)
- Edge 条目加排除规则:解压后 4.22 GB 中 3.79 GB 是可再生的缓存/遥测/扩展本体,
  保留书签、密码、偏好、历史与站点数据。
- 可选 7z 加密(@encrypt 标记或全局开关),取不到口令时明确失败,绝不写明文。
- 磁盘空间守卫:放不下就跳过该条目,低于阈值告警。

工程化(P3)
- 新增 BackupConfig.psd1、README.md、.gitignore。
- tests/Run-Tests.ps1(32 项)与 tests/Run-E2E.ps1(16 项端到端验收)。
- tools/Register-BackupTask.ps1 注册每日计划任务。
- 归档命名算法保持不变,已有归档不会失联。
2026-09-21 20:10:18 +08:00