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

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

Issue 136643008: A64: Synchronize with r18256. (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
11 # disclaimer in the documentation and/or other materials provided 11 # disclaimer in the documentation and/or other materials provided
12 # with the distribution. 12 # with the distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived 14 # contributors may be used to endorse or promote products derived
15 # from this software without specific prior written permission. 15 # from this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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
30 import optparse 29 import optparse
31 import sys 30 import sys
32 import tempfile 31 import tempfile
33 import urllib2 32 import urllib2
34 33
35 from common_includes import * 34 from common_includes import *
36 35
37 TRUNKBRANCH = "TRUNKBRANCH" 36 TRUNKBRANCH = "TRUNKBRANCH"
38 CHROMIUM = "CHROMIUM" 37 CHROMIUM = "CHROMIUM"
39 DEPS_FILE = "DEPS_FILE" 38 DEPS_FILE = "DEPS_FILE"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 def Reload(self, body): 94 def Reload(self, body):
96 """Attempts to reload the commit message from rietveld in order to allow 95 """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 96 late changes to the LOG flag. Note: This is brittle to future changes of
98 the web page name or structure. 97 the web page name or structure.
99 """ 98 """
100 match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", 99 match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$",
101 body, flags=re.M) 100 body, flags=re.M)
102 if match: 101 if match:
103 cl_url = "https://codereview.chromium.org/%s/description" % match.group(1) 102 cl_url = "https://codereview.chromium.org/%s/description" % match.group(1)
104 try: 103 try:
105 body = self.ReadURL(cl_url) 104 # Fetch from Rietveld but only retry once with one second delay since
105 # there might be many revisions.
106 body = self.ReadURL(cl_url, wait_plan=[1])
106 except urllib2.URLError: 107 except urllib2.URLError:
107 pass 108 pass
108 return body 109 return body
109 110
110 def RunStep(self): 111 def RunStep(self):
111 self.RestoreIfUnset("last_push") 112 self.RestoreIfUnset("last_push")
112 113
113 # These version numbers are used again later for the trunk commit. 114 # These version numbers are used again later for the trunk commit.
114 self.ReadAndPersistVersion() 115 self.ReadAndPersistVersion()
115 116
116 date = datetime.date.today().strftime("%Y-%m-%d") 117 date = self.GetDate()
117 self.Persist("date", date) 118 self.Persist("date", date)
118 output = "%s: Version %s.%s.%s\n\n" % (date, 119 output = "%s: Version %s.%s.%s\n\n" % (date,
119 self._state["major"], 120 self._state["major"],
120 self._state["minor"], 121 self._state["minor"],
121 self._state["build"]) 122 self._state["build"])
122 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE)) 123 TextToFile(output, self.Config(CHANGELOG_ENTRY_FILE))
123 124
124 args = "log %s..HEAD --format=%%H" % self._state["last_push"] 125 args = "log %s..HEAD --format=%%H" % self._state["last_push"]
125 commits = self.Git(args).strip() 126 commits = self.Git(args).strip()
126 127
(...skipping 22 matching lines...) Expand all
149 150
150 151
151 class EditChangeLog(Step): 152 class EditChangeLog(Step):
152 MESSAGE = "Edit ChangeLog entry." 153 MESSAGE = "Edit ChangeLog entry."
153 154
154 def RunStep(self): 155 def RunStep(self):
155 print ("Please press <Return> to have your EDITOR open the ChangeLog " 156 print ("Please press <Return> to have your EDITOR open the ChangeLog "
156 "entry, then edit its contents to your liking. When you're done, " 157 "entry, then edit its contents to your liking. When you're done, "
157 "save the file and exit your EDITOR. ") 158 "save the file and exit your EDITOR. ")
158 self.ReadLine(default="") 159 self.ReadLine(default="")
159
160 # TODO(machenbach): Don't use EDITOR in forced mode as soon as script is
161 # well tested.
162 self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) 160 self.Editor(self.Config(CHANGELOG_ENTRY_FILE))
163 handle, new_changelog = tempfile.mkstemp() 161 handle, new_changelog = tempfile.mkstemp()
164 os.close(handle) 162 os.close(handle)
165 163
166 # Strip comments and reformat with correct indentation. 164 # Strip comments and reformat with correct indentation.
167 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip() 165 changelog_entry = FileToText(self.Config(CHANGELOG_ENTRY_FILE)).rstrip()
168 changelog_entry = StripComments(changelog_entry) 166 changelog_entry = StripComments(changelog_entry)
169 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) 167 changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines()))
170 changelog_entry = changelog_entry.lstrip() 168 changelog_entry = changelog_entry.lstrip()
171 169
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 class CommitLocal(Step): 204 class CommitLocal(Step):
207 MESSAGE = "Commit to local branch." 205 MESSAGE = "Commit to local branch."
208 206
209 def RunStep(self): 207 def RunStep(self):
210 self.RestoreVersionIfUnset("new_") 208 self.RestoreVersionIfUnset("new_")
211 prep_commit_msg = ("Prepare push to trunk. " 209 prep_commit_msg = ("Prepare push to trunk. "
212 "Now working on version %s.%s.%s." % (self._state["new_major"], 210 "Now working on version %s.%s.%s." % (self._state["new_major"],
213 self._state["new_minor"], 211 self._state["new_minor"],
214 self._state["new_build"])) 212 self._state["new_build"]))
215 self.Persist("prep_commit_msg", prep_commit_msg) 213 self.Persist("prep_commit_msg", prep_commit_msg)
216 if self.Git("commit -a -m \"%s\"" % prep_commit_msg) is None: 214
215 # Include optional TBR only in the git command. The persisted commit
216 # message is used for finding the commit again later.
217 review = "\n\nTBR=%s" % self._options.r if not self.IsManual() else ""
218 if self.Git("commit -a -m \"%s%s\"" % (prep_commit_msg, review)) is None:
217 self.Die("'git commit -a' failed.") 219 self.Die("'git commit -a' failed.")
218 220
219 221
220 class CommitRepository(Step): 222 class CommitRepository(Step):
221 MESSAGE = "Commit to the repository." 223 MESSAGE = "Commit to the repository."
222 224
223 def RunStep(self): 225 def RunStep(self):
224 self.WaitForLGTM() 226 self.WaitForLGTM()
225 # Re-read the ChangeLog entry (to pick up possible changes). 227 # Re-read the ChangeLog entry (to pick up possible changes).
226 # FIXME(machenbach): This was hanging once with a broken pipe. 228 # FIXME(machenbach): This was hanging once with a broken pipe.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 result.splitlines()) 358 result.splitlines())
357 if len(result) > 0: 359 if len(result) > 0:
358 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0]) 360 trunk_revision = re.sub(r"^Committed r([0-9]+)", r"\1", result[0])
359 361
360 # Sometimes grepping for the revision fails. No idea why. If you figure 362 # Sometimes grepping for the revision fails. No idea why. If you figure
361 # out why it is flaky, please do fix it properly. 363 # out why it is flaky, please do fix it properly.
362 if not trunk_revision: 364 if not trunk_revision:
363 print("Sorry, grepping for the SVN revision failed. Please look for it " 365 print("Sorry, grepping for the SVN revision failed. Please look for it "
364 "in the last command's output above and provide it manually (just " 366 "in the last command's output above and provide it manually (just "
365 "the number, without the leading \"r\").") 367 "the number, without the leading \"r\").")
366 self.DieInForcedMode("Can't prompt in forced mode.") 368 self.DieNoManualMode("Can't prompt in forced mode.")
367 while not trunk_revision: 369 while not trunk_revision:
368 print "> ", 370 print "> ",
369 trunk_revision = self.ReadLine() 371 trunk_revision = self.ReadLine()
370 self.Persist("trunk_revision", trunk_revision) 372 self.Persist("trunk_revision", trunk_revision)
371 373
372 374
373 class TagRevision(Step): 375 class TagRevision(Step):
374 MESSAGE = "Tag the new revision." 376 MESSAGE = "Tag the new revision."
375 377
376 def RunStep(self): 378 def RunStep(self):
377 self.RestoreVersionIfUnset() 379 self.RestoreVersionIfUnset()
378 ver = "%s.%s.%s" % (self._state["major"], 380 ver = "%s.%s.%s" % (self._state["major"],
379 self._state["minor"], 381 self._state["minor"],
380 self._state["build"]) 382 self._state["build"])
381 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None: 383 if self.Git("svn tag %s -m \"Tagging version %s\"" % (ver, ver)) is None:
382 self.Die("'git svn tag' failed.") 384 self.Die("'git svn tag' failed.")
383 385
384 386
385 class CheckChromium(Step): 387 class CheckChromium(Step):
386 MESSAGE = "Ask for chromium checkout." 388 MESSAGE = "Ask for chromium checkout."
387 389
388 def Run(self): 390 def Run(self):
389 chrome_path = self._options.c 391 chrome_path = self._options.c
390 if not chrome_path: 392 if not chrome_path:
391 self.DieInForcedMode("Please specify the path to a Chromium checkout in " 393 self.DieNoManualMode("Please specify the path to a Chromium checkout in "
392 "forced mode.") 394 "forced mode.")
393 print ("Do you have a \"NewGit\" Chromium checkout and want " 395 print ("Do you have a \"NewGit\" Chromium checkout and want "
394 "this script to automate creation of the roll CL? If yes, enter the " 396 "this script to automate creation of the roll CL? If yes, enter the "
395 "path to (and including) the \"src\" directory here, otherwise just " 397 "path to (and including) the \"src\" directory here, otherwise just "
396 "press <Return>: "), 398 "press <Return>: "),
397 chrome_path = self.ReadLine() 399 chrome_path = self.ReadLine()
398 self.Persist("chrome_path", chrome_path) 400 self.Persist("chrome_path", chrome_path)
399 401
400 402
401 class SwitchChromium(Step): 403 class SwitchChromium(Step):
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 451
450 self.RestoreVersionIfUnset() 452 self.RestoreVersionIfUnset()
451 ver = "%s.%s.%s" % (self._state["major"], 453 ver = "%s.%s.%s" % (self._state["major"],
452 self._state["minor"], 454 self._state["minor"],
453 self._state["build"]) 455 self._state["build"])
454 if self._options and self._options.r: 456 if self._options and self._options.r:
455 print "Using account %s for review." % self._options.r 457 print "Using account %s for review." % self._options.r
456 rev = self._options.r 458 rev = self._options.r
457 else: 459 else:
458 print "Please enter the email address of a reviewer for the roll CL: ", 460 print "Please enter the email address of a reviewer for the roll CL: ",
459 self.DieInForcedMode("A reviewer must be specified in forced mode.") 461 self.DieNoManualMode("A reviewer must be specified in forced mode.")
460 rev = self.ReadLine() 462 rev = self.ReadLine()
461 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev) 463 args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev)
462 if self.Git(args) is None: 464 if self.Git(args) is None:
463 self.Die("'git commit' failed.") 465 self.Die("'git commit' failed.")
464 force_flag = " -f" if self._options.f else "" 466 force_flag = " -f" if not self.IsManual() else ""
465 if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None: 467 if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None:
466 self.Die("'git cl upload' failed, please try again.") 468 self.Die("'git cl upload' failed, please try again.")
467 print "CL uploaded." 469 print "CL uploaded."
468 470
469 471
470 class SwitchV8(Step): 472 class SwitchV8(Step):
471 MESSAGE = "Returning to V8 checkout." 473 MESSAGE = "Returning to V8 checkout."
472 REQUIRES = "chrome_path" 474 REQUIRES = "chrome_path"
473 475
474 def RunStep(self): 476 def RunStep(self):
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 result = optparse.OptionParser() 541 result = optparse.OptionParser()
540 result.add_option("-c", "--chromium", dest="c", 542 result.add_option("-c", "--chromium", dest="c",
541 help=("Specify the path to your Chromium src/ " 543 help=("Specify the path to your Chromium src/ "
542 "directory to automate the V8 roll.")) 544 "directory to automate the V8 roll."))
543 result.add_option("-f", "--force", dest="f", 545 result.add_option("-f", "--force", dest="f",
544 help="Don't prompt the user.", 546 help="Don't prompt the user.",
545 default=False, action="store_true") 547 default=False, action="store_true")
546 result.add_option("-l", "--last-push", dest="l", 548 result.add_option("-l", "--last-push", dest="l",
547 help=("Manually specify the git commit ID " 549 help=("Manually specify the git commit ID "
548 "of the last push to trunk.")) 550 "of the last push to trunk."))
551 result.add_option("-m", "--manual", dest="m",
552 help="Prompt the user at every important step.",
553 default=False, action="store_true")
549 result.add_option("-r", "--reviewer", dest="r", 554 result.add_option("-r", "--reviewer", dest="r",
550 help=("Specify the account name to be used for reviews.")) 555 help=("Specify the account name to be used for reviews."))
551 result.add_option("-s", "--step", dest="s", 556 result.add_option("-s", "--step", dest="s",
552 help="Specify the step where to start work. Default: 0.", 557 help="Specify the step where to start work. Default: 0.",
553 default=0, type="int") 558 default=0, type="int")
554 return result 559 return result
555 560
556 561
557 def ProcessOptions(options): 562 def ProcessOptions(options):
558 if options.s < 0: 563 if options.s < 0:
559 print "Bad step number %d" % options.s 564 print "Bad step number %d" % options.s
560 return False 565 return False
561 if options.f and not options.r: 566 if not options.m and not options.r:
562 print "A reviewer (-r) is required in forced mode." 567 print "A reviewer (-r) is required in (semi-)automatic mode."
563 return False 568 return False
564 if options.f and not options.c: 569 if options.f and options.m:
565 print "A chromium checkout (-c) is required in forced mode." 570 print "Manual and forced mode cannot be combined."
571 return False
572 if not options.m and not options.c:
573 print "A chromium checkout (-c) is required in (semi-)automatic mode."
566 return False 574 return False
567 return True 575 return True
568 576
569 577
570 def Main(): 578 def Main():
571 parser = BuildOptions() 579 parser = BuildOptions()
572 (options, args) = parser.parse_args() 580 (options, args) = parser.parse_args()
573 if not ProcessOptions(options): 581 if not ProcessOptions(options):
574 parser.print_help() 582 parser.print_help()
575 return 1 583 return 1
576 RunPushToTrunk(CONFIG, options) 584 RunPushToTrunk(CONFIG, options)
577 585
578 if __name__ == "__main__": 586 if __name__ == "__main__":
579 sys.exit(Main()) 587 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