From 7cfec24f77881fcf01a65d21b3a45da5c773a7cf Mon Sep 17 00:00:00 2001 From: Daniel Gallagher Date: Sun, 25 Jun 2017 14:40:03 -0700 Subject: [PATCH 1/3] Fix bug with the file-contents-sorter hook when processing file that does not end in a newline --- pre_commit_hooks/file_contents_sorter.py | 19 +++++++++---------- tests/file_contents_sorter_test.py | 4 ++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 6fa3bc0..b66cc72 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -18,19 +18,18 @@ FAIL = 1 def sort_file_contents(f): - before = tuple(f) + before = [line.strip(b'\n\r') for line in f if line.strip()] after = sorted(before) - before_string = b''.join(before) - after_string = b''.join(after) - - if before_string == after_string: + if before == after: return PASS - else: - f.seek(0) - f.write(after_string) - f.truncate() - return FAIL + + after_string = b'\n'.join(after) + b'\n' + + f.seek(0) + f.write(after_string) + f.truncate() + return FAIL def main(argv=None): diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index 5f4dc5b..b635eb0 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -11,12 +11,16 @@ from pre_commit_hooks.file_contents_sorter import PASS (b'', PASS, b''), (b'lonesome\n', PASS, b'lonesome\n'), (b'missing_newline', PASS, b'missing_newline'), + (b'newline\nmissing', FAIL, b'missing\nnewline\n'), + (b'missing\nnewline', PASS, b'missing\nnewline'), (b'alpha\nbeta\n', PASS, b'alpha\nbeta\n'), (b'beta\nalpha\n', FAIL, b'alpha\nbeta\n'), (b'C\nc\n', PASS, b'C\nc\n'), (b'c\nC\n', FAIL, b'C\nc\n'), (b'mag ical \n tre vor\n', FAIL, b' tre vor\nmag ical \n'), (b'@\n-\n_\n#\n', FAIL, b'#\n-\n@\n_\n'), + (b'extra\n\n\nwhitespace\n', PASS, b'extra\n\n\nwhitespace\n'), + (b'whitespace\n\n\nextra\n', FAIL, b'extra\nwhitespace\n'), ) ) def test_integration(input_s, expected_retval, output, tmpdir): From 5dd1819e8b6757490f8c20b51df219d714d4ab0e Mon Sep 17 00:00:00 2001 From: Daniel Gallagher Date: Sun, 25 Jun 2017 15:37:58 -0700 Subject: [PATCH 2/3] Warn users of file-contents-sorter that blank lines are removed and comments are not respected --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92fb408..6e268ff 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Add this to your `.pre-commit-config.yaml` with single quoted strings. - `end-of-file-fixer` - Makes sure files end in a newline and only a newline. - `fix-encoding-pragma` - Add `# -*- coding: utf-8 -*-` to the top of python files. -- `file-contents-sorter` - Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. +- `file-contents-sorter` - Sort the lines in specified files (defaults to alphabetical). You must provide list of target files as input to it. Note that this hook WILL remove blank lines and does NOT respect any comments. - To remove the coding pragma pass `--remove` (useful in a python3-only codebase) - `flake8` - Run flake8 on your python files. - `forbid-new-submodules` - Prevent addition of new git submodules. From 7102e0c8a3db26c25a3795b098258c02c74649af Mon Sep 17 00:00:00 2001 From: Daniel Gallagher Date: Sun, 25 Jun 2017 19:51:50 -0700 Subject: [PATCH 3/3] file-contents-sorter should add newline at end of files missing newlines Make an explicit 'else' path for readability --- pre_commit_hooks/file_contents_sorter.py | 19 ++++++++++--------- tests/file_contents_sorter_test.py | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index b66cc72..fe7f7ee 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -18,18 +18,19 @@ FAIL = 1 def sort_file_contents(f): - before = [line.strip(b'\n\r') for line in f if line.strip()] - after = sorted(before) - - if before == after: - return PASS + before = list(f) + after = sorted([line.strip(b'\n\r') for line in before if line.strip()]) + before_string = b''.join(before) after_string = b'\n'.join(after) + b'\n' - f.seek(0) - f.write(after_string) - f.truncate() - return FAIL + if before_string == after_string: + return PASS + else: + f.seek(0) + f.write(after_string) + f.truncate() + return FAIL def main(argv=None): diff --git a/tests/file_contents_sorter_test.py b/tests/file_contents_sorter_test.py index b635eb0..2c85c8a 100644 --- a/tests/file_contents_sorter_test.py +++ b/tests/file_contents_sorter_test.py @@ -8,18 +8,18 @@ from pre_commit_hooks.file_contents_sorter import PASS @pytest.mark.parametrize( ('input_s', 'expected_retval', 'output'), ( - (b'', PASS, b''), + (b'', FAIL, b'\n'), (b'lonesome\n', PASS, b'lonesome\n'), - (b'missing_newline', PASS, b'missing_newline'), + (b'missing_newline', FAIL, b'missing_newline\n'), (b'newline\nmissing', FAIL, b'missing\nnewline\n'), - (b'missing\nnewline', PASS, b'missing\nnewline'), + (b'missing\nnewline', FAIL, b'missing\nnewline\n'), (b'alpha\nbeta\n', PASS, b'alpha\nbeta\n'), (b'beta\nalpha\n', FAIL, b'alpha\nbeta\n'), (b'C\nc\n', PASS, b'C\nc\n'), (b'c\nC\n', FAIL, b'C\nc\n'), (b'mag ical \n tre vor\n', FAIL, b' tre vor\nmag ical \n'), (b'@\n-\n_\n#\n', FAIL, b'#\n-\n@\n_\n'), - (b'extra\n\n\nwhitespace\n', PASS, b'extra\n\n\nwhitespace\n'), + (b'extra\n\n\nwhitespace\n', FAIL, b'extra\nwhitespace\n'), (b'whitespace\n\n\nextra\n', FAIL, b'extra\nwhitespace\n'), ) )