Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: patch.py

Issue 6055005: Add a function to detect patches that can't be safely applied. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/commit-queue
Patch Set: Rebase against trunk Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pending_manager.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « no previous file | pending_manager.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698