Files
ai-proj-helper/skills-req/req-test-gate-plugin/skills/templates/convention-script.md
John Qiu b9c808cce0 feat(req-test-gate): 集成 Harness Engineering 工程约束方法论
将项目级的 Ratchet/约定检测方法论融入 req-test-gate 技能,
通过 /req 流程三个节点自动触发(dev 环境检测、cr 约定建议、test Gate 0B),
无需手动记忆执行。

新增文档:harness-engineering.md、ratchet-pattern.md、convention-flow.md、
project-bootstrap.md 及 4 个模板(ratchet/convention 脚本、GATES.md、pre-commit)。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 11:34:42 +10:30

121 lines
4.7 KiB
Markdown

# Convention Detection Script Template
泛化的约定检测脚本模板,基于 new-ai-proj `check-modal-safety.sh` 提取。用于检测代码中违反编码约定的模式。
## 使用方法
1. 复制下方脚本到 `scripts/check-{NAME}.sh`
2. 替换所有 `{PLACEHOLDER}` 为项目特定值
3. 运行 `chmod +x scripts/check-{NAME}.sh`
4. 验证:`./scripts/check-{NAME}.sh` 输出 PASSED
## 脚本模板
```bash
#!/usr/bin/env bash
#
# {CONVENTION_NAME} Check — detects {WHAT_IT_DETECTS} in {TARGET_SCOPE}.
#
# {PROBLEM_DESCRIPTION}
#
# Usage:
# ./scripts/check-{NAME}.sh # Check and report
# ./scripts/check-{NAME}.sh --ci # Exit code 1 on violations
#
set -euo pipefail
TARGET_DIR="$(cd "$(dirname "$0")/../{TARGET_DIRECTORY}" && pwd)"
CI_MODE=false
[[ "${1:-}" == "--ci" ]] && CI_MODE=true
violations=0
# ── detection logic ─────────────────────────────────────────────────
# Strategy A: Simple grep pattern (file-level)
# Find files matching a bad pattern, optionally excluding false positives.
#
# while IFS= read -r file; do
# rel_path="${file#"$TARGET_DIR"/}"
# echo "WARNING: $rel_path — {VIOLATION_MESSAGE}"
# violations=$((violations + 1))
# done < <(grep -rl '{BAD_PATTERN}' "$TARGET_DIR" --include='{FILE_GLOB}' 2>/dev/null \
# | while read f; do grep -L '{FALSE_POSITIVE_PATTERN}' "$f" 2>/dev/null; done)
# Strategy B: Line-level with context (multi-condition)
# Find a primary pattern, check nearby lines for secondary pattern.
#
# while IFS= read -r file; do
# while IFS= read -r line_num; do
# # Check context around the match
# has_mitigation=$(sed -n "${line_num},$((line_num + {CONTEXT_LINES}))p" "$file" \
# | grep -c '{MITIGATION_PATTERN}' || true)
# if [[ "$has_mitigation" -eq 0 ]]; then
# # Additional condition: check if problematic follow-up exists
# after_end=$((line_num + {LOOKAHEAD_LINES}))
# has_problem=$(sed -n "$((line_num + 1)),${after_end}p" "$file" \
# | grep -cE '{FOLLOW_UP_BAD_PATTERN}' || true)
# if [[ "$has_problem" -gt 0 ]]; then
# rel_path="${file#"$TARGET_DIR"/}"
# echo "WARNING: $rel_path:$line_num — {VIOLATION_MESSAGE}"
# violations=$((violations + 1))
# fi
# fi
# done < <(grep -n '{PRIMARY_PATTERN}' "$file" | cut -d: -f1)
# done < <(grep -rl '{PRIMARY_PATTERN}' "$TARGET_DIR" --include='{FILE_GLOB}' 2>/dev/null)
# ── results ─────────────────────────────────────────────────────────
if [[ "$violations" -gt 0 ]]; then
echo ""
echo "Found $violations {CONVENTION_NAME} violation(s)."
echo "Fix: {FIX_GUIDANCE}"
echo "Docs: see CLAUDE.md '{CLAUDE_MD_SECTION}'"
$CI_MODE && exit 1
else
echo "{CONVENTION_NAME} check PASSED."
fi
```
## Placeholder 说明
| Placeholder | 含义 | 示例 |
|-------------|------|------|
| `{NAME}` | 脚本短名 | `modal-safety`, `sql-injection` |
| `{CONVENTION_NAME}` | 约定显示名 | `Modal safety`, `SQL injection prevention` |
| `{WHAT_IT_DETECTS}` | 检测内容 | `potential modal overlap patterns` |
| `{TARGET_SCOPE}` | 目标范围描述 | `frontend code`, `Go handlers` |
| `{TARGET_DIRECTORY}` | 扫描目录 | `frontend/src`, `backend` |
| `{PROBLEM_DESCRIPTION}` | 问题描述 | `Ant Design Modal.success is non-blocking...` |
| `{FILE_GLOB}` | 文件匹配 | `*.tsx`, `*.go` |
| `{PRIMARY_PATTERN}` | 主匹配模式 | `Modal\.\(success\|info\)` |
| `{MITIGATION_PATTERN}` | 缓解模式(有则排除) | `onOk` |
| `{FOLLOW_UP_BAD_PATTERN}` | 后续违规模式 | `set\w*Open\(true\)` |
| `{CONTEXT_LINES}` | 上下文行数 | `25` |
| `{LOOKAHEAD_LINES}` | 前瞻行数 | `20` |
| `{BAD_PATTERN}` | Strategy A 主匹配模式 | `console\.log` |
| `{FALSE_POSITIVE_PATTERN}` | Strategy A 排除模式(匹配到则非违规) | `// eslint-disable` |
| `{VIOLATION_MESSAGE}` | 违规消息 | `Modal without onOk followed by setState` |
| `{FIX_GUIDANCE}` | 修复指导 | `add onOk callback to Modal` |
| `{CLAUDE_MD_SECTION}` | CLAUDE.md 章节名 | `Frontend: Modal 安全规则` |
## 两种检测策略
### Strategy A: 文件级检测
适用于:整个文件不应出现某模式(或出现即违规)。
例子:
- `console.log` 在生产代码中
- `TODO` / `FIXME` 计数
- 缺少 license header
### Strategy B: 行级 + 上下文检测
适用于:模式本身不违规,需要检查周围上下文。
例子:
- `Modal.success()` 不违规,但后面紧跟 `setState` 才违规
- `db.Exec()` 不违规,但参数用字符串拼接才违规
- `fmt.Println()` 不违规,但在 handler 中输出敏感数据才违规