from pathlib import Path
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[1]
ATTRIBUTES = ROOT / ".gitattributes"
def tracked_files():
result = subprocess.run(
["git", "ls-files", "-z"],
cwd=ROOT,
check=True,
stdout=subprocess.PIPE,
)
return [ROOT / Path(item.decode("utf-8")) for item in result.stdout.split(b"\0") if item]
def attribute_patterns():
patterns = []
for line in ATTRIBUTES.read_text(encoding="utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
parts = line.split()
if len(parts) < 2 or parts[1] == "binary":
continue
if parts[1] == "text" and any(part == "eol=lf" for part in parts[2:]):
patterns.append(parts[0])
return patterns
def matches(path, patterns):
relative = path.relative_to(ROOT).as_posix()
name = path.name
for pattern in patterns:
if pattern.startswith("*.") and name.endswith(pattern[1:]):
return True
if pattern == relative or pattern == name:
return True
return False
def main():
patterns = attribute_patterns()
changed = []
for path in tracked_files():
if not matches(path, patterns):
continue
raw = path.read_bytes()
normalized = raw.replace(b"\r\n", b"\n")
if normalized != raw:
path.write_bytes(normalized)
changed.append(path.relative_to(ROOT).as_posix())
for path in changed:
print(f"LF: {path}")
print(f"normalized {len(changed)} file(s)")
return 0
if __name__ == "__main__":
sys.exit(main())