From 5d2ad40336838c19e45a5aaad5419b2a868bbb72 Mon Sep 17 00:00:00 2001 From: iomgaa Date: Wed, 14 Oct 2026 22:32:52 -0400 Subject: [PATCH] chore: gate complexity only on functions touched by the change Whole-tree radon blocking let 16 legacy C+ functions block every commit, including docs-only ones. Touched functions still block; legacy debt is reported as a warning. --- .claude/scripts/hooks/pre-commit-guard.sh | 31 ++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.claude/scripts/hooks/pre-commit-guard.sh b/.claude/scripts/hooks/pre-commit-guard.sh index a3b1441..f570777 100755 --- a/.claude/scripts/hooks/pre-commit-guard.sh +++ b/.claude/scripts/hooks/pre-commit-guard.sh @@ -41,10 +41,35 @@ for CODE_DIR in "${CODE_DIRS[@]}"; do fi fi + # 复杂度只对"本次改动触及的函数"硬拦: 全量拦截会让存量债务挡住一切提交 + # (含纯文档提交),久之只剩绕过一条路;存量 ≥C 函数降为告警,随触及随还。 + # 用 HEAD 对比工作区+暂存区: 钩子在 `git add && git commit` 同一命令里先于 add 运行 if command -v radon &> /dev/null; then - RADON_OUTPUT=$(radon cc "$CODE_DIR" -n C -s 2>&1 || true) - if echo "$RADON_OUTPUT" | grep -qE '^\s+[FMC]\s'; then - ERRORS+="[radon] 存在圈复杂度 ≥ C 的函数:\n$RADON_OUTPUT\n" + mapfile -t CHANGED_PY < <(git diff HEAD --name-only --diff-filter=AM -- "$CODE_DIR" | grep '\.py$' || true) + if [[ ${#CHANGED_PY[@]} -gt 0 ]]; then + TOUCHED=$(git diff HEAD -U0 -- "${CHANGED_PY[@]}" | python3 -c ' +import json, re, subprocess, sys +hunks, path = {}, None +for line in sys.stdin: + if line.startswith("+++ "): + path = line[6:].strip() if line.startswith("+++ b/") else None + m = re.match(r"@@ -\S+ \+(\d+)(?:,(\d+))? @@", line) + if m and path: + start, count = int(m.group(1)), int(m.group(2) or 1) + hunks.setdefault(path, []).append((start, start + max(count, 1) - 1)) +data = json.loads(subprocess.run(["radon", "cc", "-j", "-n", "C", *hunks], capture_output=True, text=True).stdout or "{}") +for path, blocks in data.items(): + for b in blocks if isinstance(blocks, list) else []: + if any(s <= b["endline"] and e >= b["lineno"] for s, e in hunks.get(path, [])): + print("%s:%s %s - %s (%s)" % (path, b["lineno"], b["name"], b["rank"], b["complexity"])) +' 2>&1 || true) + if [[ -n "$TOUCHED" ]]; then + ERRORS+="[radon] 本次改动触及的函数圈复杂度 ≥ C:\n$TOUCHED\n" + fi + fi + LEGACY_COUNT=$(radon cc "$CODE_DIR" -n C 2>/dev/null | grep -cE '^\s+[FMC]\s' || true) + if [[ "$LEGACY_COUNT" -gt 0 ]]; then + WARNINGS+="[radon] $CODE_DIR/ 存量 ${LEGACY_COUNT} 个函数圈复杂度 ≥ C(未被本次改动触及,不阻塞)。\n" fi fi