mirror of
git://f0xx.org/ac/ac-scripts
synced 2026-07-29 04:39:20 +03:00
initial
This commit is contained in:
90
header-pre-commit.py
Executable file
90
header-pre-commit.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Git pre-commit: validate headers on new files; refresh Updated/Digest on staged edits."""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from header_lib import (
|
||||
REPO_ROOT,
|
||||
SOURCE_SUFFIXES,
|
||||
apply_header_to_content,
|
||||
has_valid_header,
|
||||
header_needs_identity_refresh,
|
||||
hook_skip_requested,
|
||||
is_excluded_path,
|
||||
resolve_header_contributor,
|
||||
update_header_timestamps,
|
||||
)
|
||||
|
||||
|
||||
def staged_files() -> list[Path]:
|
||||
out = subprocess.check_output(
|
||||
["git", "diff", "--cached", "--name-only", "--diff-filter=ACMR"],
|
||||
cwd=REPO_ROOT,
|
||||
text=True,
|
||||
)
|
||||
files = []
|
||||
for line in out.splitlines():
|
||||
p = REPO_ROOT / line.strip()
|
||||
if not p.is_file() or p.suffix.lower() not in SOURCE_SUFFIXES:
|
||||
continue
|
||||
if is_excluded_path(p):
|
||||
continue
|
||||
files.append(p)
|
||||
return files
|
||||
|
||||
|
||||
def is_new_file(path: Path) -> bool:
|
||||
rel = path.relative_to(REPO_ROOT).as_posix()
|
||||
try:
|
||||
subprocess.check_call(
|
||||
["git", "diff", "--cached", "--diff-filter=A", "--quiet", "--", rel],
|
||||
cwd=REPO_ROOT,
|
||||
)
|
||||
return False
|
||||
except subprocess.CalledProcessError:
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if hook_skip_requested():
|
||||
return 0
|
||||
|
||||
errors = []
|
||||
contributor = resolve_header_contributor()
|
||||
for path in staged_files():
|
||||
text = path.read_text(encoding="utf-8", errors="replace")
|
||||
if is_new_file(path):
|
||||
if not has_valid_header(text):
|
||||
errors.append(
|
||||
f"{path.relative_to(REPO_ROOT)}: new file must include HEADER.txt block"
|
||||
)
|
||||
text = apply_header_to_content(path, text)
|
||||
text = update_header_timestamps(text, path, contributor)
|
||||
else:
|
||||
if has_valid_header(text):
|
||||
if header_needs_identity_refresh(text, path):
|
||||
text = apply_header_to_content(path, text)
|
||||
text = update_header_timestamps(text, path, contributor)
|
||||
else:
|
||||
text = apply_header_to_content(path, text)
|
||||
text = update_header_timestamps(text, path, contributor)
|
||||
path.write_text(text, encoding="utf-8", newline="\n")
|
||||
rel = path.relative_to(REPO_ROOT).as_posix()
|
||||
subprocess.check_call(["git", "add", "--", rel], cwd=REPO_ROOT)
|
||||
|
||||
if errors:
|
||||
for e in errors:
|
||||
print(e, file=sys.stderr)
|
||||
print(
|
||||
"Run: python3 scripts/apply-project-headers.py",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user