| 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 |