Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: tools/push-to-trunk/push_to_trunk.py

Issue 148593004: A64: Synchronize with r18084. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/push-to-trunk/common_includes.py ('k') | tools/push-to-trunk/test_scripts.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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",
43 PERSISTFILE_BASENAME: "/tmp/v8-push-to-trunk-tempfile", 44 PERSISTFILE_BASENAME: "/tmp/v8-push-to-trunk-tempfile",
44 TEMP_BRANCH: "prepare-push-temporary-branch-created-by-script", 45 TEMP_BRANCH: "prepare-push-temporary-branch-created-by-script",
45 DOT_GIT_LOCATION: ".git", 46 DOT_GIT_LOCATION: ".git",
46 VERSION_FILE: "src/version.cc", 47 VERSION_FILE: "src/version.cc",
47 CHANGELOG_FILE: "ChangeLog", 48 CHANGELOG_FILE: "ChangeLog",
48 CHANGELOG_ENTRY_FILE: "/tmp/v8-push-to-trunk-tempfile-changelog-entry", 49 CHANGELOG_ENTRY_FILE: "/tmp/v8-push-to-trunk-tempfile-changelog-entry",
49 PATCH_FILE: "/tmp/v8-push-to-trunk-tempfile-patch-file", 50 PATCH_FILE: "/tmp/v8-push-to-trunk-tempfile-patch-file",
50 COMMITMSG_FILE: "/tmp/v8-push-to-trunk-tempfile-commitmsg", 51 COMMITMSG_FILE: "/tmp/v8-push-to-trunk-tempfile-commitmsg",
51 DEPS_FILE: "DEPS", 52 DEPS_FILE: "DEPS",
52 } 53 }
53 54
54 55
55 class Preparation(Step): 56 class Preparation(Step):
56 def __init__(self): 57 MESSAGE = "Preparation."
57 Step.__init__(self, "Preparation.")
58 58
59 def RunStep(self): 59 def RunStep(self):
60 self.InitialEnvironmentChecks() 60 self.InitialEnvironmentChecks()
61 self.CommonPrepare() 61 self.CommonPrepare()
62 self.PrepareBranch() 62 self.PrepareBranch()
63 self.DeleteBranch(self.Config(TRUNKBRANCH)) 63 self.DeleteBranch(self.Config(TRUNKBRANCH))
64 64
65 65
66 class FreshBranch(Step): 66 class FreshBranch(Step):
67 def __init__(self): 67 MESSAGE = "Create a fresh branch."
68 Step.__init__(self, "Create a fresh branch.")
69 68
70 def RunStep(self): 69 def RunStep(self):
71 args = "checkout -b %s svn/bleeding_edge" % self.Config(BRANCHNAME) 70 args = "checkout -b %s svn/bleeding_edge" % self.Config(BRANCHNAME)
72 if self.Git(args) is None: 71 if self.Git(args) is None:
73 self.Die("Creating branch %s failed." % self.Config(BRANCHNAME)) 72 self.Die("Creating branch %s failed." % self.Config(BRANCHNAME))
74 73
75 74
76 class DetectLastPush(Step): 75 class DetectLastPush(Step):
77 def __init__(self): 76 MESSAGE = "Detect commit ID of last push to trunk."
78 Step.__init__(self, "Detect commit ID of last push to trunk.")
79 77
80 def RunStep(self): 78 def RunStep(self):
81 last_push = (self._options.l or 79 last_push = (self._options.l or
82 self.Git("log -1 --format=%H ChangeLog").strip()) 80 self.Git("log -1 --format=%H ChangeLog").strip())
83 while True: 81 while True:
84 # Print assumed commit, circumventing git's pager. 82 # Print assumed commit, circumventing git's pager.
85 print self.Git("log -1 %s" % last_push) 83 print self.Git("log -1 %s" % last_push)
86 if self.Confirm("Is the commit printed above the last push to trunk?"): 84 if self.Confirm("Is the commit printed above the last push to trunk?"):
87 break 85 break
88 args = "log -1 --format=%H %s^ ChangeLog" % last_push 86 args = "log -1 --format=%H %s^ ChangeLog" % last_push
89 last_push = self.Git(args).strip() 87 last_push = self.Git(args).strip()
90 self.Persist("last_push", last_push) 88 self.Persist("last_push", last_push)
91 self._state["last_push"] = last_push 89 self._state["last_push"] = last_push
92 90
93 91
94 class PrepareChangeLog(Step): 92 class PrepareChangeLog(Step):
95 def __init__(self): 93 MESSAGE = "Prepare raw ChangeLog entry."
96 Step.__init__(self, "Prepare raw ChangeLog entry.") 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
97 109
98 def RunStep(self): 110 def RunStep(self):
99 self.RestoreIfUnset("last_push") 111 self.RestoreIfUnset("last_push")
100 112
101 # These version numbers are used again later for the trunk commit. 113 # These version numbers are used again later for the trunk commit.
102 self.ReadAndPersistVersion() 114 self.ReadAndPersistVersion()
103 115
104 date = datetime.date.today().strftime("%Y-%m-%d") 116 date = datetime.date.today().strftime("%Y-%m-%d")
105 self.Persist("date", date) 117 self.Persist("date", date)
106 output = "%s: Version %s.%s.%s\n\n" % (date, 118 output = "%s: Version %s.%s.%s\n\n" % (date,
107 self._state["major"], 119 self._state["major"],
108 self._state["minor"], 120 self._state["minor"],
109 self._state["build"]) 121 self._state["build"])
110 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE)) 122 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE))
111 123
112 args = "log %s..HEAD --format=%%H" % self._state["last_push"] 124 args = "log %s..HEAD --format=%%H" % self._state["last_push"]
113 commits = self.Git(args).strip() 125 commits = self.Git(args).strip()
114 126
115 def GetCommitMessages(): 127 # Cache raw commit messages.
116 for commit in commits.splitlines(): 128 commit_messages = [
117 yield [ 129 [
118 self.Git("log -1 %s --format=\"%%w(80,8,8)%%s\"" % commit), 130 self.Git("log -1 %s --format=\"%%s\"" % commit),
119 self.Git("log -1 %s --format=\"%%B\"" % commit), 131 self.Reload(self.Git("log -1 %s --format=\"%%B\"" % commit)),
120 self.Git("log -1 %s --format=\"%%w(80,8,8)(%%an)\"" % commit), 132 self.Git("log -1 %s --format=\"%%an\"" % commit),
121 ] 133 ] for commit in commits.splitlines()
134 ]
122 135
123 body = MakeChangeLogBody(GetCommitMessages) 136 # Auto-format commit messages.
137 body = MakeChangeLogBody(commit_messages, auto_format=True)
124 AppendToFile(body, self.Config(CHANGELOG_ENTRY_FILE)) 138 AppendToFile(body, self.Config(CHANGELOG_ENTRY_FILE))
125 139
126 msg = " Performance and stability improvements on all platforms.\n" 140 msg = (" Performance and stability improvements on all platforms."
141 "\n#\n# The change log above is auto-generated. Please review if "
142 "all relevant\n# commit messages from the list below are included."
143 "\n# All lines starting with # will be stripped.\n#\n")
127 AppendToFile(msg, self.Config(CHANGELOG_ENTRY_FILE)) 144 AppendToFile(msg, self.Config(CHANGELOG_ENTRY_FILE))
128 145
146 # Include unformatted commit messages as a reference in a comment.
147 comment_body = MakeComment(MakeChangeLogBody(commit_messages))
148 AppendToFile(comment_body, self.Config(CHANGELOG_ENTRY_FILE))
149
129 150
130 class EditChangeLog(Step): 151 class EditChangeLog(Step):
131 def __init__(self): 152 MESSAGE = "Edit ChangeLog entry."
132 Step.__init__(self, "Edit ChangeLog entry.")
133 153
134 def RunStep(self): 154 def RunStep(self):
135 print ("Please press <Return> to have your EDITOR open the ChangeLog " 155 print ("Please press <Return> to have your EDITOR open the ChangeLog "
136 "entry, then edit its contents to your liking. When you're done, " 156 "entry, then edit its contents to your liking. When you're done, "
137 "save the file and exit your EDITOR. ") 157 "save the file and exit your EDITOR. ")
138 self.ReadLine(default="") 158 self.ReadLine(default="")
139 159
140 # 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
141 # well tested. 161 # well tested.
142 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) 162 self.Editor(self.Config(CHANGELOG_ENTRY_FILE))
143 handle, new_changelog = tempfile.mkstemp() 163 handle, new_changelog = tempfile.mkstemp()
144 os.close(handle) 164 os.close(handle)
145 165
146 # (1) Eliminate tabs, (2) fix too little and (3) too much indentation, and 166 # Strip comments and reformat with correct indentation.
147 # (4) eliminate trailing whitespace.
148 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() 167 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip()
149 changelog_entry = MSub(r"\t", r" ", changelog_entry) 168 changelog_entry = StripComments(changelog_entry)
150 changelog_entry = MSub(r"^ {1,7}([^ ])", r" \1", changelog_entry) 169 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines()))
151 changelog_entry = MSub(r"^ {9,80}([^ ])", r" \1", changelog_entry) 170 changelog_entry = changelog_entry.lstrip()
152 changelog_entry = MSub(r" +$", r"", changelog_entry)
153 171
154 if changelog_entry == "": 172 if changelog_entry == "":
155 self.Die("Empty ChangeLog entry.") 173 self.Die("Empty ChangeLog entry.")
156 174
157 with open(new_changelog, "w") as f: 175 with open(new_changelog, "w") as f:
158 f.write(changelog_entry) 176 f.write(changelog_entry)
159 f.write("\n\n\n") # Explicitly insert two empty lines. 177 f.write("\n\n\n") # Explicitly insert two empty lines.
160 178
161 AppendToFile(FileToText(self.Config(CHANGELOG_FILE)), new_changelog) 179 AppendToFile(FileToText(self.Config(CHANGELOG_FILE)), new_changelog)
162 TextToFile(FileToText(new_changelog), self.Config(CHANGELOG_FILE)) 180 TextToFile(FileToText(new_changelog), self.Config(CHANGELOG_FILE))
163 os.remove(new_changelog) 181 os.remove(new_changelog)
164 182
165 183
166 class IncrementVersion(Step): 184 class IncrementVersion(Step):
167 def __init__(self): 185 MESSAGE = "Increment version number."
168 Step.__init__(self, "Increment version number.")
169 186
170 def RunStep(self): 187 def RunStep(self):
171 self.RestoreIfUnset("build") 188 self.RestoreIfUnset("build")
172 new_build = str(int(self._state["build"]) + 1) 189 new_build = str(int(self._state["build"]) + 1)
173 190
174 if self.Confirm(("Automatically increment BUILD_NUMBER? (Saying 'n' will " 191 if self.Confirm(("Automatically increment BUILD_NUMBER? (Saying 'n' will "
175 "fire up your EDITOR on %s so you can make arbitrary " 192 "fire up your EDITOR on %s so you can make arbitrary "
176 "changes. When you're done, save the file and exit your " 193 "changes. When you're done, save the file and exit your "
177 "EDITOR.)" % self.Config(VERSION_FILE))): 194 "EDITOR.)" % self.Config(VERSION_FILE))):
178 text = FileToText(self.Config(VERSION_FILE)) 195 text = FileToText(self.Config(VERSION_FILE))
179 text = MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$", 196 text = MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
180 r"\g<space>%s" % new_build, 197 r"\g<space>%s" % new_build,
181 text) 198 text)
182 TextToFile(text, self.Config(VERSION_FILE)) 199 TextToFile(text, self.Config(VERSION_FILE))
183 else: 200 else:
184 self.Editor(self.Config(VERSION_FILE)) 201 self.Editor(self.Config(VERSION_FILE))
185 202
186 self.ReadAndPersistVersion("new_") 203 self.ReadAndPersistVersion("new_")
187 204
188 205
189 class CommitLocal(Step): 206 class CommitLocal(Step):
190 def __init__(self): 207 MESSAGE = "Commit to local branch."
191 Step.__init__(self, "Commit to local branch.")
192 208
193 def RunStep(self): 209 def RunStep(self):
194 self.RestoreVersionIfUnset("new_") 210 self.RestoreVersionIfUnset("new_")
195 prep_commit_msg = ("Prepare push to trunk. " 211 prep_commit_msg = ("Prepare push to trunk. "
196 "Now working on version %s.%s.%s." % (self._state["new_major"], 212 "Now working on version %s.%s.%s." % (self._state["new_major"],
197 self._state["new_minor"], 213 self._state["new_minor"],
198 self._state["new_build"])) 214 self._state["new_build"]))
199 self.Persist("prep_commit_msg", prep_commit_msg) 215 self.Persist("prep_commit_msg", prep_commit_msg)
200 if self.Git("commit -a -m \"%s\"" % prep_commit_msg) is None: 216 if self.Git("commit -a -m \"%s\"" % prep_commit_msg) is None:
201 self.Die("'git commit -a' failed.") 217 self.Die("'git commit -a' failed.")
202 218
203 219
204 class CommitRepository(Step): 220 class CommitRepository(Step):
205 def __init__(self): 221 MESSAGE = "Commit to the repository."
206 Step.__init__(self, "Commit to the repository.")
207 222
208 def RunStep(self): 223 def RunStep(self):
209 self.WaitForLGTM() 224 self.WaitForLGTM()
210 # Re-read the ChangeLog entry (to pick up possible changes). 225 # Re-read the ChangeLog entry (to pick up possible changes).
211 # FIXME(machenbach): This was hanging once with a broken pipe. 226 # FIXME(machenbach): This was hanging once with a broken pipe.
212 TextToFile(GetLastChangeLogEntries(self.Config(CHANGELOG_FILE)), 227 TextToFile(GetLastChangeLogEntries(self.Config(CHANGELOG_FILE)),
213 self.Config(CHANGELOG_ENTRY_FILE)) 228 self.Config(CHANGELOG_ENTRY_FILE))
214 229
215 if self.Git("cl dcommit -f", "PRESUBMIT_TREE_CHECK=\"skip\"") is None: 230 if self.Git("cl dcommit -f", "PRESUBMIT_TREE_CHECK=\"skip\"") is None:
216 self.Die("'git cl dcommit' failed, please try again.") 231 self.Die("'git cl dcommit' failed, please try again.")
217 232
218 233
219 class StragglerCommits(Step): 234 class StragglerCommits(Step):
220 def __init__(self): 235 MESSAGE = ("Fetch straggler commits that sneaked in since this script was "
221 Step.__init__(self, "Fetch straggler commits that sneaked in since this " 236 "started.")
222 "script was started.")
223 237
224 def RunStep(self): 238 def RunStep(self):
225 if self.Git("svn fetch") is None: 239 if self.Git("svn fetch") is None:
226 self.Die("'git svn fetch' failed.") 240 self.Die("'git svn fetch' failed.")
227 self.Git("checkout svn/bleeding_edge") 241 self.Git("checkout svn/bleeding_edge")
228 self.RestoreIfUnset("prep_commit_msg") 242 self.RestoreIfUnset("prep_commit_msg")
229 args = "log -1 --format=%%H --grep=\"%s\"" % self._state["prep_commit_msg"] 243 args = "log -1 --format=%%H --grep=\"%s\"" % self._state["prep_commit_msg"]
230 prepare_commit_hash = self.Git(args).strip() 244 prepare_commit_hash = self.Git(args).strip()
231 self.Persist("prepare_commit_hash", prepare_commit_hash) 245 self.Persist("prepare_commit_hash", prepare_commit_hash)
232 246
233 247
234 class SquashCommits(Step): 248 class SquashCommits(Step):
235 def __init__(self): 249 MESSAGE = "Squash commits into one."
236 Step.__init__(self, "Squash commits into one.")
237 250
238 def RunStep(self): 251 def RunStep(self):
239 # Instead of relying on "git rebase -i", we'll just create a diff, because 252 # Instead of relying on "git rebase -i", we'll just create a diff, because
240 # that's easier to automate. 253 # that's easier to automate.
241 self.RestoreIfUnset("prepare_commit_hash") 254 self.RestoreIfUnset("prepare_commit_hash")
242 args = "diff svn/trunk %s" % self._state["prepare_commit_hash"] 255 args = "diff svn/trunk %s" % self._state["prepare_commit_hash"]
243 TextToFile(self.Git(args), self.Config(PATCH_FILE)) 256 TextToFile(self.Git(args), self.Config(PATCH_FILE))
244 257
245 # Convert the ChangeLog entry to commit message format: 258 # Convert the ChangeLog entry to commit message format:
246 # - remove date 259 # - remove date
(...skipping 21 matching lines...) Expand all
268 }\ 281 }\
269 }'" % (changelog_entry, self._state["date"])) 282 }'" % (changelog_entry, self._state["date"]))
270 283
271 if not text: 284 if not text:
272 self.Die("Commit message editing failed.") 285 self.Die("Commit message editing failed.")
273 TextToFile(text, self.Config(COMMITMSG_FILE)) 286 TextToFile(text, self.Config(COMMITMSG_FILE))
274 os.remove(self.Config(CHANGELOG_ENTRY_FILE)) 287 os.remove(self.Config(CHANGELOG_ENTRY_FILE))
275 288
276 289
277 class NewBranch(Step): 290 class NewBranch(Step):
278 def __init__(self): 291 MESSAGE = "Create a new branch from trunk."
279 Step.__init__(self, "Create a new branch from trunk.")
280 292
281 def RunStep(self): 293 def RunStep(self):
282 if self.Git("checkout -b %s svn/trunk" % self.Config(TRUNKBRANCH)) is None: 294 if self.Git("checkout -b %s svn/trunk" % self.Config(TRUNKBRANCH)) is None:
283 self.Die("Checking out a new branch '%s' failed." % 295 self.Die("Checking out a new branch '%s' failed." %
284 self.Config(TRUNKBRANCH)) 296 self.Config(TRUNKBRANCH))
285 297
286 298
287 class ApplyChanges(Step): 299 class ApplyChanges(Step):
288 def __init__(self): 300 MESSAGE = "Apply squashed changes."
289 Step.__init__(self, "Apply squashed changes.")
290 301
291 def RunStep(self): 302 def RunStep(self):
292 self.ApplyPatch(self.Config(PATCH_FILE)) 303 self.ApplyPatch(self.Config(PATCH_FILE))
293 Command("rm", "-f %s*" % self.Config(PATCH_FILE)) 304 Command("rm", "-f %s*" % self.Config(PATCH_FILE))
294 305
295 306
296 class SetVersion(Step): 307 class SetVersion(Step):
297 def __init__(self): 308 MESSAGE = "Set correct version for trunk."
298 Step.__init__(self, "Set correct version for trunk.")
299 309
300 def RunStep(self): 310 def RunStep(self):
301 self.RestoreVersionIfUnset() 311 self.RestoreVersionIfUnset()
302 output = "" 312 output = ""
303 for line in FileToText(self.Config(VERSION_FILE)).splitlines(): 313 for line in FileToText(self.Config(VERSION_FILE)).splitlines():
304 if line.startswith("#define MAJOR_VERSION"): 314 if line.startswith("#define MAJOR_VERSION"):
305 line = re.sub("\d+$", self._state["major"], line) 315 line = re.sub("\d+$", self._state["major"], line)
306 elif line.startswith("#define MINOR_VERSION"): 316 elif line.startswith("#define MINOR_VERSION"):
307 line = re.sub("\d+$", self._state["minor"], line) 317 line = re.sub("\d+$", self._state["minor"], line)
308 elif line.startswith("#define BUILD_NUMBER"): 318 elif line.startswith("#define BUILD_NUMBER"):
309 line = re.sub("\d+$", self._state["build"], line) 319 line = re.sub("\d+$", self._state["build"], line)
310 elif line.startswith("#define PATCH_LEVEL"): 320 elif line.startswith("#define PATCH_LEVEL"):
311 line = re.sub("\d+$", "0", line) 321 line = re.sub("\d+$", "0", line)
312 elif line.startswith("#define IS_CANDIDATE_VERSION"): 322 elif line.startswith("#define IS_CANDIDATE_VERSION"):
313 line = re.sub("\d+$", "0", line) 323 line = re.sub("\d+$", "0", line)
314 output += "%s\n" % line 324 output += "%s\n" % line
315 TextToFile(output, self.Config(VERSION_FILE)) 325 TextToFile(output, self.Config(VERSION_FILE))
316 326
317 327
318 class CommitTrunk(Step): 328 class CommitTrunk(Step):
319 def __init__(self): 329 MESSAGE = "Commit to local trunk branch."
320 Step.__init__(self, "Commit to local trunk branch.")
321 330
322 def RunStep(self): 331 def RunStep(self):
323 self.Git("add \"%s\"" % self.Config(VERSION_FILE)) 332 self.Git("add \"%s\"" % self.Config(VERSION_FILE))
324 if self.Git("commit -F \"%s\"" % self.Config(COMMITMSG_FILE)) is None: 333 if self.Git("commit -F \"%s\"" % self.Config(COMMITMSG_FILE)) is None:
325 self.Die("'git commit' failed.") 334 self.Die("'git commit' failed.")
326 Command("rm", "-f %s*" % self.Config(COMMITMSG_FILE)) 335 Command("rm", "-f %s*" % self.Config(COMMITMSG_FILE))
327 336
328 337
329 class SanityCheck(Step): 338 class SanityCheck(Step):
330 def __init__(self): 339 MESSAGE = "Sanity check."
331 Step.__init__(self, "Sanity check.")
332 340
333 def RunStep(self): 341 def RunStep(self):
334 if not self.Confirm("Please check if your local checkout is sane: Inspect " 342 if not self.Confirm("Please check if your local checkout is sane: Inspect "
335 "%s, compile, run tests. Do you want to commit this new trunk " 343 "%s, compile, run tests. Do you want to commit this new trunk "
336 "revision to the repository?" % self.Config(VERSION_FILE)): 344 "revision to the repository?" % self.Config(VERSION_FILE)):
337 self.Die("Execution canceled.") 345 self.Die("Execution canceled.")
338 346
339 347
340 class CommitSVN(Step): 348 class CommitSVN(Step):
341 def __init__(self): 349 MESSAGE = "Commit to SVN."
342 Step.__init__(self, "Commit to SVN.")
343 350
344 def RunStep(self): 351 def RunStep(self):
345 result = self.Git("svn dcommit 2>&1") 352 result = self.Git("svn dcommit 2>&1")
346 if not result: 353 if not result:
347 self.Die("'git svn dcommit' failed.") 354 self.Die("'git svn dcommit' failed.")
348 result = filter(lambda x: re.search(r"^Committed r[0-9]+", x), 355 result = filter(lambda x: re.search(r"^Committed r[0-9]+", x),
349 result.splitlines()) 356 result.splitlines())
350 if len(result) > 0: 357 if len(result) > 0:
351 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0]) 358 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0])
352 359
353 # Sometimes grepping for the revision fails. No idea why. If you figure 360 # Sometimes grepping for the revision fails. No idea why. If you figure
354 # out why it is flaky, please do fix it properly. 361 # out why it is flaky, please do fix it properly.
355 if not trunk_revision: 362 if not trunk_revision:
356 print("Sorry, grepping for the SVN revision failed. Please look for it " 363 print("Sorry, grepping for the SVN revision failed. Please look for it "
357 "in the last command's output above and provide it manually (just " 364 "in the last command's output above and provide it manually (just "
358 "the number, without the leading \"r\").") 365 "the number, without the leading \"r\").")
359 self.DieInForcedMode("Can't prompt in forced mode.") 366 self.DieInForcedMode("Can't prompt in forced mode.")
360 while not trunk_revision: 367 while not trunk_revision:
361 print "> ", 368 print "> ",
362 trunk_revision = self.ReadLine() 369 trunk_revision = self.ReadLine()
363 self.Persist("trunk_revision", trunk_revision) 370 self.Persist("trunk_revision", trunk_revision)
364 371
365 372
366 class TagRevision(Step): 373 class TagRevision(Step):
367 def __init__(self): 374 MESSAGE = "Tag the new revision."
368 Step.__init__(self, "Tag the new revision.")
369 375
370 def RunStep(self): 376 def RunStep(self):
371 self.RestoreVersionIfUnset() 377 self.RestoreVersionIfUnset()
372 ver = "%s.%s.%s" % (self._state["major"], 378 ver = "%s.%s.%s" % (self._state["major"],
373 self._state["minor"], 379 self._state["minor"],
374 self._state["build"]) 380 self._state["build"])
375 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None: 381 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None:
376 self.Die("'git svn tag' failed.") 382 self.Die("'git svn tag' failed.")
377 383
378 384
379 class CheckChromium(Step): 385 class CheckChromium(Step):
380 def __init__(self): 386 MESSAGE = "Ask for chromium checkout."
381 Step.__init__(self, "Ask for chromium checkout.")
382 387
383 def Run(self): 388 def Run(self):
384 chrome_path = self._options.c 389 chrome_path = self._options.c
385 if not chrome_path: 390 if not chrome_path:
386 self.DieInForcedMode("Please specify the path to a Chromium checkout in " 391 self.DieInForcedMode("Please specify the path to a Chromium checkout in "
387 "forced mode.") 392 "forced mode.")
388 print ("Do you have a \"NewGit\" Chromium checkout and want " 393 print ("Do you have a \"NewGit\" Chromium checkout and want "
389 "this script to automate creation of the roll CL? If yes, enter the " 394 "this script to automate creation of the roll CL? If yes, enter the "
390 "path to (and including) the \"src\" directory here, otherwise just " 395 "path to (and including) the \"src\" directory here, otherwise just "
391 "press <Return>: "), 396 "press <Return>: "),
392 chrome_path = self.ReadLine() 397 chrome_path = self.ReadLine()
393 self.Persist("chrome_path", chrome_path) 398 self.Persist("chrome_path", chrome_path)
394 399
395 400
396 class SwitchChromium(Step): 401 class SwitchChromium(Step):
397 def __init__(self): 402 MESSAGE = "Switch to Chromium checkout."
398 Step.__init__(self, "Switch to Chromium checkout.", requires="chrome_path") 403 REQUIRES = "chrome_path"
399 404
400 def RunStep(self): 405 def RunStep(self):
401 v8_path = os.getcwd() 406 v8_path = os.getcwd()
402 self.Persist("v8_path", v8_path) 407 self.Persist("v8_path", v8_path)
403 os.chdir(self._state["chrome_path"]) 408 os.chdir(self._state["chrome_path"])
404 self.InitialEnvironmentChecks() 409 self.InitialEnvironmentChecks()
405 # Check for a clean workdir. 410 # Check for a clean workdir.
406 if self.Git("status -s -uno").strip() != "": 411 if self.Git("status -s -uno").strip() != "":
407 self.Die("Workspace is not clean. Please commit or undo your changes.") 412 self.Die("Workspace is not clean. Please commit or undo your changes.")
408 # Assert that the DEPS file is there. 413 # Assert that the DEPS file is there.
409 if not os.path.exists(self.Config(DEPS_FILE)): 414 if not os.path.exists(self.Config(DEPS_FILE)):
410 self.Die("DEPS file not present.") 415 self.Die("DEPS file not present.")
411 416
412 417
413 class UpdateChromiumCheckout(Step): 418 class UpdateChromiumCheckout(Step):
414 def __init__(self): 419 MESSAGE = "Update the checkout and create a new branch."
415 Step.__init__(self, "Update the checkout and create a new branch.", 420 REQUIRES = "chrome_path"
416 requires="chrome_path")
417 421
418 def RunStep(self): 422 def RunStep(self):
419 os.chdir(self._state["chrome_path"]) 423 os.chdir(self._state["chrome_path"])
420 if self.Git("checkout master") is None: 424 if self.Git("checkout master") is None:
421 self.Die("'git checkout master' failed.") 425 self.Die("'git checkout master' failed.")
422 if self.Git("pull") is None: 426 if self.Git("pull") is None:
423 self.Die("'git pull' failed, please try again.") 427 self.Die("'git pull' failed, please try again.")
424 428
425 self.RestoreIfUnset("trunk_revision") 429 self.RestoreIfUnset("trunk_revision")
426 args = "checkout -b v8-roll-%s" % self._state["trunk_revision"] 430 args = "checkout -b v8-roll-%s" % self._state["trunk_revision"]
427 if self.Git(args) is None: 431 if self.Git(args) is None:
428 self.Die("Failed to checkout a new branch.") 432 self.Die("Failed to checkout a new branch.")
429 433
430 434
431 class UploadCL(Step): 435 class UploadCL(Step):
432 def __init__(self): 436 MESSAGE = "Create and upload CL."
433 Step.__init__(self, "Create and upload CL.", requires="chrome_path") 437 REQUIRES = "chrome_path"
434 438
435 def RunStep(self): 439 def RunStep(self):
436 os.chdir(self._state["chrome_path"]) 440 os.chdir(self._state["chrome_path"])
437 441
438 # Patch DEPS file. 442 # Patch DEPS file.
439 self.RestoreIfUnset("trunk_revision") 443 self.RestoreIfUnset("trunk_revision")
440 deps = FileToText(self.Config(DEPS_FILE)) 444 deps = FileToText(self.Config(DEPS_FILE))
441 deps = re.sub("(?<=\"v8_revision\": \")([0-9]+)(?=\")", 445 deps = re.sub("(?<=\"v8_revision\": \")([0-9]+)(?=\")",
442 self._state["trunk_revision"], 446 self._state["trunk_revision"],
443 deps) 447 deps)
444 TextToFile(deps, self.Config(DEPS_FILE)) 448 TextToFile(deps, self.Config(DEPS_FILE))
445 449
446 self.RestoreVersionIfUnset() 450 self.RestoreVersionIfUnset()
447 ver = "%s.%s.%s" % (self._state["major"], 451 ver = "%s.%s.%s" % (self._state["major"],
448 self._state["minor"], 452 self._state["minor"],
449 self._state["build"]) 453 self._state["build"])
450 if self._options and self._options.r: 454 if self._options and self._options.r:
451 print "Using account %s for review." % self._options.r 455 print "Using account %s for review." % self._options.r
452 rev = self._options.r 456 rev = self._options.r
453 else: 457 else:
454 print "Please enter the email address of a reviewer for the roll CL: ", 458 print "Please enter the email address of a reviewer for the roll CL: ",
455 self.DieInForcedMode("A reviewer must be specified in forced mode.") 459 self.DieInForcedMode("A reviewer must be specified in forced mode.")
456 rev = self.ReadLine() 460 rev = self.ReadLine()
457 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev) 461 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev)
458 if self.Git(args) is None: 462 if self.Git(args) is None:
459 self.Die("'git commit' failed.") 463 self.Die("'git commit' failed.")
460 if self.Git("cl upload --send-mail", pipe=False) is None: 464 force_flag = " -f" if self._options.f else ""
465 if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None:
461 self.Die("'git cl upload' failed, please try again.") 466 self.Die("'git cl upload' failed, please try again.")
462 print "CL uploaded." 467 print "CL uploaded."
463 468
464 469
465 class SwitchV8(Step): 470 class SwitchV8(Step):
466 def __init__(self): 471 MESSAGE = "Returning to V8 checkout."
467 Step.__init__(self, "Returning to V8 checkout.", requires="chrome_path") 472 REQUIRES = "chrome_path"
468 473
469 def RunStep(self): 474 def RunStep(self):
470 self.RestoreIfUnset("v8_path") 475 self.RestoreIfUnset("v8_path")
471 os.chdir(self._state["v8_path"]) 476 os.chdir(self._state["v8_path"])
472 477
473 478
474 class CleanUp(Step): 479 class CleanUp(Step):
475 def __init__(self): 480 MESSAGE = "Done!"
476 Step.__init__(self, "Done!")
477 481
478 def RunStep(self): 482 def RunStep(self):
479 self.RestoreVersionIfUnset() 483 self.RestoreVersionIfUnset()
480 ver = "%s.%s.%s" % (self._state["major"], 484 ver = "%s.%s.%s" % (self._state["major"],
481 self._state["minor"], 485 self._state["minor"],
482 self._state["build"]) 486 self._state["build"])
483 self.RestoreIfUnset("trunk_revision") 487 self.RestoreIfUnset("trunk_revision")
484 self.RestoreIfUnset("chrome_path") 488 self.RestoreIfUnset("chrome_path")
485 489
486 if self._state["chrome_path"]: 490 if self._state["chrome_path"]:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 result.add_option("-s", "--step", dest="s", 551 result.add_option("-s", "--step", dest="s",
548 help="Specify the step where to start work. Default: 0.", 552 help="Specify the step where to start work. Default: 0.",
549 default=0, type="int") 553 default=0, type="int")
550 return result 554 return result
551 555
552 556
553 def ProcessOptions(options): 557 def ProcessOptions(options):
554 if options.s < 0: 558 if options.s < 0:
555 print "Bad step number %d" % options.s 559 print "Bad step number %d" % options.s
556 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
557 return True 567 return True
558 568
559 569
560 def Main(): 570 def Main():
561 parser = BuildOptions() 571 parser = BuildOptions()
562 (options, args) = parser.parse_args() 572 (options, args) = parser.parse_args()
563 if not ProcessOptions(options): 573 if not ProcessOptions(options):
564 parser.print_help() 574 parser.print_help()
565 return 1 575 return 1
566 RunPushToTrunk(CONFIG, options) 576 RunPushToTrunk(CONFIG, options)
567 577
568 if __name__ == "__main__": 578 if __name__ == "__main__":
569 sys.exit(Main()) 579 sys.exit(Main())
OLDNEW
« no previous file with comments | « tools/push-to-trunk/common_includes.py ('k') | tools/push-to-trunk/test_scripts.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698