| 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 16 matching lines...) Expand all Loading... |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | 28 |
| 29 import argparse | 29 import argparse |
| 30 import sys | 30 import sys |
| 31 import tempfile | 31 import tempfile |
| 32 import urllib2 | 32 import urllib2 |
| 33 | 33 |
| 34 from common_includes import * | 34 from common_includes import * |
| 35 | 35 |
| 36 TRUNKBRANCH = "TRUNKBRANCH" | 36 TRUNKBRANCH = "TRUNKBRANCH" |
| 37 CHROMIUM = "CHROMIUM" | |
| 38 DEPS_FILE = "DEPS_FILE" | |
| 39 | 37 |
| 40 CONFIG = { | 38 CONFIG = { |
| 41 BRANCHNAME: "prepare-push", | 39 BRANCHNAME: "prepare-push", |
| 42 TRUNKBRANCH: "trunk-push", | 40 TRUNKBRANCH: "trunk-push", |
| 43 PERSISTFILE_BASENAME: "/tmp/v8-push-to-trunk-tempfile", | 41 PERSISTFILE_BASENAME: "/tmp/v8-push-to-trunk-tempfile", |
| 44 TEMP_BRANCH: "prepare-push-temporary-branch-created-by-script", | 42 TEMP_BRANCH: "prepare-push-temporary-branch-created-by-script", |
| 45 DOT_GIT_LOCATION: ".git", | 43 DOT_GIT_LOCATION: ".git", |
| 46 VERSION_FILE: "src/version.cc", | 44 VERSION_FILE: "src/version.cc", |
| 47 CHANGELOG_FILE: "ChangeLog", | 45 CHANGELOG_FILE: "ChangeLog", |
| 48 CHANGELOG_ENTRY_FILE: "/tmp/v8-push-to-trunk-tempfile-changelog-entry", | 46 CHANGELOG_ENTRY_FILE: "/tmp/v8-push-to-trunk-tempfile-changelog-entry", |
| 49 PATCH_FILE: "/tmp/v8-push-to-trunk-tempfile-patch-file", | 47 PATCH_FILE: "/tmp/v8-push-to-trunk-tempfile-patch-file", |
| 50 COMMITMSG_FILE: "/tmp/v8-push-to-trunk-tempfile-commitmsg", | 48 COMMITMSG_FILE: "/tmp/v8-push-to-trunk-tempfile-commitmsg", |
| 51 DEPS_FILE: "DEPS", | |
| 52 } | 49 } |
| 53 | 50 |
| 54 PUSH_MESSAGE_SUFFIX = " (based on bleeding_edge revision r%d)" | 51 PUSH_MESSAGE_SUFFIX = " (based on bleeding_edge revision r%d)" |
| 55 PUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") | 52 PUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") |
| 56 | 53 |
| 57 | 54 |
| 58 class Preparation(Step): | 55 class Preparation(Step): |
| 59 MESSAGE = "Preparation." | 56 MESSAGE = "Preparation." |
| 60 | 57 |
| 61 def RunStep(self): | 58 def RunStep(self): |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 self["trunk_revision"] = self.ReadLine() | 350 self["trunk_revision"] = self.ReadLine() |
| 354 | 351 |
| 355 | 352 |
| 356 class TagRevision(Step): | 353 class TagRevision(Step): |
| 357 MESSAGE = "Tag the new revision." | 354 MESSAGE = "Tag the new revision." |
| 358 | 355 |
| 359 def RunStep(self): | 356 def RunStep(self): |
| 360 self.GitSVNTag(self["version"]) | 357 self.GitSVNTag(self["version"]) |
| 361 | 358 |
| 362 | 359 |
| 363 class CheckChromium(Step): | |
| 364 MESSAGE = "Ask for chromium checkout." | |
| 365 | |
| 366 def Run(self): | |
| 367 self["chrome_path"] = self._options.chromium | |
| 368 if not self["chrome_path"]: | |
| 369 self.DieNoManualMode("Please specify the path to a Chromium checkout in " | |
| 370 "forced mode.") | |
| 371 print ("Do you have a \"NewGit\" Chromium checkout and want " | |
| 372 "this script to automate creation of the roll CL? If yes, enter the " | |
| 373 "path to (and including) the \"src\" directory here, otherwise just " | |
| 374 "press <Return>: "), | |
| 375 self["chrome_path"] = self.ReadLine() | |
| 376 | |
| 377 | |
| 378 class SwitchChromium(Step): | |
| 379 MESSAGE = "Switch to Chromium checkout." | |
| 380 REQUIRES = "chrome_path" | |
| 381 | |
| 382 def RunStep(self): | |
| 383 self["v8_path"] = os.getcwd() | |
| 384 os.chdir(self["chrome_path"]) | |
| 385 self.InitialEnvironmentChecks() | |
| 386 # Check for a clean workdir. | |
| 387 if not self.GitIsWorkdirClean(): # pragma: no cover | |
| 388 self.Die("Workspace is not clean. Please commit or undo your changes.") | |
| 389 # Assert that the DEPS file is there. | |
| 390 if not os.path.exists(self.Config(DEPS_FILE)): # pragma: no cover | |
| 391 self.Die("DEPS file not present.") | |
| 392 | |
| 393 | |
| 394 class UpdateChromiumCheckout(Step): | |
| 395 MESSAGE = "Update the checkout and create a new branch." | |
| 396 REQUIRES = "chrome_path" | |
| 397 | |
| 398 def RunStep(self): | |
| 399 os.chdir(self["chrome_path"]) | |
| 400 self.GitCheckout("master") | |
| 401 self.GitPull() | |
| 402 self.GitCreateBranch("v8-roll-%s" % self["trunk_revision"]) | |
| 403 | |
| 404 | |
| 405 class UploadCL(Step): | |
| 406 MESSAGE = "Create and upload CL." | |
| 407 REQUIRES = "chrome_path" | |
| 408 | |
| 409 def RunStep(self): | |
| 410 os.chdir(self["chrome_path"]) | |
| 411 | |
| 412 # Patch DEPS file. | |
| 413 deps = FileToText(self.Config(DEPS_FILE)) | |
| 414 deps = re.sub("(?<=\"v8_revision\": \")([0-9]+)(?=\")", | |
| 415 self["trunk_revision"], | |
| 416 deps) | |
| 417 TextToFile(deps, self.Config(DEPS_FILE)) | |
| 418 | |
| 419 if self._options.reviewer: | |
| 420 print "Using account %s for review." % self._options.reviewer | |
| 421 rev = self._options.reviewer | |
| 422 else: | |
| 423 print "Please enter the email address of a reviewer for the roll CL: ", | |
| 424 self.DieNoManualMode("A reviewer must be specified in forced mode.") | |
| 425 rev = self.ReadLine() | |
| 426 suffix = PUSH_MESSAGE_SUFFIX % int(self["svn_revision"]) | |
| 427 self.GitCommit("Update V8 to version %s%s.\n\nTBR=%s" | |
| 428 % (self["version"], suffix, rev)) | |
| 429 self.GitUpload(author=self._options.author, | |
| 430 force=self._options.force_upload) | |
| 431 print "CL uploaded." | |
| 432 | |
| 433 | |
| 434 class SwitchV8(Step): | |
| 435 MESSAGE = "Returning to V8 checkout." | |
| 436 REQUIRES = "chrome_path" | |
| 437 | |
| 438 def RunStep(self): | |
| 439 os.chdir(self["v8_path"]) | |
| 440 | |
| 441 | |
| 442 class CleanUp(Step): | 360 class CleanUp(Step): |
| 443 MESSAGE = "Done!" | 361 MESSAGE = "Done!" |
| 444 | 362 |
| 445 def RunStep(self): | 363 def RunStep(self): |
| 446 if self["chrome_path"]: | 364 print("Congratulations, you have successfully created the trunk " |
| 447 print("Congratulations, you have successfully created the trunk " | 365 "revision %s. Please don't forget to roll this new version into " |
| 448 "revision %s and rolled it into Chromium. Please don't forget to " | 366 "Chromium, and to update the v8rel spreadsheet:" |
| 449 "update the v8rel spreadsheet:" % self["version"]) | 367 % self["version"]) |
| 450 else: # pragma: no cover | 368 print "%s\ttrunk\t%s" % (self["version"], self["trunk_revision"]) |
| 451 print("Congratulations, you have successfully created the trunk " | |
| 452 "revision %s. Please don't forget to roll this new version into " | |
| 453 "Chromium, and to update the v8rel spreadsheet:" | |
| 454 % self["version"]) | |
| 455 print "%s\ttrunk\t%s" % (self["version"], | |
| 456 self["trunk_revision"]) | |
| 457 | 369 |
| 458 self.CommonCleanup() | 370 self.CommonCleanup() |
| 459 if self.Config(TRUNKBRANCH) != self["current_branch"]: | 371 if self.Config(TRUNKBRANCH) != self["current_branch"]: |
| 460 self.GitDeleteBranch(self.Config(TRUNKBRANCH)) | 372 self.GitDeleteBranch(self.Config(TRUNKBRANCH)) |
| 461 | 373 |
| 462 | 374 |
| 463 class PushToTrunk(ScriptsBase): | 375 class PushToTrunk(ScriptsBase): |
| 464 def _PrepareOptions(self, parser): | 376 def _PrepareOptions(self, parser): |
| 465 group = parser.add_mutually_exclusive_group() | 377 group = parser.add_mutually_exclusive_group() |
| 466 group.add_argument("-f", "--force", | 378 group.add_argument("-f", "--force", |
| 467 help="Don't prompt the user.", | 379 help="Don't prompt the user.", |
| 468 default=False, action="store_true") | 380 default=False, action="store_true") |
| 469 group.add_argument("-m", "--manual", | 381 group.add_argument("-m", "--manual", |
| 470 help="Prompt the user at every important step.", | 382 help="Prompt the user at every important step.", |
| 471 default=False, action="store_true") | 383 default=False, action="store_true") |
| 472 parser.add_argument("-b", "--last-bleeding-edge", | 384 parser.add_argument("-b", "--last-bleeding-edge", |
| 473 help=("The git commit ID of the last bleeding edge " | 385 help=("The git commit ID of the last bleeding edge " |
| 474 "revision that was pushed to trunk. This is " | 386 "revision that was pushed to trunk. This is " |
| 475 "used for the auto-generated ChangeLog entry.")) | 387 "used for the auto-generated ChangeLog entry.")) |
| 476 parser.add_argument("-c", "--chromium", | |
| 477 help=("The path to your Chromium src/ " | |
| 478 "directory to automate the V8 roll.")) | |
| 479 parser.add_argument("-l", "--last-push", | 388 parser.add_argument("-l", "--last-push", |
| 480 help="The git commit ID of the last push to trunk.") | 389 help="The git commit ID of the last push to trunk.") |
| 481 | 390 |
| 482 def _ProcessOptions(self, options): # pragma: no cover | 391 def _ProcessOptions(self, options): # pragma: no cover |
| 483 if not options.manual and not options.reviewer: | 392 if not options.manual and not options.reviewer: |
| 484 print "A reviewer (-r) is required in (semi-)automatic mode." | 393 print "A reviewer (-r) is required in (semi-)automatic mode." |
| 485 return False | 394 return False |
| 486 if not options.manual and not options.chromium: | |
| 487 print "A chromium checkout (-c) is required in (semi-)automatic mode." | |
| 488 return False | |
| 489 if not options.manual and not options.author: | 395 if not options.manual and not options.author: |
| 490 print "Specify your chromium.org email with -a in (semi-)automatic mode." | 396 print "Specify your chromium.org email with -a in (semi-)automatic mode." |
| 491 return False | 397 return False |
| 492 | 398 |
| 493 options.tbr_commit = not options.manual | 399 options.tbr_commit = not options.manual |
| 494 return True | 400 return True |
| 495 | 401 |
| 496 def _Steps(self): | 402 def _Steps(self): |
| 497 return [ | 403 return [ |
| 498 Preparation, | 404 Preparation, |
| 499 FreshBranch, | 405 FreshBranch, |
| 500 DetectLastPush, | 406 DetectLastPush, |
| 501 IncrementVersion, | 407 IncrementVersion, |
| 502 PrepareChangeLog, | 408 PrepareChangeLog, |
| 503 EditChangeLog, | 409 EditChangeLog, |
| 504 StragglerCommits, | 410 StragglerCommits, |
| 505 SquashCommits, | 411 SquashCommits, |
| 506 NewBranch, | 412 NewBranch, |
| 507 ApplyChanges, | 413 ApplyChanges, |
| 508 AddChangeLog, | 414 AddChangeLog, |
| 509 SetVersion, | 415 SetVersion, |
| 510 CommitTrunk, | 416 CommitTrunk, |
| 511 SanityCheck, | 417 SanityCheck, |
| 512 CommitSVN, | 418 CommitSVN, |
| 513 TagRevision, | 419 TagRevision, |
| 514 CheckChromium, | |
| 515 SwitchChromium, | |
| 516 UpdateChromiumCheckout, | |
| 517 UploadCL, | |
| 518 SwitchV8, | |
| 519 CleanUp, | 420 CleanUp, |
| 520 ] | 421 ] |
| 521 | 422 |
| 522 | 423 |
| 523 if __name__ == "__main__": # pragma: no cover | 424 if __name__ == "__main__": # pragma: no cover |
| 524 sys.exit(PushToTrunk(CONFIG).Run()) | 425 sys.exit(PushToTrunk(CONFIG).Run()) |
| OLD | NEW |