OLD | NEW |
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 | 151 |
152 class EditChangeLog(Step): | 152 class EditChangeLog(Step): |
153 MESSAGE = "Edit ChangeLog entry." | 153 MESSAGE = "Edit ChangeLog entry." |
154 | 154 |
155 def RunStep(self): | 155 def RunStep(self): |
156 print ("Please press <Return> to have your EDITOR open the ChangeLog " | 156 print ("Please press <Return> to have your EDITOR open the ChangeLog " |
157 "entry, then edit its contents to your liking. When you're done, " | 157 "entry, then edit its contents to your liking. When you're done, " |
158 "save the file and exit your EDITOR. ") | 158 "save the file and exit your EDITOR. ") |
159 self.ReadLine(default="") | 159 self.ReadLine(default="") |
160 | |
161 # TODO(machenbach): Don't use EDITOR in forced mode as soon as script is | |
162 # well tested. | |
163 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) | 160 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) |
164 handle, new_changelog = tempfile.mkstemp() | 161 handle, new_changelog = tempfile.mkstemp() |
165 os.close(handle) | 162 os.close(handle) |
166 | 163 |
167 # Strip comments and reformat with correct indentation. | 164 # Strip comments and reformat with correct indentation. |
168 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() | 165 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() |
169 changelog_entry = StripComments(changelog_entry) | 166 changelog_entry = StripComments(changelog_entry) |
170 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) | 167 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) |
171 changelog_entry = changelog_entry.lstrip() | 168 changelog_entry = changelog_entry.lstrip() |
172 | 169 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 class CommitLocal(Step): | 204 class CommitLocal(Step): |
208 MESSAGE = "Commit to local branch." | 205 MESSAGE = "Commit to local branch." |
209 | 206 |
210 def RunStep(self): | 207 def RunStep(self): |
211 self.RestoreVersionIfUnset("new_") | 208 self.RestoreVersionIfUnset("new_") |
212 prep_commit_msg = ("Prepare push to trunk. " | 209 prep_commit_msg = ("Prepare push to trunk. " |
213 "Now working on version %s.%s.%s." % (self._state["new_major"], | 210 "Now working on version %s.%s.%s." % (self._state["new_major"], |
214 self._state["new_minor"], | 211 self._state["new_minor"], |
215 self._state["new_build"])) | 212 self._state["new_build"])) |
216 self.Persist("prep_commit_msg", prep_commit_msg) | 213 self.Persist("prep_commit_msg", prep_commit_msg) |
217 if self.Git("commit -a -m \"%s\"" % prep_commit_msg) is None: | 214 |
| 215 # Include optional TBR only in the git command. The persisted commit |
| 216 # message is used for finding the commit again later. |
| 217 review = "\n\nTBR=%s" % self._options.r if not self.IsManual() else "" |
| 218 if self.Git("commit -a -m \"%s%s\"" % (prep_commit_msg, review)) is None: |
218 self.Die("'git commit -a' failed.") | 219 self.Die("'git commit -a' failed.") |
219 | 220 |
220 | 221 |
221 class CommitRepository(Step): | 222 class CommitRepository(Step): |
222 MESSAGE = "Commit to the repository." | 223 MESSAGE = "Commit to the repository." |
223 | 224 |
224 def RunStep(self): | 225 def RunStep(self): |
225 self.WaitForLGTM() | 226 self.WaitForLGTM() |
226 # Re-read the ChangeLog entry (to pick up possible changes). | 227 # Re-read the ChangeLog entry (to pick up possible changes). |
227 # FIXME(machenbach): This was hanging once with a broken pipe. | 228 # FIXME(machenbach): This was hanging once with a broken pipe. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 result.splitlines()) | 358 result.splitlines()) |
358 if len(result) > 0: | 359 if len(result) > 0: |
359 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0]) | 360 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0]) |
360 | 361 |
361 # Sometimes grepping for the revision fails. No idea why. If you figure | 362 # Sometimes grepping for the revision fails. No idea why. If you figure |
362 # out why it is flaky, please do fix it properly. | 363 # out why it is flaky, please do fix it properly. |
363 if not trunk_revision: | 364 if not trunk_revision: |
364 print("Sorry, grepping for the SVN revision failed. Please look for it " | 365 print("Sorry, grepping for the SVN revision failed. Please look for it " |
365 "in the last command's output above and provide it manually (just " | 366 "in the last command's output above and provide it manually (just " |
366 "the number, without the leading \"r\").") | 367 "the number, without the leading \"r\").") |
367 self.DieInForcedMode("Can't prompt in forced mode.") | 368 self.DieNoManualMode("Can't prompt in forced mode.") |
368 while not trunk_revision: | 369 while not trunk_revision: |
369 print "> ", | 370 print "> ", |
370 trunk_revision = self.ReadLine() | 371 trunk_revision = self.ReadLine() |
371 self.Persist("trunk_revision", trunk_revision) | 372 self.Persist("trunk_revision", trunk_revision) |
372 | 373 |
373 | 374 |
374 class TagRevision(Step): | 375 class TagRevision(Step): |
375 MESSAGE = "Tag the new revision." | 376 MESSAGE = "Tag the new revision." |
376 | 377 |
377 def RunStep(self): | 378 def RunStep(self): |
378 self.RestoreVersionIfUnset() | 379 self.RestoreVersionIfUnset() |
379 ver = "%s.%s.%s" % (self._state["major"], | 380 ver = "%s.%s.%s" % (self._state["major"], |
380 self._state["minor"], | 381 self._state["minor"], |
381 self._state["build"]) | 382 self._state["build"]) |
382 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None: | 383 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None: |
383 self.Die("'git svn tag' failed.") | 384 self.Die("'git svn tag' failed.") |
384 | 385 |
385 | 386 |
386 class CheckChromium(Step): | 387 class CheckChromium(Step): |
387 MESSAGE = "Ask for chromium checkout." | 388 MESSAGE = "Ask for chromium checkout." |
388 | 389 |
389 def Run(self): | 390 def Run(self): |
390 chrome_path = self._options.c | 391 chrome_path = self._options.c |
391 if not chrome_path: | 392 if not chrome_path: |
392 self.DieInForcedMode("Please specify the path to a Chromium checkout in " | 393 self.DieNoManualMode("Please specify the path to a Chromium checkout in " |
393 "forced mode.") | 394 "forced mode.") |
394 print ("Do you have a \"NewGit\" Chromium checkout and want " | 395 print ("Do you have a \"NewGit\" Chromium checkout and want " |
395 "this script to automate creation of the roll CL? If yes, enter the " | 396 "this script to automate creation of the roll CL? If yes, enter the " |
396 "path to (and including) the \"src\" directory here, otherwise just " | 397 "path to (and including) the \"src\" directory here, otherwise just " |
397 "press <Return>: "), | 398 "press <Return>: "), |
398 chrome_path = self.ReadLine() | 399 chrome_path = self.ReadLine() |
399 self.Persist("chrome_path", chrome_path) | 400 self.Persist("chrome_path", chrome_path) |
400 | 401 |
401 | 402 |
402 class SwitchChromium(Step): | 403 class SwitchChromium(Step): |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 | 451 |
451 self.RestoreVersionIfUnset() | 452 self.RestoreVersionIfUnset() |
452 ver = "%s.%s.%s" % (self._state["major"], | 453 ver = "%s.%s.%s" % (self._state["major"], |
453 self._state["minor"], | 454 self._state["minor"], |
454 self._state["build"]) | 455 self._state["build"]) |
455 if self._options and self._options.r: | 456 if self._options and self._options.r: |
456 print "Using account %s for review." % self._options.r | 457 print "Using account %s for review." % self._options.r |
457 rev = self._options.r | 458 rev = self._options.r |
458 else: | 459 else: |
459 print "Please enter the email address of a reviewer for the roll CL: ", | 460 print "Please enter the email address of a reviewer for the roll CL: ", |
460 self.DieInForcedMode("A reviewer must be specified in forced mode.") | 461 self.DieNoManualMode("A reviewer must be specified in forced mode.") |
461 rev = self.ReadLine() | 462 rev = self.ReadLine() |
462 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev) | 463 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev) |
463 if self.Git(args) is None: | 464 if self.Git(args) is None: |
464 self.Die("'git commit' failed.") | 465 self.Die("'git commit' failed.") |
465 force_flag = " -f" if self._options.f else "" | 466 force_flag = " -f" if not self.IsManual() else "" |
466 if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None: | 467 if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None: |
467 self.Die("'git cl upload' failed, please try again.") | 468 self.Die("'git cl upload' failed, please try again.") |
468 print "CL uploaded." | 469 print "CL uploaded." |
469 | 470 |
470 | 471 |
471 class SwitchV8(Step): | 472 class SwitchV8(Step): |
472 MESSAGE = "Returning to V8 checkout." | 473 MESSAGE = "Returning to V8 checkout." |
473 REQUIRES = "chrome_path" | 474 REQUIRES = "chrome_path" |
474 | 475 |
475 def RunStep(self): | 476 def RunStep(self): |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 result = optparse.OptionParser() | 541 result = optparse.OptionParser() |
541 result.add_option("-c", "--chromium", dest="c", | 542 result.add_option("-c", "--chromium", dest="c", |
542 help=("Specify the path to your Chromium src/ " | 543 help=("Specify the path to your Chromium src/ " |
543 "directory to automate the V8 roll.")) | 544 "directory to automate the V8 roll.")) |
544 result.add_option("-f", "--force", dest="f", | 545 result.add_option("-f", "--force", dest="f", |
545 help="Don't prompt the user.", | 546 help="Don't prompt the user.", |
546 default=False, action="store_true") | 547 default=False, action="store_true") |
547 result.add_option("-l", "--last-push", dest="l", | 548 result.add_option("-l", "--last-push", dest="l", |
548 help=("Manually specify the git commit ID " | 549 help=("Manually specify the git commit ID " |
549 "of the last push to trunk.")) | 550 "of the last push to trunk.")) |
| 551 result.add_option("-m", "--manual", dest="m", |
| 552 help="Prompt the user at every important step.", |
| 553 default=False, action="store_true") |
550 result.add_option("-r", "--reviewer", dest="r", | 554 result.add_option("-r", "--reviewer", dest="r", |
551 help=("Specify the account name to be used for reviews.")) | 555 help=("Specify the account name to be used for reviews.")) |
552 result.add_option("-s", "--step", dest="s", | 556 result.add_option("-s", "--step", dest="s", |
553 help="Specify the step where to start work. Default: 0.", | 557 help="Specify the step where to start work. Default: 0.", |
554 default=0, type="int") | 558 default=0, type="int") |
555 return result | 559 return result |
556 | 560 |
557 | 561 |
558 def ProcessOptions(options): | 562 def ProcessOptions(options): |
559 if options.s < 0: | 563 if options.s < 0: |
560 print "Bad step number %d" % options.s | 564 print "Bad step number %d" % options.s |
561 return False | 565 return False |
562 if options.f and not options.r: | 566 if not options.m and not options.r: |
563 print "A reviewer (-r) is required in forced mode." | 567 print "A reviewer (-r) is required in (semi-)automatic mode." |
564 return False | 568 return False |
565 if options.f and not options.c: | 569 if options.f and options.m: |
566 print "A chromium checkout (-c) is required in forced mode." | 570 print "Manual and forced mode cannot be combined." |
| 571 return False |
| 572 if not options.m and not options.c: |
| 573 print "A chromium checkout (-c) is required in (semi-)automatic mode." |
567 return False | 574 return False |
568 return True | 575 return True |
569 | 576 |
570 | 577 |
571 def Main(): | 578 def Main(): |
572 parser = BuildOptions() | 579 parser = BuildOptions() |
573 (options, args) = parser.parse_args() | 580 (options, args) = parser.parse_args() |
574 if not ProcessOptions(options): | 581 if not ProcessOptions(options): |
575 parser.print_help() | 582 parser.print_help() |
576 return 1 | 583 return 1 |
577 RunPushToTrunk(CONFIG, options) | 584 RunPushToTrunk(CONFIG, options) |
578 | 585 |
579 if __name__ == "__main__": | 586 if __name__ == "__main__": |
580 sys.exit(Main()) | 587 sys.exit(Main()) |
OLD | NEW |