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 |