| Index: patch.py
|
| diff --git a/patch.py b/patch.py
|
| index af18ee43e212583815d27d138d1fc426883eb663..cc86d343e011b1985dfb7c724b15ad06f1af91e2 100644
|
| --- a/patch.py
|
| +++ b/patch.py
|
| @@ -1,8 +1,10 @@
|
| +# coding=utf8
|
| # Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
| """Utility functions to handle patches."""
|
|
|
| +import logging
|
| import re
|
| import subprocess2
|
|
|
| @@ -29,3 +31,68 @@ def apply_patch(location, patch):
|
| cmd = ['patch', '-p0', '--forward', '--force']
|
| subprocess2.check_call(cmd, stdin=patch, cwd=location)
|
|
|
| +
|
| +def verify_patch(patch_data):
|
| + """Verifies if a patch can be applied.
|
| +
|
| + Returns a string if the patch can't be applied explaining the issue.
|
| + """
|
| + lines = patch_data.splitlines(False)
|
| + svn_separator = (
|
| + '___________________________________________________________________')
|
| +
|
| + index = 0
|
| +
|
| + def next_line(i):
|
| + if index+i >= len(lines):
|
| + return ''
|
| + return lines[index+i]
|
| +
|
| + for index, line in enumerate(lines):
|
| + if line == svn_separator:
|
| + # Look for the next line.
|
| + # TODO: If we ever hit non English patches, we need to
|
| + # use something like re.match(ur'^\w+$', u'Modifié', re.UNICODE)
|
| + m = re.match(r'^(\w+)\s*\:\s*svn\:([\w\-]+)$', next_line(1))
|
| + if not m:
|
| + # The patch confused the script;
|
| + continue
|
| + prop = m.group(2)
|
| + if prop in ('mergeinfo', 'executable', 'ignore'):
|
| + # In practice, executable should be treated like eol-style, assuming we
|
| + # lookup auto-props.
|
| + return 'Can\'t apply svn property svn:%s' % prop
|
| + elif prop in ('eol-style', 'mime-type'):
|
| + # Silently ignore it, assume that the auto-props are ok.
|
| + # TODO: Verify the auto-props would trigger.
|
| + continue
|
| + else:
|
| + # Unknown property
|
| + logging.error('Unknown property %s' % prop)
|
| + continue
|
| + m = re.match(r'^Index\:\s*(.+)$', line)
|
| + if m:
|
| + # We need to find --- on the next 3 lines otherwise discard the patch.
|
| + if next_line(1).startswith('--- '):
|
| + continue
|
| + if not next_line(1):
|
| + return 'Can\'t patch empty file (svn)'
|
| + if next_line(2).startswith('--- '):
|
| + continue
|
| + if not next_line(2):
|
| + return 'Can\'t patch empty file (svn)'
|
| + if next_line(3).startswith('--- '):
|
| + continue
|
| + if not next_line(3):
|
| + return 'Can\'t patch empty file (svn)'
|
| + if next_line(4).startswith('--- '):
|
| + # See testSupported3() for a real-world example.
|
| + continue
|
| + return 'Can\'t patch empty file (svn)'
|
| + m = re.match(r'diff \-\-git (.*)$', line)
|
| + if m:
|
| + if not next_line(1):
|
| + return 'Can\'t patch empty file (git)'
|
| + if next_line(1).startswith('old mode '):
|
| + return 'Unsupported git file mode change'
|
| + return None
|
|
|