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

Side by Side Diff: tools/push-to-trunk/common_includes.py

Issue 166903012: Refactoring: Extract git checks in push and merge scripts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review. Created 6 years, 10 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 | « no previous file | tools/push-to-trunk/merge_to_branch.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 the V8 project authors. All rights reserved. 2 # Copyright 2013 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following 10 # copyright notice, this list of conditions and the following
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 def GetDate(self): 213 def GetDate(self):
214 return datetime.date.today().strftime("%Y-%m-%d") 214 return datetime.date.today().strftime("%Y-%m-%d")
215 215
216 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() 216 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
217 217
218 218
219 class NoRetryException(Exception): 219 class NoRetryException(Exception):
220 pass 220 pass
221 221
222 222
223 class GitFailedException(Exception):
224 pass
225
226
223 class CommonOptions(object): 227 class CommonOptions(object):
224 def __init__(self, options, manual=True): 228 def __init__(self, options, manual=True):
225 self.requires_editor = True 229 self.requires_editor = True
226 self.wait_for_lgtm = True 230 self.wait_for_lgtm = True
227 self.s = options.s 231 self.s = options.s
228 self.force_readline_defaults = not manual 232 self.force_readline_defaults = not manual
229 self.force_upload = not manual 233 self.force_upload = not manual
230 self.manual = manual 234 self.manual = manual
231 self.reviewer = getattr(options, 'reviewer', None) 235 self.reviewer = getattr(options, 'reviewer', None)
232 self.author = getattr(options, 'a', None) 236 self.author = getattr(options, 'a', None)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 def ReadLine(self, default=None): 317 def ReadLine(self, default=None):
314 # Don't prompt in forced mode. 318 # Don't prompt in forced mode.
315 if self._options.force_readline_defaults and default is not None: 319 if self._options.force_readline_defaults and default is not None:
316 print "%s (forced)" % default 320 print "%s (forced)" % default
317 return default 321 return default
318 else: 322 else:
319 return self._side_effect_handler.ReadLine() 323 return self._side_effect_handler.ReadLine()
320 324
321 def Git(self, args="", prefix="", pipe=True, retry_on=None): 325 def Git(self, args="", prefix="", pipe=True, retry_on=None):
322 cmd = lambda: self._side_effect_handler.Command("git", args, prefix, pipe) 326 cmd = lambda: self._side_effect_handler.Command("git", args, prefix, pipe)
323 return self.Retry(cmd, retry_on, [5, 30]) 327 result = self.Retry(cmd, retry_on, [5, 30])
328 if result is None:
329 raise GitFailedException("'git %s' failed." % args)
330 return result
324 331
325 def SVN(self, args="", prefix="", pipe=True, retry_on=None): 332 def SVN(self, args="", prefix="", pipe=True, retry_on=None):
326 cmd = lambda: self._side_effect_handler.Command("svn", args, prefix, pipe) 333 cmd = lambda: self._side_effect_handler.Command("svn", args, prefix, pipe)
327 return self.Retry(cmd, retry_on, [5, 30]) 334 return self.Retry(cmd, retry_on, [5, 30])
328 335
329 def Editor(self, args): 336 def Editor(self, args):
330 if self._options.requires_editor: 337 if self._options.requires_editor:
331 return self._side_effect_handler.Command(os.environ["EDITOR"], args, 338 return self._side_effect_handler.Command(os.environ["EDITOR"], args,
332 pipe=False) 339 pipe=False)
333 340
(...skipping 20 matching lines...) Expand all
354 print "%s [Y/n] " % msg, 361 print "%s [Y/n] " % msg,
355 answer = self.ReadLine(default="Y") 362 answer = self.ReadLine(default="Y")
356 return answer == "" or answer == "Y" or answer == "y" 363 return answer == "" or answer == "Y" or answer == "y"
357 364
358 def DeleteBranch(self, name): 365 def DeleteBranch(self, name):
359 git_result = self.Git("branch").strip() 366 git_result = self.Git("branch").strip()
360 for line in git_result.splitlines(): 367 for line in git_result.splitlines():
361 if re.match(r".*\s+%s$" % name, line): 368 if re.match(r".*\s+%s$" % name, line):
362 msg = "Branch %s exists, do you want to delete it?" % name 369 msg = "Branch %s exists, do you want to delete it?" % name
363 if self.Confirm(msg): 370 if self.Confirm(msg):
364 if self.Git("branch -D %s" % name) is None: 371 self.Git("branch -D %s" % name)
365 self.Die("Deleting branch '%s' failed." % name)
366 print "Branch %s deleted." % name 372 print "Branch %s deleted." % name
367 else: 373 else:
368 msg = "Can't continue. Please delete branch %s and try again." % name 374 msg = "Can't continue. Please delete branch %s and try again." % name
369 self.Die(msg) 375 self.Die(msg)
370 376
371 def InitialEnvironmentChecks(self): 377 def InitialEnvironmentChecks(self):
372 # Cancel if this is not a git checkout. 378 # Cancel if this is not a git checkout.
373 if not os.path.exists(self._config[DOT_GIT_LOCATION]): 379 if not os.path.exists(self._config[DOT_GIT_LOCATION]):
374 self.Die("This is not a git checkout, this script won't work for you.") 380 self.Die("This is not a git checkout, this script won't work for you.")
375 381
(...skipping 10 matching lines...) Expand all
386 # Persist current branch. 392 # Persist current branch.
387 self["current_branch"] = "" 393 self["current_branch"] = ""
388 git_result = self.Git("status -s -b -uno").strip() 394 git_result = self.Git("status -s -b -uno").strip()
389 for line in git_result.splitlines(): 395 for line in git_result.splitlines():
390 match = re.match(r"^## (.+)", line) 396 match = re.match(r"^## (.+)", line)
391 if match: 397 if match:
392 self["current_branch"] = match.group(1) 398 self["current_branch"] = match.group(1)
393 break 399 break
394 400
395 # Fetch unfetched revisions. 401 # Fetch unfetched revisions.
396 if self.Git("svn fetch") is None: 402 self.Git("svn fetch")
397 self.Die("'git svn fetch' failed.")
398 403
399 def PrepareBranch(self): 404 def PrepareBranch(self):
400 # Get ahold of a safe temporary branch and check it out. 405 # Get ahold of a safe temporary branch and check it out.
401 if self["current_branch"] != self._config[TEMP_BRANCH]: 406 if self["current_branch"] != self._config[TEMP_BRANCH]:
402 self.DeleteBranch(self._config[TEMP_BRANCH]) 407 self.DeleteBranch(self._config[TEMP_BRANCH])
403 self.Git("checkout -b %s" % self._config[TEMP_BRANCH]) 408 self.Git("checkout -b %s" % self._config[TEMP_BRANCH])
404 409
405 # Delete the branch that will be created later if it exists already. 410 # Delete the branch that will be created later if it exists already.
406 self.DeleteBranch(self._config[BRANCHNAME]) 411 self.DeleteBranch(self._config[BRANCHNAME])
407 412
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 if answer == "ABORT": 455 if answer == "ABORT":
451 self.Die("Applying the patch failed.") 456 self.Die("Applying the patch failed.")
452 if answer != "": 457 if answer != "":
453 print "That was not 'RESOLVED' or 'ABORT'." 458 print "That was not 'RESOLVED' or 'ABORT'."
454 print "> ", 459 print "> ",
455 answer = self.ReadLine() 460 answer = self.ReadLine()
456 461
457 # Takes a file containing the patch to apply as first argument. 462 # Takes a file containing the patch to apply as first argument.
458 def ApplyPatch(self, patch_file, reverse_patch=""): 463 def ApplyPatch(self, patch_file, reverse_patch=""):
459 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file) 464 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file)
460 if self.Git(args) is None: 465 try:
466 self.Git(args)
467 except GitFailedException:
461 self.WaitForResolvingConflicts(patch_file) 468 self.WaitForResolvingConflicts(patch_file)
462 469
463 def FindLastTrunkPush(self): 470 def FindLastTrunkPush(self):
464 push_pattern = "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based" 471 push_pattern = "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based"
465 args = "log -1 --format=%%H --grep=\"%s\" svn/trunk" % push_pattern 472 args = "log -1 --format=%%H --grep=\"%s\" svn/trunk" % push_pattern
466 return self.Git(args).strip() 473 return self.Git(args).strip()
467 474
468 475
469 class UploadStep(Step): 476 class UploadStep(Step):
470 MESSAGE = "Upload for code review." 477 MESSAGE = "Upload for code review."
471 478
472 def RunStep(self): 479 def RunStep(self):
473 if self._options.reviewer: 480 if self._options.reviewer:
474 print "Using account %s for review." % self._options.reviewer 481 print "Using account %s for review." % self._options.reviewer
475 reviewer = self._options.reviewer 482 reviewer = self._options.reviewer
476 else: 483 else:
477 print "Please enter the email address of a V8 reviewer for your patch: ", 484 print "Please enter the email address of a V8 reviewer for your patch: ",
478 self.DieNoManualMode("A reviewer must be specified in forced mode.") 485 self.DieNoManualMode("A reviewer must be specified in forced mode.")
479 reviewer = self.ReadLine() 486 reviewer = self.ReadLine()
480 author_option = self._options.author 487 author_option = self._options.author
481 author = " --email \"%s\"" % author_option if author_option else "" 488 author = " --email \"%s\"" % author_option if author_option else ""
482 force_flag = " -f" if self._options.force_upload else "" 489 force_flag = " -f" if self._options.force_upload else ""
483 args = ("cl upload%s -r \"%s\" --send-mail%s" 490 args = ("cl upload%s -r \"%s\" --send-mail%s"
484 % (author, reviewer, force_flag)) 491 % (author, reviewer, force_flag))
485 # TODO(machenbach): Check output in forced mode. Verify that all required 492 # TODO(machenbach): Check output in forced mode. Verify that all required
486 # base files were uploaded, if not retry. 493 # base files were uploaded, if not retry.
487 if self.Git(args, pipe=False) is None: 494 self.Git(args, pipe=False)
488 self.Die("'git cl upload' failed, please try again.")
489 495
490 496
491 def MakeStep(step_class=Step, number=0, state=None, config=None, 497 def MakeStep(step_class=Step, number=0, state=None, config=None,
492 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 498 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
493 # Allow to pass in empty dictionaries. 499 # Allow to pass in empty dictionaries.
494 state = state if state is not None else {} 500 state = state if state is not None else {}
495 config = config if config is not None else {} 501 config = config if config is not None else {}
496 502
497 try: 503 try:
498 message = step_class.MESSAGE 504 message = step_class.MESSAGE
(...skipping 17 matching lines...) Expand all
516 if options.s == 0 and os.path.exists(state_file): 522 if options.s == 0 and os.path.exists(state_file):
517 os.remove(state_file) 523 os.remove(state_file)
518 state = {} 524 state = {}
519 steps = [] 525 steps = []
520 for (number, step_class) in enumerate(step_classes): 526 for (number, step_class) in enumerate(step_classes):
521 steps.append(MakeStep(step_class, number, state, config, 527 steps.append(MakeStep(step_class, number, state, config,
522 options, side_effect_handler)) 528 options, side_effect_handler))
523 529
524 for step in steps[options.s:]: 530 for step in steps[options.s:]:
525 step.Run() 531 step.Run()
OLDNEW
« no previous file with comments | « no previous file | tools/push-to-trunk/merge_to_branch.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698