Files
bot-bottle/.githooks/commit-msg
didericis 399ed93dc8 refactor: convert project from bash to Python
Replaces cli.sh + lib/*.sh with a claude_bottle/ Python package and a
cli.py entry point. No external dependencies — uses only Python's
stdlib (json, subprocess, getpass, tempfile, argparse, re, etc.).

- claude_bottle/{log,docker,manifest,env_resolve,network,pipelock,
  skills,ssh,cli}.py mirror the previous lib/*.sh modules.
- Tests converted to unittest under tests/test_*.py with a stdlib
  runner at tests/run_tests.py (unit | integration | path).
- .githooks/commit-msg ported to Python; same Conventional Commits rules.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 15:26:58 +00:00

46 lines
1.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Enforce Conventional Commits on the first line of the commit message.
https://www.conventionalcommits.org/en/v1.0.0/
Activate per clone with:
git config core.hooksPath .githooks
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ALLOWED_PREFIXES = ("Merge ", "Revert ", "fixup! ", "squash! ", "amend! ")
PATTERN = re.compile(
r"^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)"
r"(\([a-z0-9._-]+\))?!?: .+"
)
def main(argv: list[str]) -> int:
if len(argv) < 1:
print("commit-msg: missing message file path", file=sys.stderr)
return 1
msg_file = Path(argv[0])
text = msg_file.read_text(encoding="utf-8", errors="replace")
first_line = text.splitlines()[0] if text else ""
if any(first_line.startswith(p) for p in ALLOWED_PREFIXES):
return 0
if not PATTERN.match(first_line):
sys.stderr.write("commit-msg: aborting — message does not follow Conventional Commits.\n")
sys.stderr.write(" expected: <type>[(<scope>)][!]: <description>\n")
sys.stderr.write(" types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert\n")
sys.stderr.write(f" got: {first_line}\n")
return 1
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))