From f51fcfdf5614d7210a5bb9df42160ee301cd1404 Mon Sep 17 00:00:00 2001 From: sladro Date: Wed, 11 Feb 2026 13:02:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=9B=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .githooks/check_staged_java_encoding.py | 92 +++++++++++++++++++++++++ .githooks/pre-commit | 14 ++++ 2 files changed, 106 insertions(+) create mode 100644 .githooks/check_staged_java_encoding.py create mode 100644 .githooks/pre-commit diff --git a/.githooks/check_staged_java_encoding.py b/.githooks/check_staged_java_encoding.py new file mode 100644 index 0000000..b4d847f --- /dev/null +++ b/.githooks/check_staged_java_encoding.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +import subprocess +import sys + + +def run_git(*args: str) -> subprocess.CompletedProcess: + return subprocess.run( + ["git", *args], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + + +def staged_java_files() -> list[str]: + result = run_git("diff", "--cached", "--name-only", "--diff-filter=ACMR", "-z") + if result.returncode != 0: + sys.stderr.write(result.stderr.decode("utf-8", errors="replace")) + return [] + + files: list[str] = [] + for raw in result.stdout.split(b"\0"): + if not raw: + continue + path = raw.decode("utf-8", errors="surrogateescape") + if path.lower().endswith(".java"): + files.append(path) + return files + + +def staged_blob(path: str) -> bytes | None: + result = run_git("show", f":{path}") + if result.returncode != 0: + return None + return result.stdout + + +def main() -> int: + utf8_errors: list[str] = [] + bom_errors: list[str] = [] + crlf_errors: list[str] = [] + missing_errors: list[str] = [] + + for path in staged_java_files(): + data = staged_blob(path) + if data is None: + missing_errors.append(path) + continue + + if data.startswith(b"\xef\xbb\xbf"): + bom_errors.append(path) + + try: + data.decode("utf-8") + except UnicodeDecodeError: + utf8_errors.append(path) + + if b"\r\n" in data: + crlf_errors.append(path) + + if not (utf8_errors or bom_errors or crlf_errors or missing_errors): + return 0 + + sys.stderr.write("\npre-commit blocked: Java file encoding/line-ending violations found.\n") + if utf8_errors: + sys.stderr.write("\n[Non-UTF-8 Java files]\n") + for p in utf8_errors: + sys.stderr.write(f" - {p}\n") + if bom_errors: + sys.stderr.write("\n[UTF-8 BOM not allowed]\n") + for p in bom_errors: + sys.stderr.write(f" - {p}\n") + if crlf_errors: + sys.stderr.write("\n[CRLF not allowed in Java files]\n") + for p in crlf_errors: + sys.stderr.write(f" - {p}\n") + if missing_errors: + sys.stderr.write("\n[Could not read staged blob]\n") + for p in missing_errors: + sys.stderr.write(f" - {p}\n") + + sys.stderr.write( + "\nFix tips:\n" + " 1) Convert file encoding to UTF-8 (without BOM).\n" + " 2) Convert line endings to LF.\n" + " 3) Re-stage files: git add \n" + ) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100644 index 0000000..5c7758c --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,14 @@ +#!/usr/bin/env sh +set -eu + +PYTHON_BIN="${PYTHON:-python}" +if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then + PYTHON_BIN="python3" +fi + +if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then + echo "pre-commit: Python is required to run encoding checks." >&2 + exit 1 +fi + +exec "$PYTHON_BIN" ".githooks/check_staged_java_encoding.py"