| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 88 |
| 89 if self._options.last_bleeding_edge: | 89 if self._options.last_bleeding_edge: |
| 90 # Read the bleeding edge revision of the last push from a command-line | 90 # Read the bleeding edge revision of the last push from a command-line |
| 91 # option. | 91 # option. |
| 92 last_push_bleeding_edge = self._options.last_bleeding_edge | 92 last_push_bleeding_edge = self._options.last_bleeding_edge |
| 93 else: | 93 else: |
| 94 # Retrieve the bleeding edge revision of the last push from the text in | 94 # Retrieve the bleeding edge revision of the last push from the text in |
| 95 # the push commit message. | 95 # the push commit message. |
| 96 last_push_title = self.GitLog(n=1, format="%s", git_hash=last_push) | 96 last_push_title = self.GitLog(n=1, format="%s", git_hash=last_push) |
| 97 last_push_be_svn = PUSH_MESSAGE_RE.match(last_push_title).group(1) | 97 last_push_be_svn = PUSH_MESSAGE_RE.match(last_push_title).group(1) |
| 98 if not last_push_be_svn: | 98 if not last_push_be_svn: # pragma: no cover |
| 99 self.Die("Could not retrieve bleeding edge revision for trunk push %s" | 99 self.Die("Could not retrieve bleeding edge revision for trunk push %s" |
| 100 % last_push) | 100 % last_push) |
| 101 last_push_bleeding_edge = self.GitSVNFindGitHash(last_push_be_svn) | 101 last_push_bleeding_edge = self.GitSVNFindGitHash(last_push_be_svn) |
| 102 if not last_push_bleeding_edge: | 102 if not last_push_bleeding_edge: # pragma: no cover |
| 103 self.Die("Could not retrieve bleeding edge git hash for trunk push %s" | 103 self.Die("Could not retrieve bleeding edge git hash for trunk push %s" |
| 104 % last_push) | 104 % last_push) |
| 105 | 105 |
| 106 # TODO(machenbach): last_push_trunk points to the svn revision on trunk. | 106 # TODO(machenbach): last_push_trunk points to the svn revision on trunk. |
| 107 # It is not used yet but we'll need it for retrieving the current version. | 107 # It is not used yet but we'll need it for retrieving the current version. |
| 108 self["last_push_trunk"] = last_push | 108 self["last_push_trunk"] = last_push |
| 109 # TODO(machenbach): This currently points to the prepare push revision that | 109 # TODO(machenbach): This currently points to the prepare push revision that |
| 110 # will be deprecated soon. After the deprecation it will point to the last | 110 # will be deprecated soon. After the deprecation it will point to the last |
| 111 # bleeding_edge revision that went into the last push. | 111 # bleeding_edge revision that went into the last push. |
| 112 self["last_push_bleeding_edge"] = last_push_bleeding_edge | 112 self["last_push_bleeding_edge"] = last_push_bleeding_edge |
| 113 | 113 |
| 114 | 114 |
| 115 class PrepareChangeLog(Step): | 115 class PrepareChangeLog(Step): |
| 116 MESSAGE = "Prepare raw ChangeLog entry." | 116 MESSAGE = "Prepare raw ChangeLog entry." |
| 117 | 117 |
| 118 def Reload(self, body): | 118 def Reload(self, body): |
| 119 """Attempts to reload the commit message from rietveld in order to allow | 119 """Attempts to reload the commit message from rietveld in order to allow |
| 120 late changes to the LOG flag. Note: This is brittle to future changes of | 120 late changes to the LOG flag. Note: This is brittle to future changes of |
| 121 the web page name or structure. | 121 the web page name or structure. |
| 122 """ | 122 """ |
| 123 match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", | 123 match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", |
| 124 body, flags=re.M) | 124 body, flags=re.M) |
| 125 if match: | 125 if match: |
| 126 cl_url = ("https://codereview.chromium.org/%s/description" | 126 cl_url = ("https://codereview.chromium.org/%s/description" |
| 127 % match.group(1)) | 127 % match.group(1)) |
| 128 try: | 128 try: |
| 129 # Fetch from Rietveld but only retry once with one second delay since | 129 # Fetch from Rietveld but only retry once with one second delay since |
| 130 # there might be many revisions. | 130 # there might be many revisions. |
| 131 body = self.ReadURL(cl_url, wait_plan=[1]) | 131 body = self.ReadURL(cl_url, wait_plan=[1]) |
| 132 except urllib2.URLError: | 132 except urllib2.URLError: # pragma: no cover |
| 133 pass | 133 pass |
| 134 return body | 134 return body |
| 135 | 135 |
| 136 def RunStep(self): | 136 def RunStep(self): |
| 137 # These version numbers are used again later for the trunk commit. | 137 # These version numbers are used again later for the trunk commit. |
| 138 self.ReadAndPersistVersion() | 138 self.ReadAndPersistVersion() |
| 139 self["date"] = self.GetDate() | 139 self["date"] = self.GetDate() |
| 140 self["version"] = "%s.%s.%s" % (self["major"], | 140 self["version"] = "%s.%s.%s" % (self["major"], |
| 141 self["minor"], | 141 self["minor"], |
| 142 self["build"]) | 142 self["build"]) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 "save the file and exit your EDITOR. ") | 179 "save the file and exit your EDITOR. ") |
| 180 self.ReadLine(default="") | 180 self.ReadLine(default="") |
| 181 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) | 181 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) |
| 182 | 182 |
| 183 # Strip comments and reformat with correct indentation. | 183 # Strip comments and reformat with correct indentation. |
| 184 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() | 184 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() |
| 185 changelog_entry = StripComments(changelog_entry) | 185 changelog_entry = StripComments(changelog_entry) |
| 186 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) | 186 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) |
| 187 changelog_entry = changelog_entry.lstrip() | 187 changelog_entry = changelog_entry.lstrip() |
| 188 | 188 |
| 189 if changelog_entry == "": | 189 if changelog_entry == "": # pragma: no cover |
| 190 self.Die("Empty ChangeLog entry.") | 190 self.Die("Empty ChangeLog entry.") |
| 191 | 191 |
| 192 # Safe new change log for adding it later to the trunk patch. | 192 # Safe new change log for adding it later to the trunk patch. |
| 193 TextToFile(changelog_entry, self.Config(NEW_CHANGELOG_FILE)) | 193 TextToFile(changelog_entry, self.Config(NEW_CHANGELOG_FILE)) |
| 194 | 194 |
| 195 old_change_log = FileToText(self.Config(CHANGELOG_FILE)) | 195 old_change_log = FileToText(self.Config(CHANGELOG_FILE)) |
| 196 new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log) | 196 new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log) |
| 197 TextToFile(new_change_log, self.Config(CHANGELOG_FILE)) | 197 TextToFile(new_change_log, self.Config(CHANGELOG_FILE)) |
| 198 | 198 |
| 199 | 199 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 suffix = PUSH_MESSAGE_SUFFIX % int(self["svn_revision"]) | 283 suffix = PUSH_MESSAGE_SUFFIX % int(self["svn_revision"]) |
| 284 text = MSub(r"^(Version \d+\.\d+\.\d+)$", "\\1%s" % suffix, text) | 284 text = MSub(r"^(Version \d+\.\d+\.\d+)$", "\\1%s" % suffix, text) |
| 285 | 285 |
| 286 # Remove indentation and merge paragraphs into single long lines, keeping | 286 # Remove indentation and merge paragraphs into single long lines, keeping |
| 287 # empty lines between them. | 287 # empty lines between them. |
| 288 def SplitMapJoin(split_text, fun, join_text): | 288 def SplitMapJoin(split_text, fun, join_text): |
| 289 return lambda text: join_text.join(map(fun, text.split(split_text))) | 289 return lambda text: join_text.join(map(fun, text.split(split_text))) |
| 290 strip = lambda line: line.strip() | 290 strip = lambda line: line.strip() |
| 291 text = SplitMapJoin("\n\n", SplitMapJoin("\n", strip, " "), "\n\n")(text) | 291 text = SplitMapJoin("\n\n", SplitMapJoin("\n", strip, " "), "\n\n")(text) |
| 292 | 292 |
| 293 if not text: | 293 if not text: # pragma: no cover |
| 294 self.Die("Commit message editing failed.") | 294 self.Die("Commit message editing failed.") |
| 295 TextToFile(text, self.Config(COMMITMSG_FILE)) | 295 TextToFile(text, self.Config(COMMITMSG_FILE)) |
| 296 os.remove(self.Config(CHANGELOG_ENTRY_FILE)) | 296 os.remove(self.Config(CHANGELOG_ENTRY_FILE)) |
| 297 | 297 |
| 298 | 298 |
| 299 class NewBranch(Step): | 299 class NewBranch(Step): |
| 300 MESSAGE = "Create a new branch from trunk." | 300 MESSAGE = "Create a new branch from trunk." |
| 301 | 301 |
| 302 def RunStep(self): | 302 def RunStep(self): |
| 303 self.GitCreateBranch(self.Config(TRUNKBRANCH), "svn/trunk") | 303 self.GitCreateBranch(self.Config(TRUNKBRANCH), "svn/trunk") |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 Command("rm", "-f %s*" % self.Config(COMMITMSG_FILE)) | 340 Command("rm", "-f %s*" % self.Config(COMMITMSG_FILE)) |
| 341 | 341 |
| 342 | 342 |
| 343 class SanityCheck(Step): | 343 class SanityCheck(Step): |
| 344 MESSAGE = "Sanity check." | 344 MESSAGE = "Sanity check." |
| 345 | 345 |
| 346 def RunStep(self): | 346 def RunStep(self): |
| 347 if not self.Confirm("Please check if your local checkout is sane: Inspect " | 347 if not self.Confirm("Please check if your local checkout is sane: Inspect " |
| 348 "%s, compile, run tests. Do you want to commit this new trunk " | 348 "%s, compile, run tests. Do you want to commit this new trunk " |
| 349 "revision to the repository?" % self.Config(VERSION_FILE)): | 349 "revision to the repository?" % self.Config(VERSION_FILE)): |
| 350 self.Die("Execution canceled.") | 350 self.Die("Execution canceled.") # pragma: no cover |
| 351 | 351 |
| 352 | 352 |
| 353 class CommitSVN(Step): | 353 class CommitSVN(Step): |
| 354 MESSAGE = "Commit to SVN." | 354 MESSAGE = "Commit to SVN." |
| 355 | 355 |
| 356 def RunStep(self): | 356 def RunStep(self): |
| 357 result = self.GitSVNDCommit() | 357 result = self.GitSVNDCommit() |
| 358 if not result: | 358 if not result: # pragma: no cover |
| 359 self.Die("'git svn dcommit' failed.") | 359 self.Die("'git svn dcommit' failed.") |
| 360 result = filter(lambda x: re.search(r"^Committed r[0-9]+", x), | 360 result = filter(lambda x: re.search(r"^Committed r[0-9]+", x), |
| 361 result.splitlines()) | 361 result.splitlines()) |
| 362 if len(result) > 0: | 362 if len(result) > 0: |
| 363 self["trunk_revision"] = re.sub(r"^Committed r([0-9]+)", r"\1",result[0]) | 363 self["trunk_revision"] = re.sub(r"^Committed r([0-9]+)", r"\1",result[0]) |
| 364 | 364 |
| 365 # Sometimes grepping for the revision fails. No idea why. If you figure | 365 # Sometimes grepping for the revision fails. No idea why. If you figure |
| 366 # out why it is flaky, please do fix it properly. | 366 # out why it is flaky, please do fix it properly. |
| 367 if not self["trunk_revision"]: | 367 if not self["trunk_revision"]: |
| 368 print("Sorry, grepping for the SVN revision failed. Please look for it " | 368 print("Sorry, grepping for the SVN revision failed. Please look for it " |
| (...skipping 29 matching lines...) Expand all Loading... |
| 398 | 398 |
| 399 class SwitchChromium(Step): | 399 class SwitchChromium(Step): |
| 400 MESSAGE = "Switch to Chromium checkout." | 400 MESSAGE = "Switch to Chromium checkout." |
| 401 REQUIRES = "chrome_path" | 401 REQUIRES = "chrome_path" |
| 402 | 402 |
| 403 def RunStep(self): | 403 def RunStep(self): |
| 404 self["v8_path"] = os.getcwd() | 404 self["v8_path"] = os.getcwd() |
| 405 os.chdir(self["chrome_path"]) | 405 os.chdir(self["chrome_path"]) |
| 406 self.InitialEnvironmentChecks() | 406 self.InitialEnvironmentChecks() |
| 407 # Check for a clean workdir. | 407 # Check for a clean workdir. |
| 408 if not self.GitIsWorkdirClean(): | 408 if not self.GitIsWorkdirClean(): # pragma: no cover |
| 409 self.Die("Workspace is not clean. Please commit or undo your changes.") | 409 self.Die("Workspace is not clean. Please commit or undo your changes.") |
| 410 # Assert that the DEPS file is there. | 410 # Assert that the DEPS file is there. |
| 411 if not os.path.exists(self.Config(DEPS_FILE)): | 411 if not os.path.exists(self.Config(DEPS_FILE)): # pragma: no cover |
| 412 self.Die("DEPS file not present.") | 412 self.Die("DEPS file not present.") |
| 413 | 413 |
| 414 | 414 |
| 415 class UpdateChromiumCheckout(Step): | 415 class UpdateChromiumCheckout(Step): |
| 416 MESSAGE = "Update the checkout and create a new branch." | 416 MESSAGE = "Update the checkout and create a new branch." |
| 417 REQUIRES = "chrome_path" | 417 REQUIRES = "chrome_path" |
| 418 | 418 |
| 419 def RunStep(self): | 419 def RunStep(self): |
| 420 os.chdir(self["chrome_path"]) | 420 os.chdir(self["chrome_path"]) |
| 421 self.GitCheckout("master") | 421 self.GitCheckout("master") |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 | 461 |
| 462 | 462 |
| 463 class CleanUp(Step): | 463 class CleanUp(Step): |
| 464 MESSAGE = "Done!" | 464 MESSAGE = "Done!" |
| 465 | 465 |
| 466 def RunStep(self): | 466 def RunStep(self): |
| 467 if self["chrome_path"]: | 467 if self["chrome_path"]: |
| 468 print("Congratulations, you have successfully created the trunk " | 468 print("Congratulations, you have successfully created the trunk " |
| 469 "revision %s and rolled it into Chromium. Please don't forget to " | 469 "revision %s and rolled it into Chromium. Please don't forget to " |
| 470 "update the v8rel spreadsheet:" % self["version"]) | 470 "update the v8rel spreadsheet:" % self["version"]) |
| 471 else: | 471 else: # pragma: no cover |
| 472 print("Congratulations, you have successfully created the trunk " | 472 print("Congratulations, you have successfully created the trunk " |
| 473 "revision %s. Please don't forget to roll this new version into " | 473 "revision %s. Please don't forget to roll this new version into " |
| 474 "Chromium, and to update the v8rel spreadsheet:" | 474 "Chromium, and to update the v8rel spreadsheet:" |
| 475 % self["version"]) | 475 % self["version"]) |
| 476 print "%s\ttrunk\t%s" % (self["version"], | 476 print "%s\ttrunk\t%s" % (self["version"], |
| 477 self["trunk_revision"]) | 477 self["trunk_revision"]) |
| 478 | 478 |
| 479 self.CommonCleanup() | 479 self.CommonCleanup() |
| 480 if self.Config(TRUNKBRANCH) != self["current_branch"]: | 480 if self.Config(TRUNKBRANCH) != self["current_branch"]: |
| 481 self.GitDeleteBranch(self.Config(TRUNKBRANCH)) | 481 self.GitDeleteBranch(self.Config(TRUNKBRANCH)) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 493 parser.add_argument("-b", "--last-bleeding-edge", | 493 parser.add_argument("-b", "--last-bleeding-edge", |
| 494 help=("The git commit ID of the last bleeding edge " | 494 help=("The git commit ID of the last bleeding edge " |
| 495 "revision that was pushed to trunk. This is " | 495 "revision that was pushed to trunk. This is " |
| 496 "used for the auto-generated ChangeLog entry.")) | 496 "used for the auto-generated ChangeLog entry.")) |
| 497 parser.add_argument("-c", "--chromium", | 497 parser.add_argument("-c", "--chromium", |
| 498 help=("The path to your Chromium src/ " | 498 help=("The path to your Chromium src/ " |
| 499 "directory to automate the V8 roll.")) | 499 "directory to automate the V8 roll.")) |
| 500 parser.add_argument("-l", "--last-push", | 500 parser.add_argument("-l", "--last-push", |
| 501 help="The git commit ID of the last push to trunk.") | 501 help="The git commit ID of the last push to trunk.") |
| 502 | 502 |
| 503 def _ProcessOptions(self, options): | 503 def _ProcessOptions(self, options): # pragma: no cover |
| 504 if not options.manual and not options.reviewer: | 504 if not options.manual and not options.reviewer: |
| 505 print "A reviewer (-r) is required in (semi-)automatic mode." | 505 print "A reviewer (-r) is required in (semi-)automatic mode." |
| 506 return False | 506 return False |
| 507 if not options.manual and not options.chromium: | 507 if not options.manual and not options.chromium: |
| 508 print "A chromium checkout (-c) is required in (semi-)automatic mode." | 508 print "A chromium checkout (-c) is required in (semi-)automatic mode." |
| 509 return False | 509 return False |
| 510 if not options.manual and not options.author: | 510 if not options.manual and not options.author: |
| 511 print "Specify your chromium.org email with -a in (semi-)automatic mode." | 511 print "Specify your chromium.org email with -a in (semi-)automatic mode." |
| 512 return False | 512 return False |
| 513 | 513 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 536 TagRevision, | 536 TagRevision, |
| 537 CheckChromium, | 537 CheckChromium, |
| 538 SwitchChromium, | 538 SwitchChromium, |
| 539 UpdateChromiumCheckout, | 539 UpdateChromiumCheckout, |
| 540 UploadCL, | 540 UploadCL, |
| 541 SwitchV8, | 541 SwitchV8, |
| 542 CleanUp, | 542 CleanUp, |
| 543 ] | 543 ] |
| 544 | 544 |
| 545 | 545 |
| 546 if __name__ == "__main__": | 546 if __name__ == "__main__": # pragma: no cover |
| 547 sys.exit(PushToTrunk(CONFIG).Run()) | 547 sys.exit(PushToTrunk(CONFIG).Run()) |
| OLD | NEW |