OLD | NEW |
1 # coding=utf8 | 1 # coding=utf8 |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 """Utility functions to handle patches.""" | 5 """Utility functions to handle patches.""" |
6 | 6 |
7 import posixpath | 7 import posixpath |
8 import os | 8 import os |
9 import re | 9 import re |
10 | 10 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 if old == 'dev/null' and new == 'dev/null': | 214 if old == 'dev/null' and new == 'dev/null': |
215 self._fail('Unexpected /dev/null git diff.') | 215 self._fail('Unexpected /dev/null git diff.') |
216 break | 216 break |
217 | 217 |
218 if not old or not new: | 218 if not old or not new: |
219 self._fail('Unexpected git diff; couldn\'t find git header.') | 219 self._fail('Unexpected git diff; couldn\'t find git header.') |
220 | 220 |
221 if old not in (self.filename, 'dev/null'): | 221 if old not in (self.filename, 'dev/null'): |
222 # Copy or rename. | 222 # Copy or rename. |
223 self.source_filename = old | 223 self.source_filename = old |
| 224 self.is_new = True |
224 | 225 |
225 last_line = '' | 226 last_line = '' |
226 | 227 |
227 while lines: | 228 while lines: |
228 line = lines.pop(0) | 229 line = lines.pop(0) |
229 self._verify_git_header_process_line(lines, line, last_line) | 230 self._verify_git_header_process_line(lines, line, last_line) |
230 last_line = line | 231 last_line = line |
231 | 232 |
232 # Cheap check to make sure the file name is at least mentioned in the | 233 # Cheap check to make sure the file name is at least mentioned in the |
233 # 'diff' header. That the only remaining invariant. | 234 # 'diff' header. That the only remaining invariant. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 mode = match.group(2) | 269 mode = match.group(2) |
269 # Only look at owner ACL for executable. | 270 # Only look at owner ACL for executable. |
270 # TODO(maruel): Add support to remove a property. | 271 # TODO(maruel): Add support to remove a property. |
271 if bool(int(mode[4]) & 1): | 272 if bool(int(mode[4]) & 1): |
272 self.svn_properties.append(('svn:executable', '*')) | 273 self.svn_properties.append(('svn:executable', '*')) |
273 | 274 |
274 match = re.match(r'^--- (.*)$', line) | 275 match = re.match(r'^--- (.*)$', line) |
275 if match: | 276 if match: |
276 if last_line[:3] in ('---', '+++'): | 277 if last_line[:3] in ('---', '+++'): |
277 self._fail('--- and +++ are reversed') | 278 self._fail('--- and +++ are reversed') |
278 self.is_new = match.group(1) == '/dev/null' | 279 if match.group(1) == '/dev/null': |
279 # TODO(maruel): Use self.source_file. | 280 self.is_new = True |
280 if self.mangle(match.group(1)) not in (old, 'dev/null'): | 281 elif self.mangle(match.group(1)) != old: |
| 282 # git patches are always well formatted, do not allow random filenames. |
281 self._fail('Unexpected git diff: %s != %s.' % (old, match.group(1))) | 283 self._fail('Unexpected git diff: %s != %s.' % (old, match.group(1))) |
282 if not lines or not lines[0].startswith('+++'): | 284 if not lines or not lines[0].startswith('+++'): |
283 self._fail('Missing git diff output name.') | 285 self._fail('Missing git diff output name.') |
284 return | 286 return |
285 | 287 |
286 match = re.match(r'^\+\+\+ (.*)$', line) | 288 match = re.match(r'^\+\+\+ (.*)$', line) |
287 if match: | 289 if match: |
288 if not last_line.startswith('---'): | 290 if not last_line.startswith('---'): |
289 self._fail('Unexpected git diff: --- not following +++.') | 291 self._fail('Unexpected git diff: --- not following +++.') |
290 # TODO(maruel): new == self.filename. | |
291 if '/dev/null' == match.group(1): | 292 if '/dev/null' == match.group(1): |
292 self.is_delete = True | 293 self.is_delete = True |
293 elif self.filename != self.mangle(match.group(1)): | 294 elif self.filename != self.mangle(match.group(1)): |
294 self._fail( | 295 self._fail( |
295 'Unexpected git diff: %s != %s.' % (self.filename, match.group(1))) | 296 'Unexpected git diff: %s != %s.' % (self.filename, match.group(1))) |
296 if lines: | 297 if lines: |
297 self._fail('Crap after +++') | 298 self._fail('Crap after +++') |
298 # We're done. | 299 # We're done. |
299 return | 300 return |
300 | 301 |
(...skipping 19 matching lines...) Expand all Loading... |
320 | 321 |
321 def _verify_svn_header_process_line(self, lines, line, last_line): | 322 def _verify_svn_header_process_line(self, lines, line, last_line): |
322 """Processes a single line of the header. | 323 """Processes a single line of the header. |
323 | 324 |
324 Returns True if it should continue looping. | 325 Returns True if it should continue looping. |
325 """ | 326 """ |
326 match = re.match(r'^--- ([^\t]+).*$', line) | 327 match = re.match(r'^--- ([^\t]+).*$', line) |
327 if match: | 328 if match: |
328 if last_line[:3] in ('---', '+++'): | 329 if last_line[:3] in ('---', '+++'): |
329 self._fail('--- and +++ are reversed') | 330 self._fail('--- and +++ are reversed') |
330 self.is_new = match.group(1) == '/dev/null' | 331 if match.group(1) == '/dev/null': |
331 if (self.mangle(match.group(1)) != self.filename and | 332 self.is_new = True |
332 match.group(1) != '/dev/null'): | 333 elif self.mangle(match.group(1)) != self.filename: |
| 334 # guess the source filename. |
333 self.source_filename = match.group(1) | 335 self.source_filename = match.group(1) |
| 336 self.is_new = True |
334 if not lines or not lines[0].startswith('+++'): | 337 if not lines or not lines[0].startswith('+++'): |
335 self._fail('Nothing after header.') | 338 self._fail('Nothing after header.') |
336 return | 339 return |
337 | 340 |
338 match = re.match(r'^\+\+\+ ([^\t]+).*$', line) | 341 match = re.match(r'^\+\+\+ ([^\t]+).*$', line) |
339 if match: | 342 if match: |
340 if not last_line.startswith('---'): | 343 if not last_line.startswith('---'): |
341 self._fail('Unexpected diff: --- not following +++.') | 344 self._fail('Unexpected diff: --- not following +++.') |
342 if match.group(1) == '/dev/null': | 345 if match.group(1) == '/dev/null': |
343 self.is_delete = True | 346 self.is_delete = True |
(...skipping 18 matching lines...) Expand all Loading... |
362 for patch in self.patches: | 365 for patch in self.patches: |
363 patch.set_relpath(relpath) | 366 patch.set_relpath(relpath) |
364 | 367 |
365 def __iter__(self): | 368 def __iter__(self): |
366 for patch in self.patches: | 369 for patch in self.patches: |
367 yield patch | 370 yield patch |
368 | 371 |
369 @property | 372 @property |
370 def filenames(self): | 373 def filenames(self): |
371 return [p.filename for p in self.patches] | 374 return [p.filename for p in self.patches] |
OLD | NEW |