Skip to content

Commit be26f4f

Browse files
committed
fix: add script to strip trailing whitespace from templates
Trailing whitespace in .gitignore patterns can cause unexpected behavior. This script detects and removes trailing whitespace from template files with dry-run support. Signed-off-by: Srikanth Patchava <spatchava@meta.com>
1 parent 1dfb9ef commit be26f4f

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Strip trailing whitespace from .gitignore template files.
4+
5+
This script fixes trailing whitespace issues in gitignore templates,
6+
which can cause unexpected behavior in pattern matching.
7+
"""
8+
9+
import argparse
10+
import os
11+
import sys
12+
13+
14+
def strip_file(filepath: str, dry_run: bool = False) -> int:
15+
"""Strip trailing whitespace from a file. Returns number of lines fixed."""
16+
with open(filepath, "r", encoding="utf-8", errors="replace") as f:
17+
lines = f.readlines()
18+
19+
fixed_count = 0
20+
new_lines = []
21+
for line in lines:
22+
stripped = line.rstrip() + "\n"
23+
if stripped != line:
24+
fixed_count += 1
25+
new_lines.append(stripped)
26+
27+
# Ensure file ends with a single newline
28+
if new_lines and new_lines[-1] == "\n":
29+
pass # already ends properly
30+
elif not new_lines:
31+
new_lines = ["\n"]
32+
33+
if fixed_count > 0 and not dry_run:
34+
with open(filepath, "w", encoding="utf-8", newline="") as f:
35+
f.writelines(new_lines)
36+
37+
return fixed_count
38+
39+
40+
def main():
41+
parser = argparse.ArgumentParser(
42+
description="Strip trailing whitespace from .gitignore templates."
43+
)
44+
parser.add_argument("files", nargs="*", help="Files to process.")
45+
parser.add_argument("--repo-root", default=".", help="Repo root directory.")
46+
parser.add_argument(
47+
"--dry-run", action="store_true", help="Report but do not modify files."
48+
)
49+
args = parser.parse_args()
50+
51+
if args.files:
52+
targets = args.files
53+
else:
54+
targets = []
55+
for entry in os.listdir(args.repo_root):
56+
full = os.path.join(args.repo_root, entry)
57+
if os.path.isfile(full) and entry.endswith(".gitignore"):
58+
targets.append(full)
59+
60+
total_fixed = 0
61+
for filepath in targets:
62+
count = strip_file(filepath, dry_run=args.dry_run)
63+
if count > 0:
64+
action = "would fix" if args.dry_run else "fixed"
65+
print(f" {action} {count} line(s) in {filepath}")
66+
total_fixed += count
67+
68+
if total_fixed == 0:
69+
print("No trailing whitespace found.")
70+
else:
71+
action = "Would fix" if args.dry_run else "Fixed"
72+
print(f"\n{action} {total_fixed} line(s) total.")
73+
74+
sys.exit(0)
75+
76+
77+
if __name__ == "__main__":
78+
main()

0 commit comments

Comments
 (0)