Files
Stirling-PDF/scripts/pre-commit/install_gitleaks.py
T
Ludy87 c835f2da06 Update Ruff and lint cleanup
Bump Python tooling to Ruff 0.16.2 and datamodel-code-generator 0.72.3, add the py313 target in pre-commit, and refresh the engine lockfile. This also narrows broad exception handling and applies small Python cleanups across the engine and helper scripts to satisfy newer lint rules without changing runtime behavior.
2026-08-19 00:26:55 +02:00

106 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Download the pinned gitleaks binary into .task/bin, verifying its checksum.
gitleaks is a Go binary with no PyPI package, so it can't be locked like the
other tools (ruff/codespell/toml-sort live in engine/pyproject.toml).
This script is the single source of truth for the gitleaks version and the
SHA-256 of each release asset. It is cross-platform (stdlib only) and idempotent:
if the cached binary already reports the pinned version it does nothing, so
`task pre-commit` can call it every run.
Bump the version by editing VERSION and the SHA256 map (values come from the
release's gitleaks_<version>_checksums.txt).
"""
from __future__ import annotations
import hashlib
import platform
import subprocess
import sys
import tarfile
import urllib.request
import zipfile
from pathlib import Path
VERSION = "8.30.0"
# SHA-256 of each release asset, keyed by "<os>_<arch>" (gitleaks' own naming).
SHA256 = {
"linux_x64": "79a3ab579b53f71efd634f3aaf7e04a0fa0cf206b7ed434638d1547a2470a66e",
"linux_arm64": "b4cbbb6ddf7d1b2a603088cd03a4e3f7ce48ee7fd449b51f7de6ee2906f5fa2f",
"darwin_x64": "ca221d012d247080c2f6f61f4b7a83bffa2453806b0c195c795bbe9a8c775ed5",
"darwin_arm64": "b251ab2bcd4cd8ba9e56ff37698c033ebf38582b477d21ebd86586d927cf87e7",
"windows_x64": "54fe94f644b832dd08e8c3a5915efb3bfa862386d59fb27ca0792cb687a83573",
}
REPO_ROOT = Path(__file__).resolve().parents[2]
IS_WINDOWS = platform.system() == "Windows"
BIN = REPO_ROOT / ".task" / "bin" / ("gitleaks.exe" if IS_WINDOWS else "gitleaks")
def platform_key() -> str:
os_name = {"Linux": "linux", "Darwin": "darwin", "Windows": "windows"}.get(platform.system())
arch = {
"x86_64": "x64",
"amd64": "x64",
"arm64": "arm64",
"aarch64": "arm64",
"i386": "x32",
"i686": "x32",
"x86": "x32",
"armv7l": "armv7",
"armv6l": "armv6",
}.get(platform.machine().lower())
if not os_name or not arch:
raise SystemExit(f"Unsupported platform for gitleaks: {platform.system()}/{platform.machine()}")
return f"{os_name}_{arch}"
def cached_version() -> str | None:
if not BIN.exists():
return None
try:
return subprocess.run([str(BIN), "version"], capture_output=True, text=True, check=False).stdout.strip()
except OSError:
return None
def main() -> int:
if cached_version() == VERSION:
return 0
key = platform_key()
expected = SHA256.get(key)
if expected is None:
raise SystemExit(f"No pinned gitleaks checksum for {key}")
suffix = "zip" if key.startswith("windows") else "tar.gz"
asset = f"gitleaks_{VERSION}_{key}.{suffix}"
url = f"https://github.com/gitleaks/gitleaks/releases/download/v{VERSION}/{asset}"
print(f"Downloading gitleaks {VERSION} ({asset})", flush=True)
BIN.parent.mkdir(parents=True, exist_ok=True)
archive, _ = urllib.request.urlretrieve(url)
digest = hashlib.sha256(Path(archive).read_bytes()).hexdigest()
if digest != expected:
raise SystemExit(f"gitleaks checksum mismatch: expected {expected}, got {digest}")
member = "gitleaks.exe" if IS_WINDOWS else "gitleaks"
if suffix == "zip":
with zipfile.ZipFile(archive) as zf:
data = zf.read(member)
else:
with tarfile.open(archive) as tf:
extracted = tf.extractfile(member)
if extracted is None:
raise SystemExit(f"{member} not found in {asset}")
data = extracted.read()
BIN.write_bytes(data)
BIN.chmod(0o755)
return 0
if __name__ == "__main__":
sys.exit(main())