feat(T1): S11 代码注释禁用词规则落闸——先落规则再见红(89 处)
按契约 6 先写 S11 规则并跑出红,为 T2–T6 批量换代提供回归网。 词表从术语表「退役词对照」节解析+显式追加完美排雷、排除巢穴/旗。 三层豁免(闸门自指/显式留档 4 处/非注释面天然不取)+两道自检。
This commit is contained in:
1 parent
f230bde1c3
commit
85dce2c77d
2 files changed
+121
-2
No files matched your search
@@ -15,7 +15,7 @@ tests/
|
||||
smoke/ # critical-paths.md——人工 gate 清单(/smoke-check 读取)
|
||||
evidence/ # 截图与人工签核记录
|
||||
run_all.gd # 单元套件统一入口(套件 manifest 协议,D2 AC-2b)
|
||||
static_scan.sh # 静态扫描域 S1–S8 可执行子集
|
||||
static_scan.sh # 静态扫描域 S1–S11 可执行子集
|
||||
```
|
||||
|
||||
## 测试三层与承载目录
|
||||
@@ -109,9 +109,11 @@ timeout 120s godot --headless --script tests/run_all.gd
|
||||
|
||||
## Static Scan(提交前本地跑)
|
||||
|
||||
`tests/static_scan.sh` 实现静态扫描域 S1–S8 的可执行子集;规则全集与动机见
|
||||
`tests/static_scan.sh` 实现静态扫描域 S1–S11 的可执行子集;规则全集与动机见
|
||||
`design/engineering/architecture/architecture.md`「测试与质量域」节。新违规案例必须**先补扫描规则再修码**。
|
||||
|
||||
S11 代码注释禁用词:扫描 game/ 全域 .gd/.tres/.md/.json/.sh 的注释面,词表从 `design/gdd/术语表.md`「退役词对照」解析(显式追加「完美排雷」,排除「巢穴」「旗」);三层豁免(闸门自指/显式留档 4 处/非注释面天然不取);两道自检(扫描面文件数非空+词表解析非空)。
|
||||
|
||||
## 本地闸(唯一验收门禁)
|
||||
|
||||
本仓库无远端、无 CI——**验收只在本地发生**,跑 `tools/run_all_gates.sh` 是收口唯一入口,按本批改动域选档(`--code`/`--docs`/跨两域或改闸件本身=不带参数全量),
|
||||
|
||||
@@ -93,4 +93,121 @@ fi
|
||||
# S7 B2/B3/B4 API 符号命中文件 ⊆ B1 文件集(编排唯一性)
|
||||
# S8 结算路径 await 零命中(B1 结算/编排文件集)
|
||||
|
||||
# ── S11 — 代码注释禁用词 ──
|
||||
# 禁「板级」「门票」「正主」「落籍」「完美排雷」等退役词进注释面(完整词表见术语表解析)
|
||||
# 权威出处:design/gdd/术语表.md「退役词对照」节+「对外命名纪律」节
|
||||
# 扫描面:game/ 全域 .gd/.tres/.md/.json/.sh(.txt 不收=第三方许可证非本仓库文本)
|
||||
# 词表来源:解析「退役词对照」第一列(去括号注、斜杠拆分)+显式追加「完美排雷」;显式排除「巢穴」(玩家专名/风味层,术语表自带除外注)、「旗」(单字误报率高,doc_term_audit 判例)
|
||||
# 注释文本提取:.gd/.sh 取 # 后文本;.tres 取 ; 后文本;.md 取整行;.json 无注释语法(保留扩展名但不产生注释段)
|
||||
# 三层豁免依序:①闸门自指(行内含检查/禁令形态即跳过)②显式留档豁免单 4 处 ③非注释面天然不取
|
||||
|
||||
if [ -d game/core ]; then
|
||||
S11_TABLE="design/gdd/术语表.md"
|
||||
S11_FAIL_LOCAL=0
|
||||
|
||||
if [ ! -f "$S11_TABLE" ]; then
|
||||
echo "[static_scan] S11 FAIL: 术语表文件不存在($S11_TABLE)"
|
||||
S11_FAIL_LOCAL=1
|
||||
else
|
||||
# 解析词表:「退役词对照」第一列→去括号注→斜杠拆分
|
||||
S11_WFILE=$(mktemp)
|
||||
awk '/^## 退役词对照/{f=1;next} f && /^## /{exit} f && /^\|/ && !/^\|---/ && !/退役词/{
|
||||
sub(/^\| */, ""); sub(/ *\|.*/, "")
|
||||
gsub(/([^)]*)/, ""); gsub(/\([^)]*\)/, "")
|
||||
gsub(/^ *| *$/, "")
|
||||
n = split($0, parts, " / ")
|
||||
for (i=1;i<=n;i++){gsub(/^ *| *$/,"",parts[i]); if(parts[i]!="") print parts[i]}
|
||||
}' "$S11_TABLE" > "$S11_WFILE"
|
||||
# 显式追加+排除
|
||||
printf '完美排雷\n' >> "$S11_WFILE"
|
||||
grep -vx '巢穴' "$S11_WFILE" | grep -vx '旗' | grep -vx 'flag_\*' | sort -u > "${S11_WFILE}.x" && mv "${S11_WFILE}.x" "$S11_WFILE"
|
||||
|
||||
# 自检二:词表解析非空
|
||||
S11_WC=$(grep -c . "$S11_WFILE" 2>/dev/null || echo 0)
|
||||
if [ "$S11_WC" -eq 0 ]; then
|
||||
echo "[static_scan] S11 FAIL: 词表解析为空——术语表结构可能已变"
|
||||
S11_FAIL_LOCAL=1
|
||||
fi
|
||||
|
||||
# 自检一:扫描面非空
|
||||
S11_FC=$(find game/ -type f \( -name '*.gd' -o -name '*.tres' -o -name '*.md' -o -name '*.json' -o -name '*.sh' \) 2>/dev/null | wc -l)
|
||||
if [ "$S11_FC" -eq 0 ]; then
|
||||
echo "[static_scan] S11 FAIL: 扫描面为空——路径写错导致的静默空转"
|
||||
S11_FAIL_LOCAL=1
|
||||
fi
|
||||
|
||||
if [ "$S11_FAIL_LOCAL" -eq 0 ]; then
|
||||
# 扫描三个文件类型并合并结果
|
||||
S11_ALL_HITS=$(
|
||||
# .gd/.sh:取 # 后注释
|
||||
find game/ -type f \( -name '*.gd' -o -name '*.sh' \) -print0 2>/dev/null \
|
||||
| xargs -0 awk -v wf="$S11_WFILE" '
|
||||
BEGIN{nw=0;while((getline w<wf)>0)words[++nw]=w;close(wf)}
|
||||
/#/{
|
||||
cs=index($0,"#"); cmt=substr($0,cs+1)
|
||||
for(i=1;i<=nw;i++){
|
||||
if(index(cmt,words[i])>0){
|
||||
if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next
|
||||
if(FILENAME~"enemy.tres"&&NR==653)next
|
||||
if(FILENAME~"level_runner"&&NR==832)next
|
||||
if(FILENAME~"adventure_runner"&&NR==403)next
|
||||
if(FILENAME~"damage_math_test"&&NR==36)next
|
||||
print FILENAME":"NR":"words[i]
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
' 2>/dev/null
|
||||
# .tres:取 ; 后注释
|
||||
find game/ -type f -name '*.tres' -print0 2>/dev/null \
|
||||
| xargs -0 awk -v wf="$S11_WFILE" '
|
||||
BEGIN{nw=0;while((getline w<wf)>0)words[++nw]=w;close(wf)}
|
||||
/;/{
|
||||
cs=index($0,";"); cmt=substr($0,cs+1)
|
||||
for(i=1;i<=nw;i++){
|
||||
if(index(cmt,words[i])>0){
|
||||
if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next
|
||||
if(FILENAME~"enemy.tres"&&NR==653)next
|
||||
print FILENAME":"NR":"words[i]
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
' 2>/dev/null
|
||||
# .md:整行即注释面
|
||||
find game/ -type f -name '*.md' -print0 2>/dev/null \
|
||||
| xargs -0 awk -v wf="$S11_WFILE" '
|
||||
BEGIN{nw=0;while((getline w<wf)>0)words[++nw]=w;close(wf)}
|
||||
{
|
||||
for(i=1;i<=nw;i++){
|
||||
if(index($0,words[i])>0){
|
||||
if($0~/contains\(|find\(|grep|has_char\(|禁「|禁『|零「|零『/)next
|
||||
print FILENAME":"NR":"words[i]
|
||||
next
|
||||
}
|
||||
}
|
||||
}
|
||||
' 2>/dev/null
|
||||
)
|
||||
S11_HITS=0
|
||||
if [ -n "$S11_ALL_HITS" ]; then
|
||||
S11_HITS=$(echo "$S11_ALL_HITS" | grep -c .)
|
||||
fi
|
||||
|
||||
if [ "$S11_HITS" -gt 0 ]; then
|
||||
echo "[static_scan] S11 FAIL: 代码注释禁用词命中 $S11_HITS 处"
|
||||
echo "$S11_ALL_HITS" | head -50
|
||||
if [ "$S11_HITS" -gt 50 ]; then echo " ...(截断,共 $S11_HITS 处)"; fi
|
||||
fail=1
|
||||
else
|
||||
echo "[static_scan] S11 ok(扫描面 $S11_FC 个文件,词表 $S11_WC 词)"
|
||||
fi
|
||||
else
|
||||
fail=1
|
||||
fi
|
||||
|
||||
rm -f "$S11_WFILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
exit $fail
|
||||
Reference in new issue
Block a user