1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
Description: Support the No newline at end of file marker
Author: SnakE <snake.scaly@gmail.com>
Applied-Upstream: commit:52fd21d3330d5fdd9664c3912264e9301880d9c7
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/tests/samples/sample3.diff
+++ b/tests/samples/sample3.diff
@@ -19,8 +19,9 @@
+
+This is a new line.
- This will stay.
+-This will stay.
\ No newline at end of file
++This will stay.
=== removed file 'removed_file'
--- removed_file 2013-10-13 23:53:13 +0000
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -68,6 +68,20 @@
added_unicode_line = res.added_files[0][0][1]
self.assertEqual(added_unicode_line.value, 'holá mundo!\n')
+ def test_no_newline_at_end_of_file(self):
+ utf8_file = os.path.join(self.samples_dir, 'samples/sample3.diff')
+ with open(utf8_file, 'rb') as diff_file:
+ res = PatchSet(diff_file, encoding='utf-8')
+
+ # 3 files updated by diff
+ self.assertEqual(len(res), 3)
+ added_unicode_line = res.added_files[0][0][4]
+ self.assertEqual(added_unicode_line.line_type, '\\')
+ self.assertEqual(added_unicode_line.value, ' No newline at end of file\n')
+ added_unicode_line = res.modified_files[0][0][8]
+ self.assertEqual(added_unicode_line.line_type, '\\')
+ self.assertEqual(added_unicode_line.value, ' No newline at end of file\n')
+
def test_preserve_dos_line_endings(self):
utf8_file = os.path.join(self.samples_dir, 'samples/sample4.diff')
with open(utf8_file, 'rb') as diff_file:
--- a/unidiff/constants.py
+++ b/unidiff/constants.py
@@ -42,12 +42,16 @@
# \n empty line (treat like context)
# + added line
# - deleted line
-# \ No newline case (ignore)
+# \ No newline case
RE_HUNK_BODY_LINE = re.compile(r'^(?P<line_type>[- \n\+\\])(?P<value>.*)', re.DOTALL)
+RE_NO_NEWLINE_MARKER = re.compile(r'^\\ No newline at end of file')
+
DEFAULT_ENCODING = 'UTF-8'
LINE_TYPE_ADDED = '+'
LINE_TYPE_REMOVED = '-'
LINE_TYPE_CONTEXT = ' '
LINE_TYPE_EMPTY = '\n'
+LINE_TYPE_NO_NEWLINE = '\\'
+LINE_VALUE_NO_NEWLINE = ' No newline at end of file'
--- a/unidiff/patch.py
+++ b/unidiff/patch.py
@@ -35,10 +35,13 @@
LINE_TYPE_CONTEXT,
LINE_TYPE_EMPTY,
LINE_TYPE_REMOVED,
+ LINE_TYPE_NO_NEWLINE,
+ LINE_VALUE_NO_NEWLINE,
RE_HUNK_BODY_LINE,
RE_HUNK_HEADER,
RE_SOURCE_FILENAME,
RE_TARGET_FILENAME,
+ RE_NO_NEWLINE_MARKER,
)
from unidiff.errors import UnidiffParseError
@@ -208,6 +211,8 @@
target_line_no += 1
original_line.source_line_no = source_line_no
source_line_no += 1
+ elif line_type == LINE_TYPE_NO_NEWLINE:
+ pass
else:
original_line = None
@@ -222,6 +227,12 @@
self.append(hunk)
+ def _add_no_newline_marker_to_last_hunk(self):
+ if not self:
+ raise UnidiffParseError('Unexpected marker:' + LINE_VALUE_NO_NEWLINE)
+ last_hunk = self[-1]
+ last_hunk.append(Line(LINE_VALUE_NO_NEWLINE + '\n', line_type=LINE_TYPE_NO_NEWLINE))
+
@property
def path(self):
"""Return the file path abstracted from VCS."""
@@ -319,6 +330,13 @@
raise UnidiffParseError('Unexpected hunk found: %s' % line)
current_file._parse_hunk(line, diff, encoding)
+ # check for no newline marker
+ is_no_newline = RE_NO_NEWLINE_MARKER.match(line)
+ if is_no_newline:
+ if current_file is None:
+ raise UnidiffParseError('Unexpected marker: %s' % line)
+ current_file._add_no_newline_marker_to_last_hunk()
+
@classmethod
def from_filename(cls, filename, encoding=DEFAULT_ENCODING, errors=None):
"""Return a PatchSet instance given a diff filename."""
|