Files
BakNRet/docs/adr/0013-tui-writes-config-surgically.md
Shuery 60f2ae3e0f docs: TUI 与入口重组的设计记录(4 条 ADR + 验收锚点)
grilling 三轮把设计树走完了,这里把它落成文件,避免决策只活在对话里。

ADR-0010 零依赖自研 TUI:三个候选库全部实测排除 —— ConsoleGuiTools 的 PSGallery 元数据声明最低 7.2(5.1 装不上);Spectre.Console 0.49.1 能在 5.1 加载但要塞 4 个第三方 DLL 且不支持鼠标;Terminal.Gui 1.15.0 能反射接线到真的渲染出窗口,但 Application.Shutdown() 在两端都抛 NRE。同时记下两条实测坑:无控制台时 $Host.UI.SupportsVirtualTerminal 会撒谎返回 True(第一道闸门必须是 [Console]::IsOutputRedirected),以及 5.1 的 RawUI.LengthInBufferCells 对中文返回 2、对边框字符返回 6(都不能用来排版)。

ADR-0011 进度回调这个例外:它是注入点不是状态,无头路径为 $null 时行为与今天完全一致。

ADR-0012 入口改名与垫片:这次留垫片而 Common.psm1 直接删,是因为前者是外部接口(断了是静默没用)后者是内部实现(断了当场报错)。并纠正了自己的一个伪前提 —— 本机实测没有注册任何 BakNRet 计划任务。

ADR-0013 TUI 写配置:外科式改写 + 校验通过才原子替换。硬事实是 SoftwareCatalog.psd1 根本不能被 Import-PowerShellDataFile 读入(动态表达式),任何"解析成对象再序列化"的方案都会毁掉表达式与注释。

.scratch/tui/spec.md 是这次改造的验收锚点:9 条已定决策 + 三轮的判据 + 风险表。

验收:Parse 两版仍绿。
2026-09-27 15:27:01 +08:00

33 lines
2.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TUI 写配置:外科式改写,校验通过才原子替换
三个配置文件都含**无法往返**的内容:
- `SoftwareCatalog.psd1` 里有 `$(if ($env:SCOOP_GLOBAL) { ... } else { ... })\persist` 这类动态
表达式、`$(scoop prefix translucenttb)\settings.json`,以及**跨行字符串拼接**的 `Exclude`。
`Import-PowerShellDataFile` **实测读不了这个文件**(报 "cannot generate a PowerShell object
for a ScriptBlock evaluating dynamic expressions")。
- `BackupList.txt` 与 `BackupConfig.psd1` 里的注释**本身就是文档**(记录每个开关的取舍)。
所以任何"解析成对象 → 改 → 重新序列化"的方案都会把它们毁掉。做法:
1. **只改写被编辑的那一行/那一块**,其余逐字节保持;
2. 写临时文件 → 用模块自己的读取器解析 + 语义校验(清单逐行 `ConvertFrom-BackupListLine`、
配置的类型与取值、名录的展开与 `Test-Path`);
3. **只有全过才调用已有的 `Write-BaknretAtomicText` 替换**;不过就**拒绝保存**并把原文错误打出来。
这条让 TUI 编辑器从"方便"升级为"**比手改更安全**"——手改没有校验,而它有。
## 可编辑面按"能不能安全往返"来定
| 文件 | 模型 | 可编辑 |
| --- | --- | --- |
| `BackupList.txt` | 行编辑器(复用已有 token 解析器) | 方向 / 目标 / 覆盖 / 排除 / 追加 / 加密 / 键值 / 说明 |
| `BackupConfig.psd1` | 扁平表单 | 目录、阈值、开关及其合法取值 |
| `SoftwareCatalog.psd1` | 树 + 只读字段 | **只有 `Encrypt` 与 `Description`**;`Path`/`Exclude`/`Include` 显示为只读并提示用文本编辑器 |
## 两条配套约定
- 每次保存前把原文件按时间戳复制到 `logs/config-backups/`(已 gitignore,不污染仓库)。
- 每个编辑器带一条**往返断言**:解析 → 改一个字段 → 写回 → 重新解析,**除目标字段外逐字段相等,
且注释行数不变**。没有这条断言,TUI 编辑器就是"看起来能保存"的典型。