Skip to content

Commit 4842364

Browse files
author
zhiwei.meng
committed
Add "--check" option support to trailing_whitespace hook
1 parent 3b8b26a commit 4842364

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

pre_commit_hooks/trailing_whitespace_fixer.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ def _fix_file(
99
filename: str,
1010
is_markdown: bool,
1111
chars: bytes | None,
12+
check_only: bool = False,
13+
error_lines: list[int] = None,
1214
) -> bool:
1315
with open(filename, mode='rb') as file_processed:
1416
lines = file_processed.readlines()
15-
newlines = [_process_line(line, is_markdown, chars) for line in lines]
17+
newlines = [_process_line(line, is_markdown, chars, line_num, error_lines) for line_num, line in enumerate(lines)]
1618
if newlines != lines:
17-
with open(filename, mode='wb') as file_processed:
18-
for line in newlines:
19-
file_processed.write(line)
19+
if not check_only:
20+
with open(filename, mode='wb') as file_processed:
21+
for line in newlines:
22+
file_processed.write(line)
2023
return True
2124
else:
2225
return False
@@ -26,7 +29,10 @@ def _process_line(
2629
line: bytes,
2730
is_markdown: bool,
2831
chars: bytes | None,
32+
line_num: int,
33+
error_lines: list[int] | None
2934
) -> bytes:
35+
org_line = line
3036
if line[-2:] == b'\r\n':
3137
eol = b'\r\n'
3238
line = line[:-2]
@@ -38,11 +44,15 @@ def _process_line(
3844
# preserve trailing two-space for non-blank lines in markdown files
3945
if is_markdown and (not line.isspace()) and line.endswith(b' '):
4046
return line[:-2].rstrip(chars) + b' ' + eol
41-
return line.rstrip(chars) + eol
47+
result = line.rstrip(chars) + eol
48+
if error_lines is not None and org_line != result:
49+
error_lines.append(line_num+1)
50+
return result
4251

4352

4453
def main(argv: Sequence[str] | None = None) -> int:
4554
parser = argparse.ArgumentParser()
55+
parser.add_argument('--check', action='store_true', help='Check without fixing')
4656
parser.add_argument(
4757
'--no-markdown-linebreak-ext',
4858
action='store_true',
@@ -93,8 +103,14 @@ def main(argv: Sequence[str] | None = None) -> int:
93103
for filename in args.filenames:
94104
_, extension = os.path.splitext(filename.lower())
95105
md = all_markdown or extension in md_exts
96-
if _fix_file(filename, md, chars):
97-
print(f'Fixing {filename}')
106+
error_lines = []
107+
if _fix_file(filename, md, chars, args.check, error_lines):
108+
if args.check:
109+
location = ",".join(map(str, error_lines[:4]))
110+
location += "..." if len(error_lines) > 4 else ""
111+
print(f'Trailing whitespace check failed: {filename} @ {location}')
112+
else:
113+
print(f'Fixing {filename}')
98114
return_code = 1
99115
return return_code
100116

tests/trailing_whitespace_fixer_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@ def test_fixes_trailing_whitespace(input_s, expected, tmpdir):
1818
assert main((str(path),)) == 1
1919
assert path.read() == expected
2020

21+
@pytest.mark.parametrize(
22+
('input_s', 'exit_code', "lines"),
23+
(
24+
('foo \nbar \n', 1, [1,2]),
25+
('bar\t\nbaz\t\n', 1, [1,2]),
26+
('bar\nbaz\t\n', 1, [2]),
27+
),
28+
)
29+
def test_fixes_trailing_whitespace_check_only(capsys, input_s, exit_code, lines, tmpdir):
30+
path = tmpdir.join('file.md')
31+
path.write(input_s)
32+
assert main(('--check', str(path),)) == exit_code
33+
assert path.read() == input_s
34+
captured = capsys.readouterr()
35+
location = "@ " + ','.join(map(str, lines))
36+
assert location in captured.out
37+
2138

2239
def test_ok_no_newline_end_of_file(tmpdir):
2340
filename = tmpdir.join('f')

0 commit comments

Comments
 (0)