| 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 12 matching lines...) Expand all Loading... |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 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 datetime | 29 import datetime |
| 30 import optparse | 30 import optparse |
| 31 import sys | 31 import sys |
| 32 import tempfile | 32 import tempfile |
| 33 import urllib2 |
| 33 | 34 |
| 34 from common_includes import * | 35 from common_includes import * |
| 35 | 36 |
| 36 TRUNKBRANCH = "TRUNKBRANCH" | 37 TRUNKBRANCH = "TRUNKBRANCH" |
| 37 CHROMIUM = "CHROMIUM" | 38 CHROMIUM = "CHROMIUM" |
| 38 DEPS_FILE = "DEPS_FILE" | 39 DEPS_FILE = "DEPS_FILE" |
| 39 | 40 |
| 40 CONFIG = { | 41 CONFIG = { |
| 41 BRANCHNAME: "prepare-push", | 42 BRANCHNAME: "prepare-push", |
| 42 TRUNKBRANCH: "trunk-push", | 43 TRUNKBRANCH: "trunk-push", |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 break | 85 break |
| 85 args = "log -1 --format=%H %s^ ChangeLog" % last_push | 86 args = "log -1 --format=%H %s^ ChangeLog" % last_push |
| 86 last_push = self.Git(args).strip() | 87 last_push = self.Git(args).strip() |
| 87 self.Persist("last_push", last_push) | 88 self.Persist("last_push", last_push) |
| 88 self._state["last_push"] = last_push | 89 self._state["last_push"] = last_push |
| 89 | 90 |
| 90 | 91 |
| 91 class PrepareChangeLog(Step): | 92 class PrepareChangeLog(Step): |
| 92 MESSAGE = "Prepare raw ChangeLog entry." | 93 MESSAGE = "Prepare raw ChangeLog entry." |
| 93 | 94 |
| 95 def Reload(self, body): |
| 96 """Attempts to reload the commit message from rietveld in order to allow |
| 97 late changes to the LOG flag. Note: This is brittle to future changes of |
| 98 the web page name or structure. |
| 99 """ |
| 100 match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", |
| 101 body, flags=re.M) |
| 102 if match: |
| 103 cl_url = "https://codereview.chromium.org/%s/description" % match.group(1) |
| 104 try: |
| 105 body = self.ReadURL(cl_url) |
| 106 except urllib2.URLError: |
| 107 pass |
| 108 return body |
| 109 |
| 94 def RunStep(self): | 110 def RunStep(self): |
| 95 self.RestoreIfUnset("last_push") | 111 self.RestoreIfUnset("last_push") |
| 96 | 112 |
| 97 # These version numbers are used again later for the trunk commit. | 113 # These version numbers are used again later for the trunk commit. |
| 98 self.ReadAndPersistVersion() | 114 self.ReadAndPersistVersion() |
| 99 | 115 |
| 100 date = datetime.date.today().strftime("%Y-%m-%d") | 116 date = datetime.date.today().strftime("%Y-%m-%d") |
| 101 self.Persist("date", date) | 117 self.Persist("date", date) |
| 102 output = "%s: Version %s.%s.%s\n\n" % (date, | 118 output = "%s: Version %s.%s.%s\n\n" % (date, |
| 103 self._state["major"], | 119 self._state["major"], |
| 104 self._state["minor"], | 120 self._state["minor"], |
| 105 self._state["build"]) | 121 self._state["build"]) |
| 106 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE)) | 122 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE)) |
| 107 | 123 |
| 108 args = "log %s..HEAD --format=%%H" % self._state["last_push"] | 124 args = "log %s..HEAD --format=%%H" % self._state["last_push"] |
| 109 commits = self.Git(args).strip() | 125 commits = self.Git(args).strip() |
| 110 | 126 |
| 111 # Cache raw commit messages. | 127 # Cache raw commit messages. |
| 112 commit_messages = [ | 128 commit_messages = [ |
| 113 [ | 129 [ |
| 114 self.Git("log -1 %s --format=\"%%s\"" % commit), | 130 self.Git("log -1 %s --format=\"%%s\"" % commit), |
| 115 self.Git("log -1 %s --format=\"%%B\"" % commit), | 131 self.Reload(self.Git("log -1 %s --format=\"%%B\"" % commit)), |
| 116 self.Git("log -1 %s --format=\"%%an\"" % commit), | 132 self.Git("log -1 %s --format=\"%%an\"" % commit), |
| 117 ] for commit in commits.splitlines() | 133 ] for commit in commits.splitlines() |
| 118 ] | 134 ] |
| 119 | 135 |
| 120 # Auto-format commit messages. | 136 # Auto-format commit messages. |
| 121 body = MakeChangeLogBody(commit_messages, auto_format=True) | 137 body = MakeChangeLogBody(commit_messages, auto_format=True) |
| 122 AppendToFile(body, self.Config(CHANGELOG_ENTRY_FILE)) | 138 AppendToFile(body, self.Config(CHANGELOG_ENTRY_FILE)) |
| 123 | 139 |
| 124 msg = (" Performance and stability improvements on all platforms." | 140 msg = (" Performance and stability improvements on all platforms." |
| 125 "\n#\n# The change log above is auto-generated. Please review if " | 141 "\n#\n# The change log above is auto-generated. Please review if " |
| (...skipping 18 matching lines...) Expand all Loading... |
| 144 # TODO(machenbach): Don't use EDITOR in forced mode as soon as script is | 160 # TODO(machenbach): Don't use EDITOR in forced mode as soon as script is |
| 145 # well tested. | 161 # well tested. |
| 146 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) | 162 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) |
| 147 handle, new_changelog = tempfile.mkstemp() | 163 handle, new_changelog = tempfile.mkstemp() |
| 148 os.close(handle) | 164 os.close(handle) |
| 149 | 165 |
| 150 # Strip comments and reformat with correct indentation. | 166 # Strip comments and reformat with correct indentation. |
| 151 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() | 167 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() |
| 152 changelog_entry = StripComments(changelog_entry) | 168 changelog_entry = StripComments(changelog_entry) |
| 153 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) | 169 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) |
| 170 changelog_entry = changelog_entry.lstrip() |
| 154 | 171 |
| 155 if changelog_entry == "": | 172 if changelog_entry == "": |
| 156 self.Die("Empty ChangeLog entry.") | 173 self.Die("Empty ChangeLog entry.") |
| 157 | 174 |
| 158 with open(new_changelog, "w") as f: | 175 with open(new_changelog, "w") as f: |
| 159 f.write(changelog_entry) | 176 f.write(changelog_entry) |
| 160 f.write("\n\n\n") # Explicitly insert two empty lines. | 177 f.write("\n\n\n") # Explicitly insert two empty lines. |
| 161 | 178 |
| 162 AppendToFile(FileToText(self.Config(CHANGELOG_FILE)), new_changelog) | 179 AppendToFile(FileToText(self.Config(CHANGELOG_FILE)), new_changelog) |
| 163 TextToFile(FileToText(new_changelog), self.Config(CHANGELOG_FILE)) | 180 TextToFile(FileToText(new_changelog), self.Config(CHANGELOG_FILE)) |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 result.add_option("-s", "--step", dest="s", | 551 result.add_option("-s", "--step", dest="s", |
| 535 help="Specify the step where to start work. Default: 0.", | 552 help="Specify the step where to start work. Default: 0.", |
| 536 default=0, type="int") | 553 default=0, type="int") |
| 537 return result | 554 return result |
| 538 | 555 |
| 539 | 556 |
| 540 def ProcessOptions(options): | 557 def ProcessOptions(options): |
| 541 if options.s < 0: | 558 if options.s < 0: |
| 542 print "Bad step number %d" % options.s | 559 print "Bad step number %d" % options.s |
| 543 return False | 560 return False |
| 561 if options.f and not options.r: |
| 562 print "A reviewer (-r) is required in forced mode." |
| 563 return False |
| 564 if options.f and not options.c: |
| 565 print "A chromium checkout (-c) is required in forced mode." |
| 566 return False |
| 544 return True | 567 return True |
| 545 | 568 |
| 546 | 569 |
| 547 def Main(): | 570 def Main(): |
| 548 parser = BuildOptions() | 571 parser = BuildOptions() |
| 549 (options, args) = parser.parse_args() | 572 (options, args) = parser.parse_args() |
| 550 if not ProcessOptions(options): | 573 if not ProcessOptions(options): |
| 551 parser.print_help() | 574 parser.print_help() |
| 552 return 1 | 575 return 1 |
| 553 RunPushToTrunk(CONFIG, options) | 576 RunPushToTrunk(CONFIG, options) |
| 554 | 577 |
| 555 if __name__ == "__main__": | 578 if __name__ == "__main__": |
| 556 sys.exit(Main()) | 579 sys.exit(Main()) |
| OLD | NEW |