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

Side by Side Diff: checkout.py

Issue 10391033: Improve error message in patch application failure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 8 years, 7 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « apply_issue.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # coding=utf8 1 # coding=utf8
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Manages a project checkout. 5 """Manages a project checkout.
6 6
7 Includes support for svn, git-svn and git. 7 Includes support for svn, git-svn and git.
8 """ 8 """
9 9
10 import ConfigParser 10 import ConfigParser
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 settings[k.strip()] = v.strip() 42 settings[k.strip()] = v.strip()
43 finally: 43 finally:
44 settings_file.close() 44 settings_file.close()
45 except IOError: 45 except IOError:
46 return None 46 return None
47 return settings.get(key, None) 47 return settings.get(key, None)
48 48
49 49
50 class PatchApplicationFailed(Exception): 50 class PatchApplicationFailed(Exception):
51 """Patch failed to be applied.""" 51 """Patch failed to be applied."""
52 def __init__(self, filename, status): 52 def __init__(self, p, status):
53 super(PatchApplicationFailed, self).__init__(filename, status) 53 super(PatchApplicationFailed, self).__init__(p, status)
54 self.filename = filename 54 self.patch = p
55 self.status = status 55 self.status = status
56 56
57 @property
58 def filename(self):
59 if self.patch:
60 return self.patch.filename
61
62 def __str__(self):
63 out = []
64 if self.filename:
65 out.append('Failed to apply patch for %s:' % self.filename)
66 if self.status:
67 out.append(self.status)
68 return '\n'.join(out)
69
57 70
58 class CheckoutBase(object): 71 class CheckoutBase(object):
59 # Set to None to have verbose output. 72 # Set to None to have verbose output.
60 VOID = subprocess2.VOID 73 VOID = subprocess2.VOID
61 74
62 def __init__(self, root_dir, project_name, post_processors): 75 def __init__(self, root_dir, project_name, post_processors):
63 """ 76 """
64 Args: 77 Args:
65 post_processor: list of lambda(checkout, patches) to call on each of the 78 post_processor: list of lambda(checkout, patches) to call on each of the
66 modified files. 79 modified files.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 os.makedirs(full_dir) 146 os.makedirs(full_dir)
134 147
135 filepath = os.path.join(self.project_path, p.filename) 148 filepath = os.path.join(self.project_path, p.filename)
136 if p.is_binary: 149 if p.is_binary:
137 with open(filepath, 'wb') as f: 150 with open(filepath, 'wb') as f:
138 f.write(p.get()) 151 f.write(p.get())
139 else: 152 else:
140 if p.source_filename: 153 if p.source_filename:
141 if not p.is_new: 154 if not p.is_new:
142 raise PatchApplicationFailed( 155 raise PatchApplicationFailed(
143 p.filename, 156 p,
144 'File has a source filename specified but is not new') 157 'File has a source filename specified but is not new')
145 # Copy the file first. 158 # Copy the file first.
146 if os.path.isfile(filepath): 159 if os.path.isfile(filepath):
147 raise PatchApplicationFailed( 160 raise PatchApplicationFailed(
148 p.filename, 'File exist but was about to be overwriten') 161 p, 'File exist but was about to be overwriten')
149 shutil.copy2( 162 shutil.copy2(
150 os.path.join(self.project_path, p.source_filename), filepath) 163 os.path.join(self.project_path, p.source_filename), filepath)
151 if p.diff_hunks: 164 if p.diff_hunks:
152 stdout = subprocess2.check_output( 165 stdout = subprocess2.check_output(
153 ['patch', '-u', '--binary', '-p%s' % p.patchlevel], 166 ['patch', '-u', '--binary', '-p%s' % p.patchlevel],
154 stdin=p.get(False), 167 stdin=p.get(False),
155 stderr=subprocess2.STDOUT, 168 stderr=subprocess2.STDOUT,
156 cwd=self.project_path) 169 cwd=self.project_path)
157 elif p.is_new and not os.path.exists(filepath): 170 elif p.is_new and not os.path.exists(filepath):
158 # There is only a header. Just create the file. 171 # There is only a header. Just create the file.
159 open(filepath, 'w').close() 172 open(filepath, 'w').close()
160 for post in post_processors: 173 for post in post_processors:
161 post(self, p) 174 post(self, p)
162 except OSError, e: 175 except OSError, e:
163 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) 176 raise PatchApplicationFailed(p, '%s%s' % (stdout, e))
164 except subprocess.CalledProcessError, e: 177 except subprocess.CalledProcessError, e:
165 raise PatchApplicationFailed( 178 raise PatchApplicationFailed(
166 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) 179 p, '%s%s' % (stdout, getattr(e, 'stdout', None)))
167 180
168 def commit(self, commit_message, user): 181 def commit(self, commit_message, user):
169 """Stubbed out.""" 182 """Stubbed out."""
170 raise NotImplementedError('RawCheckout can\'t commit') 183 raise NotImplementedError('RawCheckout can\'t commit')
171 184
172 185
173 class SvnConfig(object): 186 class SvnConfig(object):
174 """Parses a svn configuration file.""" 187 """Parses a svn configuration file."""
175 def __init__(self, svn_config_dir=None): 188 def __init__(self, svn_config_dir=None):
176 super(SvnConfig, self).__init__() 189 super(SvnConfig, self).__init__()
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 ['add', dir_to_create, '--force'], credentials=False) 313 ['add', dir_to_create, '--force'], credentials=False)
301 314
302 filepath = os.path.join(self.project_path, p.filename) 315 filepath = os.path.join(self.project_path, p.filename)
303 if p.is_binary: 316 if p.is_binary:
304 with open(filepath, 'wb') as f: 317 with open(filepath, 'wb') as f:
305 f.write(p.get()) 318 f.write(p.get())
306 else: 319 else:
307 if p.source_filename: 320 if p.source_filename:
308 if not p.is_new: 321 if not p.is_new:
309 raise PatchApplicationFailed( 322 raise PatchApplicationFailed(
310 p.filename, 323 p,
311 'File has a source filename specified but is not new') 324 'File has a source filename specified but is not new')
312 # Copy the file first. 325 # Copy the file first.
313 if os.path.isfile(filepath): 326 if os.path.isfile(filepath):
314 raise PatchApplicationFailed( 327 raise PatchApplicationFailed(
315 p.filename, 'File exist but was about to be overwriten') 328 p, 'File exist but was about to be overwriten')
316 self._check_output_svn( 329 self._check_output_svn(
317 [ 330 [
318 'copy', 331 'copy',
319 os.path.join(self.project_path, p.source_filename), 332 os.path.join(self.project_path, p.source_filename),
320 filepath 333 filepath
321 ]) 334 ])
322 if p.diff_hunks: 335 if p.diff_hunks:
323 cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force'] 336 cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force']
324 stdout += subprocess2.check_output( 337 stdout += subprocess2.check_output(
325 cmd, stdin=p.get(False), cwd=self.project_path) 338 cmd, stdin=p.get(False), cwd=self.project_path)
(...skipping 14 matching lines...) Expand all
340 for value in values.split(';'): 353 for value in values.split(';'):
341 if '=' not in value: 354 if '=' not in value:
342 params = [value, '*'] 355 params = [value, '*']
343 else: 356 else:
344 params = value.split('=', 1) 357 params = value.split('=', 1)
345 stdout += self._check_output_svn( 358 stdout += self._check_output_svn(
346 ['propset'] + params + [p.filename], credentials=False) 359 ['propset'] + params + [p.filename], credentials=False)
347 for post in post_processors: 360 for post in post_processors:
348 post(self, p) 361 post(self, p)
349 except OSError, e: 362 except OSError, e:
350 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) 363 raise PatchApplicationFailed(p, '%s%s' % (stdout, e))
351 except subprocess.CalledProcessError, e: 364 except subprocess.CalledProcessError, e:
352 raise PatchApplicationFailed( 365 raise PatchApplicationFailed(
353 p.filename, 366 p,
354 'While running %s;\n%s%s' % ( 367 'While running %s;\n%s%s' % (
355 ' '.join(e.cmd), stdout, getattr(e, 'stdout', ''))) 368 ' '.join(e.cmd), stdout, getattr(e, 'stdout', '')))
356 369
357 def commit(self, commit_message, user): 370 def commit(self, commit_message, user):
358 logging.info('Committing patch for %s' % user) 371 logging.info('Committing patch for %s' % user)
359 assert self.commit_user 372 assert self.commit_user
360 assert isinstance(commit_message, unicode) 373 assert isinstance(commit_message, unicode)
361 handle, commit_filename = tempfile.mkstemp(text=True) 374 handle, commit_filename = tempfile.mkstemp(text=True)
362 try: 375 try:
363 # Shouldn't assume default encoding is UTF-8. But really, if you are using 376 # Shouldn't assume default encoding is UTF-8. But really, if you are using
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 # handled. 509 # handled.
497 if not prop[0] in ( 510 if not prop[0] in (
498 'svn:eol-style', 'svn:executable', 'svn:mime-type'): 511 'svn:eol-style', 'svn:executable', 'svn:mime-type'):
499 raise patch.UnsupportedPatchFormat( 512 raise patch.UnsupportedPatchFormat(
500 p.filename, 513 p.filename,
501 'Cannot apply svn property %s to file %s.' % ( 514 'Cannot apply svn property %s to file %s.' % (
502 prop[0], p.filename)) 515 prop[0], p.filename))
503 for post in post_processors: 516 for post in post_processors:
504 post(self, p) 517 post(self, p)
505 except OSError, e: 518 except OSError, e:
506 raise PatchApplicationFailed(p.filename, '%s%s' % (stdout, e)) 519 raise PatchApplicationFailed(p, '%s%s' % (stdout, e))
507 except subprocess.CalledProcessError, e: 520 except subprocess.CalledProcessError, e:
508 raise PatchApplicationFailed( 521 raise PatchApplicationFailed(
509 p.filename, '%s%s' % (stdout, getattr(e, 'stdout', None))) 522 p, '%s%s' % (stdout, getattr(e, 'stdout', None)))
510 # Once all the patches are processed and added to the index, commit the 523 # Once all the patches are processed and added to the index, commit the
511 # index. 524 # index.
512 self._check_call_git(['commit', '-m', 'Committed patch']) 525 self._check_call_git(['commit', '-m', 'Committed patch'])
513 # TODO(maruel): Weirdly enough they don't match, need to investigate. 526 # TODO(maruel): Weirdly enough they don't match, need to investigate.
514 #found_files = self._check_output_git( 527 #found_files = self._check_output_git(
515 # ['diff', 'master', '--name-only']).splitlines(False) 528 # ['diff', 'master', '--name-only']).splitlines(False)
516 #assert sorted(patches.filenames) == sorted(found_files), ( 529 #assert sorted(patches.filenames) == sorted(found_files), (
517 # sorted(out), sorted(found_files)) 530 # sorted(out), sorted(found_files))
518 531
519 def commit(self, commit_message, user): 532 def commit(self, commit_message, user):
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 user, message)) 766 user, message))
754 return 'FAKE' 767 return 'FAKE'
755 768
756 @property 769 @property
757 def project_name(self): 770 def project_name(self):
758 return self.checkout.project_name 771 return self.checkout.project_name
759 772
760 @property 773 @property
761 def project_path(self): 774 def project_path(self):
762 return self.checkout.project_path 775 return self.checkout.project_path
OLDNEW
« no previous file with comments | « apply_issue.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698