| 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 # Cheap check to make sure the file name is at least mentioned in the | 209 # Cheap check to make sure the file name is at least mentioned in the |
| 210 # 'diff' header. That the only remaining invariant. | 210 # 'diff' header. That the only remaining invariant. |
| 211 if not self.filename in self.diff_header: | 211 if not self.filename in self.diff_header: |
| 212 self._fail('Diff seems corrupted.') | 212 self._fail('Diff seems corrupted.') |
| 213 | 213 |
| 214 def _verify_git_header_process_line(self, lines, line, last_line, old, new): | 214 def _verify_git_header_process_line(self, lines, line, last_line, old, new): |
| 215 """Processes a single line of the header. | 215 """Processes a single line of the header. |
| 216 | 216 |
| 217 Returns True if it should continue looping. | 217 Returns True if it should continue looping. |
| 218 |
| 219 Format is described to |
| 220 http://www.kernel.org/pub/software/scm/git/docs/git-diff.html |
| 218 """ | 221 """ |
| 219 # Handle these: | |
| 220 # rename from <> | |
| 221 # copy from <> | |
| 222 match = re.match(r'^(rename|copy) from (.+)$', line) | 222 match = re.match(r'^(rename|copy) from (.+)$', line) |
| 223 if match: | 223 if match: |
| 224 if old != match.group(2): | 224 if old != match.group(2): |
| 225 self._fail('Unexpected git diff input name for line %s.' % line) | 225 self._fail('Unexpected git diff input name for line %s.' % line) |
| 226 if not lines or not lines[0].startswith('%s to ' % match.group(1)): | 226 if not lines or not lines[0].startswith('%s to ' % match.group(1)): |
| 227 self._fail( | 227 self._fail( |
| 228 'Confused %s from/to git diff for line %s.' % | 228 'Confused %s from/to git diff for line %s.' % |
| 229 (match.group(1), line)) | 229 (match.group(1), line)) |
| 230 return | 230 return |
| 231 | 231 |
| 232 # Handle these: | |
| 233 # rename to <> | |
| 234 # copy to <> | |
| 235 match = re.match(r'^(rename|copy) to (.+)$', line) | 232 match = re.match(r'^(rename|copy) to (.+)$', line) |
| 236 if match: | 233 if match: |
| 237 if new != match.group(2): | 234 if new != match.group(2): |
| 238 self._fail('Unexpected git diff output name for line %s.' % line) | 235 self._fail('Unexpected git diff output name for line %s.' % line) |
| 239 if not last_line.startswith('%s from ' % match.group(1)): | 236 if not last_line.startswith('%s from ' % match.group(1)): |
| 240 self._fail( | 237 self._fail( |
| 241 'Confused %s from/to git diff for line %s.' % | 238 'Confused %s from/to git diff for line %s.' % |
| 242 (match.group(1), line)) | 239 (match.group(1), line)) |
| 243 return | 240 return |
| 244 | 241 |
| 245 # Handle "new file mode \d{6}" | 242 match = re.match(r'^new(| file) mode (\d{6})$', line) |
| 246 match = re.match(r'^new file mode (\d{6})$', line) | |
| 247 if match: | 243 if match: |
| 248 mode = match.group(1) | 244 mode = match.group(2) |
| 249 # Only look at owner ACL for executable. | 245 # Only look at owner ACL for executable. |
| 246 # TODO(maruel): Add support to remove a property. |
| 250 if bool(int(mode[4]) & 1): | 247 if bool(int(mode[4]) & 1): |
| 251 self.svn_properties.append(('svn:executable', '*')) | 248 self.svn_properties.append(('svn:executable', '*')) |
| 252 | 249 |
| 253 # Handle "--- " | |
| 254 match = re.match(r'^--- (.*)$', line) | 250 match = re.match(r'^--- (.*)$', line) |
| 255 if match: | 251 if match: |
| 256 if last_line[:3] in ('---', '+++'): | 252 if last_line[:3] in ('---', '+++'): |
| 257 self._fail('--- and +++ are reversed') | 253 self._fail('--- and +++ are reversed') |
| 258 self.is_new = match.group(1) == '/dev/null' | 254 self.is_new = match.group(1) == '/dev/null' |
| 259 # TODO(maruel): Use self.source_file. | 255 # TODO(maruel): Use self.source_file. |
| 260 if old != self.mangle(match.group(1)) and match.group(1) != '/dev/null': | 256 if old != self.mangle(match.group(1)) and match.group(1) != '/dev/null': |
| 261 self._fail('Unexpected git diff: %s != %s.' % (old, match.group(1))) | 257 self._fail('Unexpected git diff: %s != %s.' % (old, match.group(1))) |
| 262 if not lines or not lines[0].startswith('+++'): | 258 if not lines or not lines[0].startswith('+++'): |
| 263 self._fail('Missing git diff output name.') | 259 self._fail('Missing git diff output name.') |
| 264 return | 260 return |
| 265 | 261 |
| 266 # Handle "+++ " | |
| 267 match = re.match(r'^\+\+\+ (.*)$', line) | 262 match = re.match(r'^\+\+\+ (.*)$', line) |
| 268 if match: | 263 if match: |
| 269 if not last_line.startswith('---'): | 264 if not last_line.startswith('---'): |
| 270 self._fail('Unexpected git diff: --- not following +++.') | 265 self._fail('Unexpected git diff: --- not following +++.') |
| 271 # TODO(maruel): new == self.filename. | 266 # TODO(maruel): new == self.filename. |
| 272 if new != self.mangle(match.group(1)) and '/dev/null' != match.group(1): | 267 if new != self.mangle(match.group(1)) and '/dev/null' != match.group(1): |
| 273 # TODO(maruel): Can +++ be /dev/null? If so, assert self.is_delete == | 268 # TODO(maruel): Can +++ be /dev/null? If so, assert self.is_delete == |
| 274 # True. | 269 # True. |
| 275 self._fail('Unexpected git diff: %s != %s.' % (new, match.group(1))) | 270 self._fail('Unexpected git diff: %s != %s.' % (new, match.group(1))) |
| 276 if lines: | 271 if lines: |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 for patch in self.patches: | 342 for patch in self.patches: |
| 348 patch.set_relpath(relpath) | 343 patch.set_relpath(relpath) |
| 349 | 344 |
| 350 def __iter__(self): | 345 def __iter__(self): |
| 351 for patch in self.patches: | 346 for patch in self.patches: |
| 352 yield patch | 347 yield patch |
| 353 | 348 |
| 354 @property | 349 @property |
| 355 def filenames(self): | 350 def filenames(self): |
| 356 return [p.filename for p in self.patches] | 351 return [p.filename for p in self.patches] |
| OLD | NEW |