|
42 | 42 | from scope import FULL_SCAN_EXCLUDES, changed_files, scope_cmd |
43 | 43 |
|
44 | 44 | # === git 提交内容安全检查:绝不该进版本库的文件 === |
| 45 | +CODEGUARD_VERSION = "0.12.0" |
| 46 | + |
45 | 47 | # 目录 = 构建产物/依赖快照**单一事实源**(scope.FULL_SCAN_EXCLUDES)+ IDE 目录。 |
46 | 48 | # 从单一来源派生:清单只在 scope.py 改一处,"入库面"与"扫描面"永不漂移 |
47 | 49 | # (此前两份手抄清单已经漂移:扫描面缺 out/.next/coverage 等 14 个目录, |
@@ -140,7 +142,7 @@ def _gate_cache_path(project_root: Path) -> Path: |
140 | 142 | return Path(tempfile.gettempdir()) / f"codeguard-gate-{os.getuid()}-{key}.json" |
141 | 143 |
|
142 | 144 |
|
143 | | -def _worktree_fingerprint(project_root: Path) -> str: |
| 145 | +def _worktree_fingerprint(project_root: Path, *, max_files: int = 500) -> str: |
144 | 146 | """工作区指纹:三路改动的**名字 + stat** 指纹(不再哈希全文内容)。 |
145 | 147 |
|
146 | 148 | 只用 index mtime 会漏掉"文件已修但未 git add"——键不变 → 60 秒内继续 |
@@ -459,6 +461,24 @@ def check(lang: str): |
459 | 461 | if not ok: |
460 | 462 | return (lang, None, f"{lang} 工具链不可用未验证:{reason}(安装: {hint})") |
461 | 463 |
|
| 464 | + # Java 门禁接入 java_project 分析:mvnw 感知 + 工具链失配归跳过。 |
| 465 | + if lang == "java": |
| 466 | + try: |
| 467 | + from java_project import analyze as _jp_analyze |
| 468 | + _jp = _jp_analyze(str(project_root)) |
| 469 | + if _jp.get("status") == "UNVERIFIED": |
| 470 | + return (lang, None, |
| 471 | + (f"{lang} 项目分析 UNVERIFIED({_jp.get('build_system', '?')})," |
| 472 | + f"原因: {'; '.join(_jp.get('reasons', []))},本次未验证")) |
| 473 | + exe = _jp.get("executable") |
| 474 | + if exe and base_cmd and base_cmd[0] in ("mvn", "gradle"): |
| 475 | + base_cmd = [exe] + base_cmd[1:] |
| 476 | + except Exception as exc: # noqa: BLE001 — 分析失败不阻塞门禁,走原路径 |
| 477 | + print(f"[codeguard] java_project 分析失败(走原路径): {exc!r}", |
| 478 | + file=sys.stderr) |
| 479 | + record_gate_decision(project_root, lang, base_cmd, -1, |
| 480 | + "UNVERIFIED", f"java_project 分析失败: {exc!r}") |
| 481 | + |
462 | 482 | outputs: list[tuple[int, str, str]] = [] |
463 | 483 | stale_notes: list[str] = [] |
464 | 484 | # 项目级命令(mvn/gradle 等,无 {file} 占位符)不追加文件路径—— |
@@ -877,11 +897,16 @@ def gate_directive(failures: list) -> str: |
877 | 897 | """ |
878 | 898 | header = [ |
879 | 899 | summarize_failures(failures), |
| 900 | + f"codeguard v{CODEGUARD_VERSION}", |
880 | 901 | "─" * 60, |
881 | 902 | "**给 AI 的强制指令**:提交门禁未通过,禁止执行 git commit / git push。\n" |
882 | 903 | + "**⚠️ 整个工具调用没有执行**:被拦截的是一次包含 git commit/push 的完整 Bash " |
883 | 904 | "调用——其中非 git 的前序步骤(写文件、跑脚本)也全部未运行。请把「修复」与" |
884 | 905 | "「提交」拆成两次独立的工具调用,修完再单独执行提交。\n" |
| 906 | + + "**⚠️ 如果报错涉及 target/、dist/、build/ 下的构建产物**:请先单独" |
| 907 | + "运行清理命令(如 `rm -rf target/reports`,不含 git commit/push)," |
| 908 | + "清理完成后再重试提交——本门禁在命令执行前拦截,此前命令链中的清理" |
| 909 | + "步骤不会被执行。\n" |
885 | 910 | + "请立即处理:1) 按下面「怎么修」逐项修复(能自动修复的先跑自动修复命令);" |
886 | 911 | "2) 纯 lint 类修复可直接继续、不必逐项追问;但凡涉及付费、发布、删除、" |
887 | 912 | "密钥、或跨出本仓的操作,必须先征得用户同意再执行;" |
|
0 commit comments