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 |