1731.1.5
by Aaron Bentley
Restore test_patches_data |
1 |
--- orig-6 2005-09-23 16:27:16.000000000 -0500
|
2 |
+++ mod-6 2005-09-23 16:27:32.000000000 -0500
|
|
3 |
@@ -1,558 +1 @@
|
|
4 |
-# Copyright (C) 2004, 2005 Aaron Bentley
|
|
5 |
-# <aaron.bentley@utoronto.ca>
|
|
6 |
-#
|
|
7 |
-# This program is free software; you can redistribute it and/or modify
|
|
8 |
-# it under the terms of the GNU General Public License as published by
|
|
9 |
-# the Free Software Foundation; either version 2 of the License, or
|
|
10 |
-# (at your option) any later version.
|
|
11 |
-#
|
|
12 |
-# This program is distributed in the hope that it will be useful,
|
|
13 |
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 |
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 |
-# GNU General Public License for more details.
|
|
16 |
-#
|
|
17 |
-# You should have received a copy of the GNU General Public License
|
|
18 |
-# along with this program; if not, write to the Free Software
|
|
19 |
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
20 |
-
|
|
21 |
-class PatchSyntax(Exception):
|
|
22 |
- def __init__(self, msg):
|
|
23 |
- Exception.__init__(self, msg)
|
|
24 |
-
|
|
25 |
-
|
|
26 |
-class MalformedPatchHeader(PatchSyntax):
|
|
27 |
- def __init__(self, desc, line):
|
|
28 |
- self.desc = desc
|
|
29 |
- self.line = line
|
|
30 |
- msg = "Malformed patch header. %s\n%r" % (self.desc, self.line)
|
|
31 |
- PatchSyntax.__init__(self, msg)
|
|
32 |
-
|
|
33 |
-class MalformedHunkHeader(PatchSyntax):
|
|
34 |
- def __init__(self, desc, line):
|
|
35 |
- self.desc = desc
|
|
36 |
- self.line = line
|
|
37 |
- msg = "Malformed hunk header. %s\n%r" % (self.desc, self.line)
|
|
38 |
- PatchSyntax.__init__(self, msg)
|
|
39 |
-
|
|
40 |
-class MalformedLine(PatchSyntax):
|
|
41 |
- def __init__(self, desc, line):
|
|
42 |
- self.desc = desc
|
|
43 |
- self.line = line
|
|
44 |
- msg = "Malformed line. %s\n%s" % (self.desc, self.line)
|
|
45 |
- PatchSyntax.__init__(self, msg)
|
|
46 |
-
|
|
47 |
-def get_patch_names(iter_lines):
|
|
48 |
- try:
|
|
49 |
- line = iter_lines.next()
|
|
50 |
- if not line.startswith("--- "):
|
|
51 |
- raise MalformedPatchHeader("No orig name", line)
|
|
52 |
- else:
|
|
53 |
- orig_name = line[4:].rstrip("\n")
|
|
54 |
- except StopIteration:
|
|
55 |
- raise MalformedPatchHeader("No orig line", "")
|
|
56 |
- try:
|
|
57 |
- line = iter_lines.next()
|
|
58 |
- if not line.startswith("+++ "):
|
|
59 |
- raise PatchSyntax("No mod name")
|
|
60 |
- else:
|
|
61 |
- mod_name = line[4:].rstrip("\n")
|
|
62 |
- except StopIteration:
|
|
63 |
- raise MalformedPatchHeader("No mod line", "")
|
|
64 |
- return (orig_name, mod_name)
|
|
65 |
-
|
|
66 |
-def parse_range(textrange):
|
|
67 |
- """Parse a patch range, handling the "1" special-case
|
|
68 |
-
|
|
69 |
- :param textrange: The text to parse
|
|
70 |
- :type textrange: str
|
|
71 |
- :return: the position and range, as a tuple
|
|
72 |
- :rtype: (int, int)
|
|
73 |
- """
|
|
74 |
- tmp = textrange.split(',')
|
|
75 |
- if len(tmp) == 1:
|
|
76 |
- pos = tmp[0]
|
|
77 |
- range = "1"
|
|
78 |
- else:
|
|
79 |
- (pos, range) = tmp
|
|
80 |
- pos = int(pos)
|
|
81 |
- range = int(range)
|
|
82 |
- return (pos, range)
|
|
83 |
-
|
|
84 |
-
|
|
85 |
-def hunk_from_header(line):
|
|
86 |
- if not line.startswith("@@") or not line.endswith("@@\n") \
|
|
87 |
- or not len(line) > 4:
|
|
88 |
- raise MalformedHunkHeader("Does not start and end with @@.", line)
|
|
89 |
- try:
|
|
90 |
- (orig, mod) = line[3:-4].split(" ")
|
|
91 |
- except Exception, e:
|
|
92 |
- raise MalformedHunkHeader(str(e), line)
|
|
93 |
- if not orig.startswith('-') or not mod.startswith('+'):
|
|
94 |
- raise MalformedHunkHeader("Positions don't start with + or -.", line)
|
|
95 |
- try:
|
|
96 |
- (orig_pos, orig_range) = parse_range(orig[1:])
|
|
97 |
- (mod_pos, mod_range) = parse_range(mod[1:])
|
|
98 |
- except Exception, e:
|
|
99 |
- raise MalformedHunkHeader(str(e), line)
|
|
100 |
- if mod_range < 0 or orig_range < 0:
|
|
101 |
- raise MalformedHunkHeader("Hunk range is negative", line)
|
|
102 |
- return Hunk(orig_pos, orig_range, mod_pos, mod_range)
|
|
103 |
-
|
|
104 |
-
|
|
105 |
-class HunkLine:
|
|
106 |
- def __init__(self, contents):
|
|
107 |
- self.contents = contents
|
|
108 |
-
|
|
109 |
- def get_str(self, leadchar):
|
|
110 |
- if self.contents == "\n" and leadchar == " " and False:
|
|
111 |
- return "\n"
|
|
112 |
- if not self.contents.endswith('\n'):
|
|
113 |
- terminator = '\n' + NO_NL
|
|
114 |
- else:
|
|
115 |
- terminator = ''
|
|
116 |
- return leadchar + self.contents + terminator
|
|
117 |
-
|
|
118 |
-
|
|
119 |
-class ContextLine(HunkLine):
|
|
120 |
- def __init__(self, contents):
|
|
121 |
- HunkLine.__init__(self, contents)
|
|
122 |
-
|
|
123 |
- def __str__(self):
|
|
124 |
- return self.get_str(" ")
|
|
125 |
-
|
|
126 |
-
|
|
127 |
-class InsertLine(HunkLine):
|
|
128 |
- def __init__(self, contents):
|
|
129 |
- HunkLine.__init__(self, contents)
|
|
130 |
-
|
|
131 |
- def __str__(self):
|
|
132 |
- return self.get_str("+")
|
|
133 |
-
|
|
134 |
-
|
|
135 |
-class RemoveLine(HunkLine):
|
|
136 |
- def __init__(self, contents):
|
|
137 |
- HunkLine.__init__(self, contents)
|
|
138 |
-
|
|
139 |
- def __str__(self):
|
|
140 |
- return self.get_str("-")
|
|
141 |
-
|
|
142 |
-NO_NL = '\\ No newline at end of file\n'
|
|
143 |
-__pychecker__="no-returnvalues"
|
|
144 |
-
|
|
145 |
-def parse_line(line):
|
|
146 |
- if line.startswith("\n"):
|
|
147 |
- return ContextLine(line)
|
|
148 |
- elif line.startswith(" "):
|
|
149 |
- return ContextLine(line[1:])
|
|
150 |
- elif line.startswith("+"):
|
|
151 |
- return InsertLine(line[1:])
|
|
152 |
- elif line.startswith("-"):
|
|
153 |
- return RemoveLine(line[1:])
|
|
154 |
- elif line == NO_NL:
|
|
155 |
- return NO_NL
|
|
156 |
- else:
|
|
157 |
- raise MalformedLine("Unknown line type", line)
|
|
158 |
-__pychecker__=""
|
|
159 |
-
|
|
160 |
-
|
|
161 |
-class Hunk:
|
|
162 |
- def __init__(self, orig_pos, orig_range, mod_pos, mod_range):
|
|
163 |
- self.orig_pos = orig_pos
|
|
164 |
- self.orig_range = orig_range
|
|
165 |
- self.mod_pos = mod_pos
|
|
166 |
- self.mod_range = mod_range
|
|
167 |
- self.lines = []
|
|
168 |
-
|
|
169 |
- def get_header(self):
|
|
170 |
- return "@@ -%s +%s @@\n" % (self.range_str(self.orig_pos,
|
|
171 |
- self.orig_range),
|
|
172 |
- self.range_str(self.mod_pos,
|
|
173 |
- self.mod_range))
|
|
174 |
-
|
|
175 |
- def range_str(self, pos, range):
|
|
176 |
- """Return a file range, special-casing for 1-line files.
|
|
177 |
-
|
|
178 |
- :param pos: The position in the file
|
|
179 |
- :type pos: int
|
|
180 |
- :range: The range in the file
|
|
181 |
- :type range: int
|
|
182 |
- :return: a string in the format 1,4 except when range == pos == 1
|
|
183 |
- """
|
|
184 |
- if range == 1:
|
|
185 |
- return "%i" % pos
|
|
186 |
- else:
|
|
187 |
- return "%i,%i" % (pos, range)
|
|
188 |
-
|
|
189 |
- def __str__(self):
|
|
190 |
- lines = [self.get_header()]
|
|
191 |
- for line in self.lines:
|
|
192 |
- lines.append(str(line))
|
|
193 |
- return "".join(lines)
|
|
194 |
-
|
|
195 |
- def shift_to_mod(self, pos):
|
|
196 |
- if pos < self.orig_pos-1:
|
|
197 |
- return 0
|
|
198 |
- elif pos > self.orig_pos+self.orig_range:
|
|
199 |
- return self.mod_range - self.orig_range
|
|
200 |
- else:
|
|
201 |
- return self.shift_to_mod_lines(pos)
|
|
202 |
-
|
|
203 |
- def shift_to_mod_lines(self, pos):
|
|
204 |
- assert (pos >= self.orig_pos-1 and pos <= self.orig_pos+self.orig_range)
|
|
205 |
- position = self.orig_pos-1
|
|
206 |
- shift = 0
|
|
207 |
- for line in self.lines:
|
|
208 |
- if isinstance(line, InsertLine):
|
|
209 |
- shift += 1
|
|
210 |
- elif isinstance(line, RemoveLine):
|
|
211 |
- if position == pos:
|
|
212 |
- return None
|
|
213 |
- shift -= 1
|
|
214 |
- position += 1
|
|
215 |
- elif isinstance(line, ContextLine):
|
|
216 |
- position += 1
|
|
217 |
- if position > pos:
|
|
218 |
- break
|
|
219 |
- return shift
|
|
220 |
-
|
|
221 |
-def iter_hunks(iter_lines):
|
|
222 |
- hunk = None
|
|
223 |
- for line in iter_lines:
|
|
224 |
- if line == "\n":
|
|
225 |
- if hunk is not None:
|
|
226 |
- yield hunk
|
|
227 |
- hunk = None
|
|
228 |
- continue
|
|
229 |
- if hunk is not None:
|
|
230 |
- yield hunk
|
|
231 |
- hunk = hunk_from_header(line)
|
|
232 |
- orig_size = 0
|
|
233 |
- mod_size = 0
|
|
234 |
- while orig_size < hunk.orig_range or mod_size < hunk.mod_range:
|
|
235 |
- hunk_line = parse_line(iter_lines.next())
|
|
236 |
- hunk.lines.append(hunk_line)
|
|
237 |
- if isinstance(hunk_line, (RemoveLine, ContextLine)):
|
|
238 |
- orig_size += 1
|
|
239 |
- if isinstance(hunk_line, (InsertLine, ContextLine)):
|
|
240 |
- mod_size += 1
|
|
241 |
- if hunk is not None:
|
|
242 |
- yield hunk
|
|
243 |
-
|
|
244 |
-class Patch:
|
|
245 |
- def __init__(self, oldname, newname):
|
|
246 |
- self.oldname = oldname
|
|
247 |
- self.newname = newname
|
|
248 |
- self.hunks = []
|
|
249 |
-
|
|
250 |
- def __str__(self):
|
|
251 |
- ret = self.get_header()
|
|
252 |
- ret += "".join([str(h) for h in self.hunks])
|
|
253 |
- return ret
|
|
254 |
-
|
|
255 |
- def get_header(self):
|
|
256 |
- return "--- %s\n+++ %s\n" % (self.oldname, self.newname)
|
|
257 |
-
|
|
258 |
- def stats_str(self):
|
|
259 |
- """Return a string of patch statistics"""
|
|
260 |
- removes = 0
|
|
261 |
- inserts = 0
|
|
262 |
- for hunk in self.hunks:
|
|
263 |
- for line in hunk.lines:
|
|
264 |
- if isinstance(line, InsertLine):
|
|
265 |
- inserts+=1;
|
|
266 |
- elif isinstance(line, RemoveLine):
|
|
267 |
- removes+=1;
|
|
268 |
- return "%i inserts, %i removes in %i hunks" % \
|
|
269 |
- (inserts, removes, len(self.hunks))
|
|
270 |
-
|
|
271 |
- def pos_in_mod(self, position):
|
|
272 |
- newpos = position
|
|
273 |
- for hunk in self.hunks:
|
|
274 |
- shift = hunk.shift_to_mod(position)
|
|
275 |
- if shift is None:
|
|
276 |
- return None
|
|
277 |
- newpos += shift
|
|
278 |
- return newpos
|
|
279 |
-
|
|
280 |
- def iter_inserted(self):
|
|
281 |
- """Iteraties through inserted lines
|
|
282 |
-
|
|
283 |
- :return: Pair of line number, line
|
|
284 |
- :rtype: iterator of (int, InsertLine)
|
|
285 |
- """
|
|
286 |
- for hunk in self.hunks:
|
|
287 |
- pos = hunk.mod_pos - 1;
|
|
288 |
- for line in hunk.lines:
|
|
289 |
- if isinstance(line, InsertLine):
|
|
290 |
- yield (pos, line)
|
|
291 |
- pos += 1
|
|
292 |
- if isinstance(line, ContextLine):
|
|
293 |
- pos += 1
|
|
294 |
-
|
|
295 |
-def parse_patch(iter_lines):
|
|
296 |
- (orig_name, mod_name) = get_patch_names(iter_lines)
|
|
297 |
- patch = Patch(orig_name, mod_name)
|
|
298 |
- for hunk in iter_hunks(iter_lines):
|
|
299 |
- patch.hunks.append(hunk)
|
|
300 |
- return patch
|
|
301 |
-
|
|
302 |
-
|
|
303 |
-def iter_file_patch(iter_lines):
|
|
304 |
- saved_lines = []
|
|
305 |
- for line in iter_lines:
|
|
306 |
- if line.startswith('=== '):
|
|
307 |
- continue
|
|
308 |
- elif line.startswith('--- '):
|
|
309 |
- if len(saved_lines) > 0:
|
|
310 |
- yield saved_lines
|
|
311 |
- saved_lines = []
|
|
312 |
- saved_lines.append(line)
|
|
313 |
- if len(saved_lines) > 0:
|
|
314 |
- yield saved_lines
|
|
315 |
-
|
|
316 |
-
|
|
317 |
-def iter_lines_handle_nl(iter_lines):
|
|
318 |
- """
|
|
319 |
- Iterates through lines, ensuring that lines that originally had no
|
|
320 |
- terminating \n are produced without one. This transformation may be
|
|
321 |
- applied at any point up until hunk line parsing, and is safe to apply
|
|
322 |
- repeatedly.
|
|
323 |
- """
|
|
324 |
- last_line = None
|
|
325 |
- for line in iter_lines:
|
|
326 |
- if line == NO_NL:
|
|
327 |
- assert last_line.endswith('\n')
|
|
328 |
- last_line = last_line[:-1]
|
|
329 |
- line = None
|
|
330 |
- if last_line is not None:
|
|
331 |
- yield last_line
|
|
332 |
- last_line = line
|
|
333 |
- if last_line is not None:
|
|
334 |
- yield last_line
|
|
335 |
-
|
|
336 |
-
|
|
337 |
-def parse_patches(iter_lines):
|
|
338 |
- iter_lines = iter_lines_handle_nl(iter_lines)
|
|
339 |
- return [parse_patch(f.__iter__()) for f in iter_file_patch(iter_lines)]
|
|
340 |
-
|
|
341 |
-
|
|
342 |
-def difference_index(atext, btext):
|
|
343 |
- """Find the indext of the first character that differs betweeen two texts
|
|
344 |
-
|
|
345 |
- :param atext: The first text
|
|
346 |
- :type atext: str
|
|
347 |
- :param btext: The second text
|
|
348 |
- :type str: str
|
|
349 |
- :return: The index, or None if there are no differences within the range
|
|
350 |
- :rtype: int or NoneType
|
|
351 |
- """
|
|
352 |
- length = len(atext)
|
|
353 |
- if len(btext) < length:
|
|
354 |
- length = len(btext)
|
|
355 |
- for i in range(length):
|
|
356 |
- if atext[i] != btext[i]:
|
|
357 |
- return i;
|
|
358 |
- return None
|
|
359 |
-
|
|
360 |
-class PatchConflict(Exception):
|
|
361 |
- def __init__(self, line_no, orig_line, patch_line):
|
|
362 |
- orig = orig_line.rstrip('\n')
|
|
363 |
- patch = str(patch_line).rstrip('\n')
|
|
364 |
- msg = 'Text contents mismatch at line %d. Original has "%s",'\
|
|
365 |
- ' but patch says it should be "%s"' % (line_no, orig, patch)
|
|
366 |
- Exception.__init__(self, msg)
|
|
367 |
-
|
|
368 |
-
|
|
369 |
-def iter_patched(orig_lines, patch_lines):
|
|
370 |
- """Iterate through a series of lines with a patch applied.
|
|
371 |
- This handles a single file, and does exact, not fuzzy patching.
|
|
372 |
- """
|
|
373 |
- if orig_lines is not None:
|
|
374 |
- orig_lines = orig_lines.__iter__()
|
|
375 |
- seen_patch = []
|
|
376 |
- patch_lines = iter_lines_handle_nl(patch_lines.__iter__())
|
|
377 |
- get_patch_names(patch_lines)
|
|
378 |
- line_no = 1
|
|
379 |
- for hunk in iter_hunks(patch_lines):
|
|
380 |
- while line_no < hunk.orig_pos:
|
|
381 |
- orig_line = orig_lines.next()
|
|
382 |
- yield orig_line
|
|
383 |
- line_no += 1
|
|
384 |
- for hunk_line in hunk.lines:
|
|
385 |
- seen_patch.append(str(hunk_line))
|
|
386 |
- if isinstance(hunk_line, InsertLine):
|
|
387 |
- yield hunk_line.contents
|
|
388 |
- elif isinstance(hunk_line, (ContextLine, RemoveLine)):
|
|
389 |
- orig_line = orig_lines.next()
|
|
390 |
- if orig_line != hunk_line.contents:
|
|
391 |
- raise PatchConflict(line_no, orig_line, "".join(seen_patch))
|
|
392 |
- if isinstance(hunk_line, ContextLine):
|
|
393 |
- yield orig_line
|
|
394 |
- else:
|
|
395 |
- assert isinstance(hunk_line, RemoveLine)
|
|
396 |
- line_no += 1
|
|
397 |
-
|
|
398 |
-import unittest
|
|
399 |
-import os.path
|
|
400 |
-class PatchesTester(unittest.TestCase):
|
|
401 |
- def datafile(self, filename):
|
|
402 |
- data_path = os.path.join(os.path.dirname(__file__), "testdata",
|
|
403 |
- filename)
|
|
404 |
- return file(data_path, "rb")
|
|
405 |
-
|
|
406 |
- def testValidPatchHeader(self):
|
|
407 |
- """Parse a valid patch header"""
|
|
408 |
- lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')
|
|
409 |
- (orig, mod) = get_patch_names(lines.__iter__())
|
|
410 |
- assert(orig == "orig/commands.py")
|
|
411 |
- assert(mod == "mod/dommands.py")
|
|
412 |
-
|
|
413 |
- def testInvalidPatchHeader(self):
|
|
414 |
- """Parse an invalid patch header"""
|
|
415 |
- lines = "-- orig/commands.py\n+++ mod/dommands.py".split('\n')
|
|
416 |
- self.assertRaises(MalformedPatchHeader, get_patch_names,
|
|
417 |
- lines.__iter__())
|
|
418 |
-
|
|
419 |
- def testValidHunkHeader(self):
|
|
420 |
- """Parse a valid hunk header"""
|
|
421 |
- header = "@@ -34,11 +50,6 @@\n"
|
|
422 |
- hunk = hunk_from_header(header);
|
|
423 |
- assert (hunk.orig_pos == 34)
|
|
424 |
- assert (hunk.orig_range == 11)
|
|
425 |
- assert (hunk.mod_pos == 50)
|
|
426 |
- assert (hunk.mod_range == 6)
|
|
427 |
- assert (str(hunk) == header)
|
|
428 |
-
|
|
429 |
- def testValidHunkHeader2(self):
|
|
430 |
- """Parse a tricky, valid hunk header"""
|
|
431 |
- header = "@@ -1 +0,0 @@\n"
|
|
432 |
- hunk = hunk_from_header(header);
|
|
433 |
- assert (hunk.orig_pos == 1)
|
|
434 |
- assert (hunk.orig_range == 1)
|
|
435 |
- assert (hunk.mod_pos == 0)
|
|
436 |
- assert (hunk.mod_range == 0)
|
|
437 |
- assert (str(hunk) == header)
|
|
438 |
-
|
|
439 |
- def makeMalformed(self, header):
|
|
440 |
- self.assertRaises(MalformedHunkHeader, hunk_from_header, header)
|
|
441 |
-
|
|
442 |
- def testInvalidHeader(self):
|
|
443 |
- """Parse an invalid hunk header"""
|
|
444 |
- self.makeMalformed(" -34,11 +50,6 \n")
|
|
445 |
- self.makeMalformed("@@ +50,6 -34,11 @@\n")
|
|
446 |
- self.makeMalformed("@@ -34,11 +50,6 @@")
|
|
447 |
- self.makeMalformed("@@ -34.5,11 +50,6 @@\n")
|
|
448 |
- self.makeMalformed("@@-34,11 +50,6@@\n")
|
|
449 |
- self.makeMalformed("@@ 34,11 50,6 @@\n")
|
|
450 |
- self.makeMalformed("@@ -34,11 @@\n")
|
|
451 |
- self.makeMalformed("@@ -34,11 +50,6.5 @@\n")
|
|
452 |
- self.makeMalformed("@@ -34,11 +50,-6 @@\n")
|
|
453 |
-
|
|
454 |
- def lineThing(self,text, type):
|
|
455 |
- line = parse_line(text)
|
|
456 |
- assert(isinstance(line, type))
|
|
457 |
- assert(str(line)==text)
|
|
458 |
-
|
|
459 |
- def makeMalformedLine(self, text):
|
|
460 |
- self.assertRaises(MalformedLine, parse_line, text)
|
|
461 |
-
|
|
462 |
- def testValidLine(self):
|
|
463 |
- """Parse a valid hunk line"""
|
|
464 |
- self.lineThing(" hello\n", ContextLine)
|
|
465 |
- self.lineThing("+hello\n", InsertLine)
|
|
466 |
- self.lineThing("-hello\n", RemoveLine)
|
|
467 |
-
|
|
468 |
- def testMalformedLine(self):
|
|
469 |
- """Parse invalid valid hunk lines"""
|
|
470 |
- self.makeMalformedLine("hello\n")
|
|
471 |
-
|
|
472 |
- def compare_parsed(self, patchtext):
|
|
473 |
- lines = patchtext.splitlines(True)
|
|
474 |
- patch = parse_patch(lines.__iter__())
|
|
475 |
- pstr = str(patch)
|
|
476 |
- i = difference_index(patchtext, pstr)
|
|
477 |
- if i is not None:
|
|
478 |
- print "%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i])
|
|
479 |
- self.assertEqual (patchtext, str(patch))
|
|
480 |
-
|
|
481 |
- def testAll(self):
|
|
482 |
- """Test parsing a whole patch"""
|
|
483 |
- patchtext = """--- orig/commands.py
|
|
484 |
-+++ mod/commands.py
|
|
485 |
-@@ -1337,7 +1337,8 @@
|
|
486 |
-
|
|
487 |
- def set_title(self, command=None):
|
|
488 |
- try:
|
|
489 |
-- version = self.tree.tree_version.nonarch
|
|
490 |
-+ version = pylon.alias_or_version(self.tree.tree_version, self.tree,
|
|
491 |
-+ full=False)
|
|
492 |
- except:
|
|
493 |
- version = "[no version]"
|
|
494 |
- if command is None:
|
|
495 |
-@@ -1983,7 +1984,11 @@
|
|
496 |
- version)
|
|
497 |
- if len(new_merges) > 0:
|
|
498 |
- if cmdutil.prompt("Log for merge"):
|
|
499 |
-- mergestuff = cmdutil.log_for_merge(tree, comp_version)
|
|
500 |
-+ if cmdutil.prompt("changelog for merge"):
|
|
501 |
-+ mergestuff = "Patches applied:\\n"
|
|
502 |
-+ mergestuff += pylon.changelog_for_merge(new_merges)
|
|
503 |
-+ else:
|
|
504 |
-+ mergestuff = cmdutil.log_for_merge(tree, comp_version)
|
|
505 |
- log.description += mergestuff
|
|
506 |
- log.save()
|
|
507 |
- try:
|
|
508 |
-"""
|
|
509 |
- self.compare_parsed(patchtext)
|
|
510 |
-
|
|
511 |
- def testInit(self):
|
|
512 |
- """Handle patches missing half the position, range tuple"""
|
|
513 |
- patchtext = \
|
|
514 |
-"""--- orig/__init__.py
|
|
515 |
-+++ mod/__init__.py
|
|
516 |
-@@ -1 +1,2 @@
|
|
517 |
- __docformat__ = "restructuredtext en"
|
|
518 |
-+__doc__ = An alternate Arch commandline interface
|
|
519 |
-"""
|
|
520 |
- self.compare_parsed(patchtext)
|
|
521 |
-
|
|
522 |
-
|
|
523 |
-
|
|
524 |
- def testLineLookup(self):
|
|
525 |
- import sys
|
|
526 |
- """Make sure we can accurately look up mod line from orig"""
|
|
527 |
- patch = parse_patch(self.datafile("diff"))
|
|
528 |
- orig = list(self.datafile("orig"))
|
|
529 |
- mod = list(self.datafile("mod"))
|
|
530 |
- removals = []
|
|
531 |
- for i in range(len(orig)):
|
|
532 |
- mod_pos = patch.pos_in_mod(i)
|
|
533 |
- if mod_pos is None:
|
|
534 |
- removals.append(orig[i])
|
|
535 |
- continue
|
|
536 |
- assert(mod[mod_pos]==orig[i])
|
|
537 |
- rem_iter = removals.__iter__()
|
|
538 |
- for hunk in patch.hunks:
|
|
539 |
- for line in hunk.lines:
|
|
540 |
- if isinstance(line, RemoveLine):
|
|
541 |
- next = rem_iter.next()
|
|
542 |
- if line.contents != next:
|
|
543 |
- sys.stdout.write(" orig:%spatch:%s" % (next,
|
|
544 |
- line.contents))
|
|
545 |
- assert(line.contents == next)
|
|
546 |
- self.assertRaises(StopIteration, rem_iter.next)
|
|
547 |
-
|
|
548 |
- def testFirstLineRenumber(self):
|
|
549 |
- """Make sure we handle lines at the beginning of the hunk"""
|
|
550 |
- patch = parse_patch(self.datafile("insert_top.patch"))
|
|
551 |
- assert (patch.pos_in_mod(0)==1)
|
|
552 |
-
|
|
553 |
-def test():
|
|
554 |
- patchesTestSuite = unittest.makeSuite(PatchesTester,'test')
|
|
555 |
- runner = unittest.TextTestRunner(verbosity=0)
|
|
556 |
- return runner.run(patchesTestSuite)
|
|
557 |
-
|
|
558 |
-
|
|
559 |
-if __name__ == "__main__":
|
|
560 |
- test()
|
|
561 |
-# arch-tag: d1541a25-eac5-4de9-a476-08a7cecd5683
|
|
562 |
+Total contents change
|