Files
EOS/scripts/cz_check_new_commits.py
T

89 lines
2.4 KiB
Python
Raw Normal View History

2025-10-28 02:50:31 +01:00
#!/usr/bin/env python3
"""Pre-push hook: Commitizen check for *new commits only*.
Cross-platform + uv/.venv aware:
2025-10-28 02:50:31 +01:00
- Prefers activated virtual environment (VIRTUAL_ENV)
- Falls back to uv-managed .uv/venv
- Falls back to .venv
- Falls back to global cz
2025-10-28 02:50:31 +01:00
"""
import os
import subprocess
import sys
from pathlib import Path
def find_cz() -> list[str]:
"""Return command to invoke Commitizen via virtualenv or globally."""
candidates = []
# 1️⃣ Currently active virtualenv
venv = os.getenv("VIRTUAL_ENV")
if venv:
candidates.append(Path(venv))
# 2️⃣ uv-managed virtualenv
uv_venv = Path(".uv") / "venv"
if uv_venv.exists():
candidates.append(uv_venv)
# 3️⃣ traditional .venv
dot_venv = Path(".venv")
if dot_venv.exists():
candidates.append(dot_venv)
# Check each candidate for Commitizen binary
for base in candidates:
cz_path = base / ("Scripts" if os.name == "nt" else "bin") / ("cz.exe" if os.name == "nt" else "cz")
2025-10-28 02:50:31 +01:00
if cz_path.exists():
return [str(cz_path)]
2025-10-28 02:50:31 +01:00
# 4️⃣ fallback to uv run cz
try:
subprocess.run(["uv", "run", "cz", "--version"], check=True, stdout=subprocess.DEVNULL)
return ["uv", "run", "cz"]
except (subprocess.CalledProcessError, FileNotFoundError):
pass
2025-10-28 02:50:31 +01:00
# 5️⃣ fallback to system cz
return ["cz"]
2025-10-28 02:50:31 +01:00
def get_merge_base() -> str | None:
"""Return merge-base between HEAD and upstream branch, or None if unavailable."""
try:
return (
subprocess.check_output(
["git", "merge-base", "@{u}", "HEAD"],
stderr=subprocess.DEVNULL,
text=True,
)
.strip()
)
except subprocess.CalledProcessError:
return None
def main() -> int:
cz = find_cz()
2025-10-28 02:50:31 +01:00
base = get_merge_base()
if not base:
print("⚠️ No upstream found; skipping Commitizen check {cz} for new commits.")
2025-10-28 02:50:31 +01:00
return 0
print(f"🔍 Using {cz} to check new commits from {base}..HEAD ...")
try:
subprocess.check_call(cz + ["check", "--rev-range", f"{base}..HEAD"])
2025-10-28 02:50:31 +01:00
print("✅ All new commits follow Commitizen conventions.")
return 0
except subprocess.CalledProcessError as e:
print("❌ Commitizen check failed for one or more new commits.")
return e.returncode
if __name__ == "__main__":
sys.exit(main())