Files
BakNRet/docs/adr/0009-prefix-completion-is-single-level.md
Shuery 2446c7c5c7 docs: 把"前缀补全只搜一层、且不提供深度开关"写成决策记录
深度递归不是"补上一个没实现的功能",而是引入一个具体的错。写成 ADR-0009 连同实测数据:26 条真实 Path 里 19 条直接命中、3 条补全救不了(软件没装)、1 条(%UserProfile%\fnm)在 5 层内会命中 AppData\Local\fnm_multishells 这个临时目录 —— 静默备份错的东西还报成功。

同时在 Find-BakNRetChildDirectoryByName 的注释里指回 ADR,免得下一个人把它当"漏了的功能"补回去。

顺带修掉 README 里一句与实现不符的话:原先写"前缀补全命中多个候选(同名目录分散在多处)",而只搜一层时多个候选只可能来自同一个父目录(既有 X 又有 X_后缀)。

全仓复查:MaxDepth / CatalogMaxDepth / 最大深度 / 向下找几层 除 ADR-0009 的历史叙述外 0 处。

验收:test.ps1 9/9 全绿(7 与 5.1)。
2026-09-27 11:34:34 +08:00

41 lines
2.6 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.
# 前缀补全只搜一层,而且**不提供**"向下找几层"的开关
名录里的 `Path` 按字面不存在时,会做一次前缀补全:在同一父目录下找 `<名>_<后缀>` 或
`<名>-<后缀>` 形式的目录。这个过程**只看直接子目录**,并且刻意没有"最多向下几层"的参数。
历史上确实有过这样一个参数:`CatalogMaxDepth`(出厂值 5),从配置一路传到
`Resolve-BakNRetEntry` → `Get-BakNRetItemArchiveName` → `Get-BakNRetSoftwareCatalog` →
`Find-BakNRetChildDirectoryByName`。但它**从未被使用** —— 最后一个函数接下了参数,
实现里却只有 `Get-ChildItem -Directory`。也就是说那个配置项写多少都不影响行为。
2026-09 的改造把整条链路删掉了(配置项、三个函数的参数、70 处调用点实参)。理由不只是
"文档不该承诺代码不做的事",还有一条拿真实名录量出来的发现。
## 实测:让深度生效会让一个条目备份错目录
拿真实的 `SoftwareCatalog.psd1`(26 条 Path)逐条试"按字面存在吗 / 1 层能救吗 / 5 层能救吗":
| 情况 | 条数 | 说明 |
| --- | --- | --- |
| 直接命中 | 19 | —— |
| 补全救不了,无论几层 | 3 | `AutoDarkMode` / `dsh-desktop` / `twinkle-tray`:软件没装,报"源不存在"是对的 |
| **深度生效后会命中错的东西** | 1 | `%UserProfile%\fnm`:1 层内 0 个,**5 层内命中 `AppData\Local\fnm_multishells`** |
`fnm_multishells` 是 fnm 做 shell 集成用的**临时目录**,不是它的数据目录。所以如果那个参数
真的生效,`FastNodeManager` 会**静默备份错的东西并报告成功**;而今天它的行为是明确报
"源不存在" —— 一个可见的失败,胜过一个不可见的成功。
## 根因:那条判据只在"同一个父目录下"才成立
补全的判据是"下一个字符是 `_` 或 `-`"(`^<名>(_|-)`)。原作者在注释里写明了它的用意 ——
"避免把 Legendary 匹配成 LegendarySomething"。这个边界在**同一层**是保守的,但一旦允许
向下递归,它就会命中任意深度的"同名亲戚":`fnm` 与 `AppData\Local\fnm_multishells` 之间
隔着两层目录,判据对此毫无抵抗力。
## 所以
**不要重新加回深度参数。** 如果将来确实需要"路径变了也能找到",正确的顺序是先把判据收紧
(例如要求后缀像版本号:`^<名>[-_]\d`),并且把每次补全的事实打印出来
("我把 X 解析成了 Y"),让人看见它猜了什么 —— 而不是扩大搜索范围,因为搜索范围越大,
这种启发式越容易命中看起来对、其实不对的东西。