1#!/usr/bin/env python 2# Copyright 2014 the V8 project authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import argparse 7import os 8import sys 9 10from common_includes import * 11 12 13class Preparation(Step): 14 MESSAGE = "Preparation." 15 16 def RunStep(self): 17 # Update v8 remote tracking branches. 18 self.GitFetchOrigin() 19 20 21class DetectLastPush(Step): 22 MESSAGE = "Detect commit ID of last push to trunk." 23 24 def RunStep(self): 25 self["last_push"] = self._options.last_push or self.FindLastTrunkPush( 26 branch="origin/master", include_patches=True) 27 self["trunk_revision"] = self.GetCommitPositionNumber(self["last_push"]) 28 self["push_title"] = self.GitLog(n=1, format="%s", 29 git_hash=self["last_push"]) 30 31 32class SwitchChromium(Step): 33 MESSAGE = "Switch to Chromium checkout." 34 35 def RunStep(self): 36 self["v8_path"] = os.getcwd() 37 cwd = self._options.chromium 38 os.chdir(cwd) 39 self.InitialEnvironmentChecks(cwd) 40 # Check for a clean workdir. 41 if not self.GitIsWorkdirClean(cwd=cwd): # pragma: no cover 42 self.Die("Workspace is not clean. Please commit or undo your changes.") 43 # Assert that the DEPS file is there. 44 if not os.path.exists(os.path.join(cwd, "DEPS")): # pragma: no cover 45 self.Die("DEPS file not present.") 46 47 48class UpdateChromiumCheckout(Step): 49 MESSAGE = "Update the checkout and create a new branch." 50 51 def RunStep(self): 52 self.GitCheckout("master", cwd=self._options.chromium) 53 self.Command("gclient", "sync --nohooks", cwd=self._options.chromium) 54 self.GitPull(cwd=self._options.chromium) 55 56 # Update v8 remotes. 57 self.GitFetchOrigin() 58 59 self.GitCreateBranch("v8-roll-%s" % self["trunk_revision"], 60 cwd=self._options.chromium) 61 62 63class UploadCL(Step): 64 MESSAGE = "Create and upload CL." 65 66 def RunStep(self): 67 # Patch DEPS file. 68 if self.Command( 69 "roll-dep", "v8 %s" % self["trunk_revision"], 70 cwd=self._options.chromium) is None: 71 self.Die("Failed to create deps for %s" % self["trunk_revision"]) 72 73 commit_title = "Update V8 to %s." % self["push_title"].lower() 74 sheriff = "" 75 if self["sheriff"]: 76 sheriff = ("\n\nPlease reply to the V8 sheriff %s in case of problems." 77 % self["sheriff"]) 78 self.GitCommit("%s%s\n\nTBR=%s" % 79 (commit_title, sheriff, self._options.reviewer), 80 author=self._options.author, 81 cwd=self._options.chromium) 82 if not self._options.dry_run: 83 self.GitUpload(author=self._options.author, 84 force=True, 85 cq=self._options.use_commit_queue, 86 cwd=self._options.chromium) 87 print "CL uploaded." 88 else: 89 self.GitCheckout("master", cwd=self._options.chromium) 90 self.GitDeleteBranch("v8-roll-%s" % self["trunk_revision"], 91 cwd=self._options.chromium) 92 print "Dry run - don't upload." 93 94 95# TODO(machenbach): Make this obsolete. We are only in the chromium chechout 96# for the initial .git check. 97class SwitchV8(Step): 98 MESSAGE = "Returning to V8 checkout." 99 100 def RunStep(self): 101 os.chdir(self["v8_path"]) 102 103 104class CleanUp(Step): 105 MESSAGE = "Done!" 106 107 def RunStep(self): 108 print("Congratulations, you have successfully rolled the push r%s it into " 109 "Chromium. Please don't forget to update the v8rel spreadsheet." 110 % self["trunk_revision"]) 111 112 # Clean up all temporary files. 113 Command("rm", "-f %s*" % self._config["PERSISTFILE_BASENAME"]) 114 115 116class ChromiumRoll(ScriptsBase): 117 def _PrepareOptions(self, parser): 118 parser.add_argument("-c", "--chromium", required=True, 119 help=("The path to your Chromium src/ " 120 "directory to automate the V8 roll.")) 121 parser.add_argument("-l", "--last-push", 122 help="The git commit ID of the last push to trunk.") 123 parser.add_argument("--use-commit-queue", 124 help="Check the CQ bit on upload.", 125 default=False, action="store_true") 126 127 def _ProcessOptions(self, options): # pragma: no cover 128 if not options.author or not options.reviewer: 129 print "A reviewer (-r) and an author (-a) are required." 130 return False 131 132 options.requires_editor = False 133 options.force = True 134 options.manual = False 135 return True 136 137 def _Config(self): 138 return { 139 "PERSISTFILE_BASENAME": "/tmp/v8-chromium-roll-tempfile", 140 } 141 142 def _Steps(self): 143 return [ 144 Preparation, 145 DetectLastPush, 146 DetermineV8Sheriff, 147 SwitchChromium, 148 UpdateChromiumCheckout, 149 UploadCL, 150 SwitchV8, 151 CleanUp, 152 ] 153 154 155if __name__ == "__main__": # pragma: no cover 156 sys.exit(ChromiumRoll().Run()) 157