feat(criteria): 文件名不得是"句子里的一段" —— 我为**自己制造的**那个化石加守
## 我制造了什么(本会话 `34bcd3e9` 那轮,实测复现) ``` 我在 bash 里写了一句带嵌套未转义双引号 + 裸 `>` 的说明: echo " ⇒ 所以"mtime > 动作时刻是**必要但不充分**,且会被**后人无关的写**覆盖"" bash 把 `>` 读成**重定向** ⇒ **在仓库根建了一个文件**: 文件名 = `动作时刻是**必要但不充分**,且会被**后人无关的写**覆盖` 内容 = ` ⇒ 所以mtime`(18 字节) ⇒ 我在检查工作树时看到 `?? "动作时刻是…"` 才发现的。 用 /tmp 里的最小复现验证到**同名同内容** ⇒ 确认是我的 shell 引号事故,不是别人的。 ``` ## 为什么值得一条判据(它会被提交) ``` · 未跟踪文件**不会**被普通 `git add <path>` 带上 ⇒ 平时看不见、不会被门禁提醒; · 但本仓**明文记录过 `git add -A` 事故**(`docs/DEV-TOOLING.md`: 含把约 7000 行重排扫进功能提交那次) ⇒ 下一次 `-A` 就会把这个"句子文件"带进历史,而**进了历史就永远删不干净**; · 它的**名字本身就说明它是无意的** —— 没有人的文件名会是"…且会被**后人无关的写**覆盖"。 ``` ## 判据(零先例实测 ⇒ 不误伤) ``` 仓库内(排除 node_modules/.git/build/release/dist/.hvigor/.codegraph/oh_modules) 不得有名字含**中文标点**(,。、!?;:()「」“”《》【】)、**markdown 粗体 `**`**、或**换行**的文件 ★ 判**名字的形态**,不判目录 —— 按目录裁豁免正是本仓记过的"给逃逸指路"。 实测先例: 加这条之前全仓命中 **0**(根目录 0、全仓 0)⇒ 不误伤任何现存文件。 ``` ## 双向变异 ``` ① 重建那个句子文件名 ⇒ **not ok 10**,逐个点名 ✓(上面就是它抓到的输出) ② 删掉 ⇒ 10/10 绿 ✓ ``` ## 顺带 ``` run-all.mjs 注册条数 9 → **10**(新增 test 必须登记精确条数,本仓约定) ``` ★ 这条与我这轮前两条(`fc54a81` 两处排除、`b16c38a` "提到≠发现路径")是**同一族**: **"看起来像在表达一件事"的东西被当成了"它就是那件事"** —— 前两条在判据的**匹配口径**里,这条在**文件名**上(一段散文被当成了路径)。 验证: criteria-hygiene 10/10;drift 自检 64/0;两文件 `node --check` 通过; 现场: 探针已删(`git status` 只剩本提交的两个文件)。
This commit is contained in:
@ -869,3 +869,58 @@ test('★ ⑤b 的负向清单在 JS 与 shell 两处都有副本,两份都必
|
||||
+ ' 而 `redeploy-gateway.sh` **没有** ⇒ 只守前者的话,删掉/写漂 shell 那份不会红,\n'
|
||||
+ ' 而 shell 那份是**部署当时打印 `ok` 行**所用的文本。');
|
||||
});
|
||||
|
||||
/*
|
||||
* ★★ 仓库里不得有"**句子里的一段**"当文件名(shell 引号事故的化石)。
|
||||
*
|
||||
* ## 为什么存在(我 `34bcd3e9` 那轮亲手制造了一个)
|
||||
*
|
||||
* 我在 bash 里写了一句带**嵌套未转义双引号 + 裸 `>`** 的说明文本,形状是:
|
||||
* echo " ⇒ 所以"mtime > 动作时刻是**必要但不充分**,且会被…覆盖""
|
||||
* bash 把 `>` 读成**重定向** ⇒ **在仓库根建了一个文件**,文件名是那句话的后半截
|
||||
* (`动作时刻是**必要但不充分**,且会被**后人无关的写**覆盖`),内容是我 echo 的前半截。
|
||||
* 实测复现: 同名同内容(`⇒ 所以mtime`,18 字节)。
|
||||
*
|
||||
* ## 为什么值得一条判据(不是我手滑,是它会**被提交**)
|
||||
*
|
||||
* · 未跟踪文件**不会**被普通 `git add <path>` 带上 ⇒ 平时看不见;
|
||||
* · 但本仓**明文记录过三次 `git add -A` 事故**(`docs/DEV-TOOLING.md`,含把 7000 行
|
||||
* 重排扫进功能提交那次)⇒ 下一次 `-A` 就会把这个"句子文件"带进历史,
|
||||
* 而它**永远删不干净**(进了历史就得改写)。
|
||||
* · 它的**名字本身就说明它是无意的** —— 人的文件名不会是"…且会被**后人无关的写**覆盖"。
|
||||
*
|
||||
* ## 判据(零先例实测 ⇒ 不误伤)
|
||||
*
|
||||
* 仓库内(排除忽略目录)**不得有**名字含中文标点、markdown 粗体标记、或换行的文件。
|
||||
* 实测: 加上这条之前,全仓命中 **0**(根目录 0、全仓 0)⇒ 收紧不误伤任何现存文件。
|
||||
* ★ 判的是**名字**(形态),不判"哪个目录" —— 按目录裁豁免正是本仓记过的"给逃逸指路"。
|
||||
*/
|
||||
test('★ 文件名不得是"句子里的一段"(shell 引号事故的化石;含中文标点/粗体标记)', () => {
|
||||
// 忽略目录:构建产物与依赖,它们的名字不受本判据约束
|
||||
const SKIP = new Set(['node_modules', '.git', 'build', 'release', 'dist', '.hvigor', '.codegraph', 'oh_modules']);
|
||||
const PUNCT = ',。、!?;:()「」“”《》【】';
|
||||
|
||||
const bad = [];
|
||||
const walk = (dir) => {
|
||||
let entries;
|
||||
try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
||||
for (const e of entries) {
|
||||
if (SKIP.has(e.name)) continue;
|
||||
const full = join(dir, e.name);
|
||||
if ([...PUNCT].some((c) => e.name.includes(c)) || e.name.includes('**') || e.name.includes('\n')) {
|
||||
bad.push(relative(REPO_ROOT, full));
|
||||
}
|
||||
if (e.isDirectory()) walk(full);
|
||||
}
|
||||
};
|
||||
walk(REPO_ROOT);
|
||||
|
||||
assert.deepEqual(bad, [],
|
||||
`这些**文件名是"句子里的一段"** —— 几乎必然是一次 shell 引号事故留下的化石:\n`
|
||||
+ ` ${bad.join('\n ')}\n`
|
||||
+ ' ⇒ 常见成因: `echo "…"某词 > 后半句"` —— 嵌套未转义双引号让 `>` 变成**重定向**,\n'
|
||||
+ ' bash 于是在该目录**新建一个文件**,名字是那句话的后半截。\n'
|
||||
+ ' ⇒ 处置: 删掉它;并把说明文本改用 `printf \'%s\\n\'` 或单引号包裹(避免 `>` 被解析)。\n'
|
||||
+ ' ⚠️ 为什么必须现在删: 未跟踪文件普通 `git add <path>` 带不上,**但它会被 `git add -A` 带上** ——\n'
|
||||
+ ' 而本仓已记录过三次 `-A` 事故;一旦进了历史,这个名字就永远在那儿了。');
|
||||
});
|
||||
|
||||
@ -138,7 +138,7 @@ const SUITE = [
|
||||
['test/commit-hygiene.test.mjs', ['--experimental-strip-types', '--no-warnings'], 4],
|
||||
// 判据目录自身的卫生:读文本必须走 test/lib/read.mjs 的具名入口;
|
||||
// 非门禁工具必须有**发现路径**;⑤b 负向清单两处副本都要点名同一对失败类
|
||||
['test/criteria-hygiene.test.mjs', [], 9],
|
||||
['test/criteria-hygiene.test.mjs', [], 10],
|
||||
// 用户管理页(P4c 同批):动作↔服务端调用同名 / 门禁只认严格 admin /
|
||||
// 启停只发 status / 「受限」徽标口径 / 页面零写死色值 / 接线(纯逻辑真被调用)
|
||||
['test/harmony-admin.test.mjs', ['--experimental-strip-types', '--no-warnings'], 31],
|
||||
|
||||
Reference in New Issue
Block a user