79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Pre-commit hook: Reject hardcoded home-directory paths.
|
|
|
|
Install:
|
|
cp pre-commit-hardcoded-path.py .git/hooks/pre-commit-hardcoded-path
|
|
chmod +x .git/hooks/pre-commit-hardcoded-path
|
|
|
|
Or add to .pre-commit-config.yaml
|
|
"""
|
|
|
|
import sys
|
|
import subprocess
|
|
import re
|
|
|
|
PATTERNS = [
|
|
(r"/Users/[\w.\-]+/", "macOS home directory"),
|
|
(r"/home/[\w.\-]+/", "Linux home directory"),
|
|
(r"(?<![\w/])~/", "unexpanded tilde"),
|
|
]
|
|
|
|
NOQA = re.compile(r"#\s*noqa:?\s*hardcoded-path-ok")
|
|
|
|
def get_staged_files():
|
|
result = subprocess.run(
|
|
["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
|
|
capture_output=True, text=True
|
|
)
|
|
return [f for f in result.stdout.strip().split("\n") if f.endswith(".py")]
|
|
|
|
def check_file(filepath):
|
|
try:
|
|
result = subprocess.run(
|
|
["git", "show", f":{filepath}"],
|
|
capture_output=True, text=True
|
|
)
|
|
content = result.stdout
|
|
except Exception:
|
|
return []
|
|
|
|
violations = []
|
|
for i, line in enumerate(content.split("\n"), 1):
|
|
if line.strip().startswith("#"):
|
|
continue
|
|
if line.strip().startswith(("import ", "from ")):
|
|
continue
|
|
if NOQA.search(line):
|
|
continue
|
|
for pattern, desc in PATTERNS:
|
|
if re.search(pattern, line):
|
|
violations.append((filepath, i, line.strip(), desc))
|
|
break
|
|
return violations
|
|
|
|
def main():
|
|
files = get_staged_files()
|
|
if not files:
|
|
sys.exit(0)
|
|
|
|
all_violations = []
|
|
for f in files:
|
|
all_violations.extend(check_file(f))
|
|
|
|
if all_violations:
|
|
print("ERROR: Hardcoded home directory paths detected:")
|
|
print()
|
|
for filepath, line_no, line, desc in all_violations:
|
|
print(f" {filepath}:{line_no}: {desc}")
|
|
print(f" {line[:100]}")
|
|
print()
|
|
print("Fix: Use $HOME, relative paths, or get_hermes_home().")
|
|
print("Override: Add '# noqa: hardcoded-path-ok' to the line.")
|
|
sys.exit(1)
|
|
|
|
sys.exit(0)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|