Jason R. Coombs avatar Jason R. Coombs committed f9cf55b

Fixes #10639: reindent.py should not convert newlines
Backport of changeset 070dc6e359fb, reindent.py now will use the newline detected in the original file and will report an error if mixed newlines are encountered.

Comments (0)

Files changed (2)

   functions (*BSD and OS X).  Also add new stat file flags for OS X
   (UF_HIDDEN and UF_COMPRESSED).
 
+Tools/Demos
+-----------
+
+- Issue #10639: reindent.py no longer converts newlines and will raise
+  an error if attempting to convert a file with mixed newlines.
+
 Tests
 -----
 

Tools/scripts/reindent.py

 
 The backup file is a copy of the one that is being reindented. The ".bak"
 file is generated with shutil.copy(), but some corner cases regarding
-user/group and permissions could leave the backup file more readable that
+user/group and permissions could leave the backup file more readable than
 you'd prefer. You can always use the --nobackup option to prevent this.
 """
 
 import tokenize
 import os, shutil
 import sys
+import io
 
 verbose    = 0
 recurse    = 0
     if verbose:
         print "checking", file, "...",
     try:
-        f = open(file)
+        f = io.open(file)
     except IOError, msg:
         errprint("%s: I/O Error: %s" % (file, str(msg)))
         return
 
     r = Reindenter(f)
     f.close()
+
+    newline = r.newlines
+    if isinstance(newline, tuple):
+        errprint("%s: mixed newlines detected; cannot process file" % file)
+        return
+
     if r.run():
         if verbose:
             print "changed."
                 shutil.copyfile(file, bak)
                 if verbose:
                     print "backed up", file, "to", bak
-            f = open(file, "w")
+            f = io.open(file, "w", newline=newline)
             r.write(f)
             f.close()
             if verbose:
         # indeed, they're our headache!
         self.stats = []
 
+        # Save the newlines found in the file so they can be used to
+        #  create output without mutating the newlines.
+        self.newlines = f.newlines
+
     def run(self):
         tokenize.tokenize(self.getline, self.tokeneater)
         # Remove trailing empty lines.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.