43 lines
1.6 KiB
Python
43 lines
1.6 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""auditor_gate.sh 보조 — 셸 도구(Bash·PowerShell) 명령에 git commit/push 가 있는지 판정 (C35-9 Layer 3)
|
|
|
|
grep 추출은 JSON 문자열의 이스케이프 따옴표에서 잘리고, `git` 바로 뒤에 commit|push 가 올 때만 잡아
|
|
`git -C <레포> commit` · `cd "x" && git commit` · PowerShell 경유 commit/push 를 놓쳤다
|
|
(2026-09-16 pm-auditor Critical — ImmortalSword 세션 대화로그 §3).
|
|
|
|
stdin : PreToolUse hook JSON
|
|
stdout: "1" = 게이트 대상 / "0" = 아님
|
|
exit 3: JSON 파싱 실패 (호출부가 grep 폴백으로 판정)
|
|
"""
|
|
import io
|
|
import json
|
|
import re
|
|
import sys
|
|
|
|
GIT_COMMIT_PUSH = re.compile(
|
|
r"""(?:^|[\s;&|(`{])git(?:\.exe)? # git 실행 토큰 (연쇄·파이프·서브셸 뒤 포함)
|
|
(?:\s+(?:-C\s+(?:"[^"]*"|'[^']*'|\S+) # -C <경로> (대소문자 무시라 -c key=value 도 여기서 소비)
|
|
|--[\w-]+(?:=(?:"[^"]*"|'[^']*'|\S+))? # --git-dir=... · --no-pager 등
|
|
|-\w+))* # 기타 전역 플래그
|
|
\s+(?:commit|push)\b""",
|
|
re.IGNORECASE | re.VERBOSE,
|
|
)
|
|
|
|
|
|
def main():
|
|
raw = sys.stdin.buffer.read().decode("utf-8", errors="replace")
|
|
try:
|
|
data = json.loads(raw)
|
|
except Exception:
|
|
sys.exit(3)
|
|
tool = data.get("tool_name", "")
|
|
cmd = (data.get("tool_input") or {}).get("command") or ""
|
|
hit = tool in ("Bash", "PowerShell") and bool(GIT_COMMIT_PUSH.search(cmd))
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
|
sys.stdout.write("1" if hit else "0")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|