Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #326: Handle CRLF in end-of-file-fixer #327

Merged
merged 3 commits into from
Oct 13, 2018

Conversation

mtkennerly
Copy link
Contributor

@mtkennerly mtkennerly commented Oct 13, 2018

I'm not sure if it's a problem that this approach always replaces a final \r\n with \n, if that could conflict with the mixed-line-ending hook or Git settings. On one hand, the existing implementation always wrote \n if there was no final line break, so this is consistent with that, but then another hook could convert that \n to \r\n, and this hook would have just ignored it.

@@ -15,6 +15,8 @@
(b'foo', 1, b'foo\n'),
(b'foo\n\n\n', 1, b'foo\n'),
(b'\xe2\x98\x83', 1, b'\xe2\x98\x83\n'),
(b'foo\r\n', 1, b'foo\n'),
(b'foo\r\n\r\n', 1, b'foo\n'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, it would be better if it kept the \r\n at the end -- is it difficult to adjust the logic to do that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably do something like:

if eof.count(b'\r') == len(eof):
    # append b'\r' and truncate
elif eof.count(b'\n') < len(eof):
    # append b'\r\n' and truncate
else:
    # append b'\n' and truncate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick response on this. I'll get it updated.

@asottile
Copy link
Member

lmk and I can just push it, here's a patch on top of yours which supports \r linebreaks as well:

diff --git a/pre_commit_hooks/end_of_file_fixer.py b/pre_commit_hooks/end_of_file_fixer.py
index 37ebbb5..5ab1b7b 100644
--- a/pre_commit_hooks/end_of_file_fixer.py
+++ b/pre_commit_hooks/end_of_file_fixer.py
@@ -15,13 +15,13 @@ def fix_file(file_obj):
         return 0
     last_character = file_obj.read(1)
     # last_character will be '' for an empty file
-    if last_character != b'\n' and last_character != b'':
+    if last_character not in {b'\n', b'\r'} and last_character != b'':
         # Needs this seek for windows, otherwise IOError
         file_obj.seek(0, os.SEEK_END)
         file_obj.write(b'\n')
         return 1
 
-    while last_character == b'\n' or last_character == b'\r':
+    while last_character in {b'\n', b'\r'}:
         # Deal with the beginning of the file
         if file_obj.tell() == 1:
             # If we've reached the beginning of the file and it is all
@@ -38,8 +38,10 @@ def fix_file(file_obj):
     # newlines.  If we find extraneous newlines, then backtrack and trim them.
     position = file_obj.tell()
     remaining = file_obj.read()
-    for sequence in [b'\n', b'\r\n']:
-        if remaining.startswith(sequence) and len(remaining) > len(sequence):
+    for sequence in (b'\n', b'\r\n', b'\r'):
+        if remaining == sequence:
+            return 0
+        elif remaining.startswith(sequence):
             file_obj.seek(position + len(sequence))
             file_obj.truncate()
             return 1
diff --git a/tests/end_of_file_fixer_test.py b/tests/end_of_file_fixer_test.py
index deedeab..f8710af 100644
--- a/tests/end_of_file_fixer_test.py
+++ b/tests/end_of_file_fixer_test.py
@@ -17,6 +17,8 @@ TESTS = (
     (b'\xe2\x98\x83', 1, b'\xe2\x98\x83\n'),
     (b'foo\r\n', 0, b'foo\r\n'),
     (b'foo\r\n\r\n\r\n', 1, b'foo\r\n'),
+    (b'foo\r', 0, b'foo\r'),
+    (b'foo\r\r\r\r', 1, b'foo\r'),
 )
 

@asottile asottile merged commit cb2bc2e into pre-commit:master Oct 13, 2018
@asottile
Copy link
Member

Thanks again for the report and the fix 🎉

@mtkennerly mtkennerly deleted the bugfix/eol-crlf branch October 13, 2018 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants