Split of rolling Chromium from push-to-trunk.
authormachenbach@chromium.org <machenbach@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 12:15:25 +0000 (12:15 +0000)
committermachenbach@chromium.org <machenbach@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 12:15:25 +0000 (12:15 +0000)
This moves rolling Chromium into a new script with its own tests.

BUG=
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/199733012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20159 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

tools/push-to-trunk/auto_roll.py
tools/push-to-trunk/chromium_roll.py [new file with mode: 0755]
tools/push-to-trunk/push_to_trunk.py
tools/push-to-trunk/test_scripts.py

index 9b28938..ebe2397 100755 (executable)
@@ -142,7 +142,6 @@ class PushToTrunk(Step):
           self._side_effect_handler.Call(
               P(push_to_trunk.CONFIG, self._side_effect_handler).Run,
               ["-a", self._options.author,
-               "-c", self._options.chromium,
                "-r", self._options.reviewer,
                "-f"])
       finally:
@@ -154,9 +153,8 @@ class PushToTrunk(Step):
 
 class AutoRoll(ScriptsBase):
   def _PrepareOptions(self, parser):
-    parser.add_argument("-c", "--chromium", required=True,
-                        help=("The path to your Chromium src/ "
-                              "directory to automate the V8 roll."))
+    parser.add_argument("-c", "--chromium",
+                        help=("Deprecated."))
     parser.add_argument("-p", "--push",
                         help="Push to trunk. Dry run if unspecified.",
                         default=False, action="store_true")
diff --git a/tools/push-to-trunk/chromium_roll.py b/tools/push-to-trunk/chromium_roll.py
new file mode 100755 (executable)
index 0000000..ef9b8bf
--- /dev/null
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import os
+import sys
+
+from common_includes import *
+
+DEPS_FILE = "DEPS_FILE"
+CHROMIUM = "CHROMIUM"
+
+CONFIG = {
+  PERSISTFILE_BASENAME: "/tmp/v8-chromium-roll-tempfile",
+  DOT_GIT_LOCATION: ".git",
+  DEPS_FILE: "DEPS",
+}
+
+
+class Preparation(Step):
+  MESSAGE = "Preparation."
+
+  def RunStep(self):
+    self.CommonPrepare()
+
+
+class DetectLastPush(Step):
+  MESSAGE = "Detect commit ID of last push to trunk."
+
+  def RunStep(self):
+    self["last_push"] = self._options.last_push or self.FindLastTrunkPush()
+    self["trunk_revision"] = self.GitSVNFindSVNRev(self["last_push"])
+    self["push_title"] = self.GitLog(n=1, format="%s",
+                                     git_hash=self["last_push"])
+
+
+class CheckChromium(Step):
+  MESSAGE = "Ask for chromium checkout."
+
+  def Run(self):
+    self["chrome_path"] = self._options.chromium
+    while not self["chrome_path"]:
+      self.DieNoManualMode("Please specify the path to a Chromium checkout in "
+                           "forced mode.")
+      print ("Please specify the path to the chromium \"src\" directory: "),
+      self["chrome_path"] = self.ReadLine()
+
+
+class SwitchChromium(Step):
+  MESSAGE = "Switch to Chromium checkout."
+  REQUIRES = "chrome_path"
+
+  def RunStep(self):
+    self["v8_path"] = os.getcwd()
+    os.chdir(self["chrome_path"])
+    self.InitialEnvironmentChecks()
+    # Check for a clean workdir.
+    if not self.GitIsWorkdirClean():  # pragma: no cover
+      self.Die("Workspace is not clean. Please commit or undo your changes.")
+    # Assert that the DEPS file is there.
+    if not os.path.exists(self.Config(DEPS_FILE)):  # pragma: no cover
+      self.Die("DEPS file not present.")
+
+
+class UpdateChromiumCheckout(Step):
+  MESSAGE = "Update the checkout and create a new branch."
+  REQUIRES = "chrome_path"
+
+  def RunStep(self):
+    os.chdir(self["chrome_path"])
+    self.GitCheckout("master")
+    self.GitPull()
+    self.GitCreateBranch("v8-roll-%s" % self["trunk_revision"])
+
+
+class UploadCL(Step):
+  MESSAGE = "Create and upload CL."
+  REQUIRES = "chrome_path"
+
+  def RunStep(self):
+    os.chdir(self["chrome_path"])
+
+    # Patch DEPS file.
+    deps = FileToText(self.Config(DEPS_FILE))
+    deps = re.sub("(?<=\"v8_revision\": \")([0-9]+)(?=\")",
+                  self["trunk_revision"],
+                  deps)
+    TextToFile(deps, self.Config(DEPS_FILE))
+
+    if self._options.reviewer:
+      print "Using account %s for review." % self._options.reviewer
+      rev = self._options.reviewer
+    else:
+      print "Please enter the email address of a reviewer for the roll CL: ",
+      self.DieNoManualMode("A reviewer must be specified in forced mode.")
+      rev = self.ReadLine()
+
+    commit_title = "Update V8 to %s." % self["push_title"].lower()
+    self.GitCommit("%s\n\nTBR=%s" % (commit_title, rev))
+    self.GitUpload(author=self._options.author,
+                   force=self._options.force_upload)
+    print "CL uploaded."
+
+
+class SwitchV8(Step):
+  MESSAGE = "Returning to V8 checkout."
+  REQUIRES = "chrome_path"
+
+  def RunStep(self):
+    os.chdir(self["v8_path"])
+
+
+class CleanUp(Step):
+  MESSAGE = "Done!"
+
+  def RunStep(self):
+    print("Congratulations, you have successfully rolled the push r%s it into "
+          "Chromium. Please don't forget to update the v8rel spreadsheet."
+          % self["trunk_revision"])
+
+    # Clean up all temporary files.
+    Command("rm", "-f %s*" % self._config[PERSISTFILE_BASENAME])
+
+
+class ChromiumRoll(ScriptsBase):
+  def _PrepareOptions(self, parser):
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument("-f", "--force",
+                      help="Don't prompt the user.",
+                      default=False, action="store_true")
+    group.add_argument("-m", "--manual",
+                      help="Prompt the user at every important step.",
+                      default=False, action="store_true")
+    parser.add_argument("-c", "--chromium",
+                        help=("The path to your Chromium src/ "
+                              "directory to automate the V8 roll."))
+    parser.add_argument("-l", "--last-push",
+                        help="The git commit ID of the last push to trunk.")
+
+  def _ProcessOptions(self, options):  # pragma: no cover
+    if not options.manual and not options.reviewer:
+      print "A reviewer (-r) is required in (semi-)automatic mode."
+      return False
+    if not options.manual and not options.chromium:
+      print "A chromium checkout (-c) is required in (semi-)automatic mode."
+      return False
+    if not options.manual and not options.author:
+      print "Specify your chromium.org email with -a in (semi-)automatic mode."
+      return False
+
+    options.tbr_commit = not options.manual
+    return True
+
+  def _Steps(self):
+    return [
+      Preparation,
+      DetectLastPush,
+      CheckChromium,
+      SwitchChromium,
+      UpdateChromiumCheckout,
+      UploadCL,
+      SwitchV8,
+      CleanUp,
+    ]
+
+
+if __name__ == "__main__":  # pragma: no cover
+  sys.exit(ChromiumRoll(CONFIG).Run())
index 6fcc901..b487b0f 100755 (executable)
@@ -34,8 +34,6 @@ import urllib2
 from common_includes import *
 
 TRUNKBRANCH = "TRUNKBRANCH"
-CHROMIUM = "CHROMIUM"
-DEPS_FILE = "DEPS_FILE"
 
 CONFIG = {
   BRANCHNAME: "prepare-push",
@@ -48,7 +46,6 @@ CONFIG = {
   CHANGELOG_ENTRY_FILE: "/tmp/v8-push-to-trunk-tempfile-changelog-entry",
   PATCH_FILE: "/tmp/v8-push-to-trunk-tempfile-patch-file",
   COMMITMSG_FILE: "/tmp/v8-push-to-trunk-tempfile-commitmsg",
-  DEPS_FILE: "DEPS",
 }
 
 PUSH_MESSAGE_SUFFIX = " (based on bleeding_edge revision r%d)"
@@ -373,100 +370,15 @@ class TagRevision(Step):
     self.GitSVNTag(self["version"])
 
 
-class CheckChromium(Step):
-  MESSAGE = "Ask for chromium checkout."
-
-  def Run(self):
-    self["chrome_path"] = self._options.chromium
-    if not self["chrome_path"]:
-      self.DieNoManualMode("Please specify the path to a Chromium checkout in "
-                          "forced mode.")
-      print ("Do you have a \"NewGit\" Chromium checkout and want "
-          "this script to automate creation of the roll CL? If yes, enter the "
-          "path to (and including) the \"src\" directory here, otherwise just "
-          "press <Return>: "),
-      self["chrome_path"] = self.ReadLine()
-
-
-class SwitchChromium(Step):
-  MESSAGE = "Switch to Chromium checkout."
-  REQUIRES = "chrome_path"
-
-  def RunStep(self):
-    self["v8_path"] = os.getcwd()
-    os.chdir(self["chrome_path"])
-    self.InitialEnvironmentChecks()
-    # Check for a clean workdir.
-    if not self.GitIsWorkdirClean():  # pragma: no cover
-      self.Die("Workspace is not clean. Please commit or undo your changes.")
-    # Assert that the DEPS file is there.
-    if not os.path.exists(self.Config(DEPS_FILE)):  # pragma: no cover
-      self.Die("DEPS file not present.")
-
-
-class UpdateChromiumCheckout(Step):
-  MESSAGE = "Update the checkout and create a new branch."
-  REQUIRES = "chrome_path"
-
-  def RunStep(self):
-    os.chdir(self["chrome_path"])
-    self.GitCheckout("master")
-    self.GitPull()
-    self.GitCreateBranch("v8-roll-%s" % self["trunk_revision"])
-
-
-class UploadCL(Step):
-  MESSAGE = "Create and upload CL."
-  REQUIRES = "chrome_path"
-
-  def RunStep(self):
-    os.chdir(self["chrome_path"])
-
-    # Patch DEPS file.
-    deps = FileToText(self.Config(DEPS_FILE))
-    deps = re.sub("(?<=\"v8_revision\": \")([0-9]+)(?=\")",
-                  self["trunk_revision"],
-                  deps)
-    TextToFile(deps, self.Config(DEPS_FILE))
-
-    if self._options.reviewer:
-      print "Using account %s for review." % self._options.reviewer
-      rev = self._options.reviewer
-    else:
-      print "Please enter the email address of a reviewer for the roll CL: ",
-      self.DieNoManualMode("A reviewer must be specified in forced mode.")
-      rev = self.ReadLine()
-    suffix = PUSH_MESSAGE_SUFFIX % int(self["svn_revision"])
-    self.GitCommit("Update V8 to version %s%s.\n\nTBR=%s"
-                   % (self["version"], suffix, rev))
-    self.GitUpload(author=self._options.author,
-                   force=self._options.force_upload)
-    print "CL uploaded."
-
-
-class SwitchV8(Step):
-  MESSAGE = "Returning to V8 checkout."
-  REQUIRES = "chrome_path"
-
-  def RunStep(self):
-    os.chdir(self["v8_path"])
-
-
 class CleanUp(Step):
   MESSAGE = "Done!"
 
   def RunStep(self):
-    if self["chrome_path"]:
-      print("Congratulations, you have successfully created the trunk "
-            "revision %s and rolled it into Chromium. Please don't forget to "
-            "update the v8rel spreadsheet:" % self["version"])
-    else:  # pragma: no cover
-      print("Congratulations, you have successfully created the trunk "
-            "revision %s. Please don't forget to roll this new version into "
-            "Chromium, and to update the v8rel spreadsheet:"
-            % self["version"])
-    print "%s\ttrunk\t%s" % (self["version"],
-                             self["trunk_revision"])
+    print("Congratulations, you have successfully created the trunk "
+          "revision %s. Please don't forget to roll this new version into "
+          "Chromium, and to update the v8rel spreadsheet:"
+          % self["version"])
+    print "%s\ttrunk\t%s" % (self["version"], self["trunk_revision"])
 
     self.CommonCleanup()
     if self.Config(TRUNKBRANCH) != self["current_branch"]:
@@ -486,9 +398,6 @@ class PushToTrunk(ScriptsBase):
                         help=("The git commit ID of the last bleeding edge "
                               "revision that was pushed to trunk. This is "
                               "used for the auto-generated ChangeLog entry."))
-    parser.add_argument("-c", "--chromium",
-                        help=("The path to your Chromium src/ "
-                              "directory to automate the V8 roll."))
     parser.add_argument("-l", "--last-push",
                         help="The git commit ID of the last push to trunk.")
     parser.add_argument("-R", "--revision",
@@ -498,9 +407,6 @@ class PushToTrunk(ScriptsBase):
     if not options.manual and not options.reviewer:
       print "A reviewer (-r) is required in (semi-)automatic mode."
       return False
-    if not options.manual and not options.chromium:
-      print "A chromium checkout (-c) is required in (semi-)automatic mode."
-      return False
     if not options.manual and not options.author:
       print "Specify your chromium.org email with -a in (semi-)automatic mode."
       return False
@@ -531,11 +437,6 @@ class PushToTrunk(ScriptsBase):
       SanityCheck,
       CommitSVN,
       TagRevision,
-      CheckChromium,
-      SwitchChromium,
-      UpdateChromiumCheckout,
-      UploadCL,
-      SwitchV8,
       CleanUp,
     ]
 
index 34627d9..957ea63 100644 (file)
@@ -41,6 +41,10 @@ import merge_to_branch
 from merge_to_branch import *
 import push_to_trunk
 from push_to_trunk import *
+import chromium_roll
+from chromium_roll import CHROMIUM
+from chromium_roll import DEPS_FILE
+from chromium_roll import ChromiumRoll
 
 
 TEST_CONFIG = {
@@ -638,12 +642,8 @@ Performance and stability improvements on all platforms."""
 
     TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
     TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile()
-    if not os.path.exists(TEST_CONFIG[CHROMIUM]):
-      os.makedirs(TEST_CONFIG[CHROMIUM])
     bleeding_edge_change_log = "2014-03-17: Sentinel\n"
     TextToFile(bleeding_edge_change_log, TEST_CONFIG[CHANGELOG_FILE])
-    TextToFile("Some line\n   \"v8_revision\": \"123444\",\n  some line",
-                 TEST_CONFIG[DEPS_FILE])
     os.environ["EDITOR"] = "vi"
 
     def ResetChangeLog():
@@ -689,7 +689,6 @@ Performance and stability improvements on all platforms.""", commit)
           change_log)
 
     force_flag = " -f" if not manual else ""
-    review_suffix = "\n\nTBR=reviewer@chromium.org" if not manual else ""
     self.ExpectGit([
       Git("status -s -uno", ""),
       Git("status -s -b -uno", "## some_branch\n"),
@@ -728,16 +727,6 @@ Performance and stability improvements on all platforms.""", commit)
           cb=CheckSVNCommit),
       Git("svn dcommit 2>&1", "Some output\nCommitted r123456\nSome output\n"),
       Git("svn tag 3.22.5 -m \"Tagging version 3.22.5\"", ""),
-      Git("status -s -uno", ""),
-      Git("checkout -f master", ""),
-      Git("pull", ""),
-      Git("checkout -b v8-roll-123456", ""),
-      Git(("commit -am \"Update V8 to version 3.22.5 "
-           "(based on bleeding_edge revision r123455).\n\n"
-           "TBR=reviewer@chromium.org\""),
-          ""),
-      Git(("cl upload --send-mail --email \"author@chromium.org\"%s"
-           % force_flag), ""),
       Git("checkout -f some_branch", ""),
       Git("branch -D %s" % TEST_CONFIG[TEMP_BRANCH], ""),
       Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
@@ -751,23 +740,18 @@ Performance and stability improvements on all platforms.""", commit)
         RL(""),  # Open editor.
         RL("Y"),  # Increment build number.
         RL("Y"),  # Sanity check.
-        RL("reviewer@chromium.org"),  # Chromium reviewer.
       ])
 
     # Expected keyboard input in semi-automatic mode and forced mode:
     if not manual:
       self.ExpectReadline([])
 
-    args = ["-a", "author@chromium.org", "-c", TEST_CONFIG[CHROMIUM],
-            "--revision", "123455"]
+    args = ["-a", "author@chromium.org", "--revision", "123455"]
     if force: args.append("-f")
     if manual: args.append("-m")
     else: args += ["-r", "reviewer@chromium.org"]
     PushToTrunk(TEST_CONFIG, self).Run(args)
 
-    deps = FileToText(TEST_CONFIG[DEPS_FILE])
-    self.assertTrue(re.search("\"v8_revision\": \"123456\"", deps))
-
     cl = FileToText(TEST_CONFIG[CHANGELOG_FILE])
     self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
     self.assertTrue(re.search(r"        Log text 1 \(issue 321\).", cl))
@@ -786,6 +770,66 @@ Performance and stability improvements on all platforms.""", commit)
   def testPushToTrunkForced(self):
     self._PushToTrunk(force=True)
 
+
+  def _ChromiumRoll(self, force=False, manual=False):
+    TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
+    if not os.path.exists(TEST_CONFIG[CHROMIUM]):
+      os.makedirs(TEST_CONFIG[CHROMIUM])
+    TextToFile("Some line\n   \"v8_revision\": \"123444\",\n  some line",
+               TEST_CONFIG[DEPS_FILE])
+
+    os.environ["EDITOR"] = "vi"
+    force_flag = " -f" if not manual else ""
+    self.ExpectGit([
+      Git("status -s -uno", ""),
+      Git("status -s -b -uno", "## some_branch\n"),
+      Git("svn fetch", ""),
+      Git(("log -1 --format=%H --grep="
+           "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
+           "svn/trunk"), "push_hash\n"),
+      Git("svn find-rev push_hash", "123455\n"),
+      Git("log -1 --format=%s push_hash",
+          "Version 3.22.5 (based on bleeding_edge revision r123454)\n"),
+      Git("status -s -uno", ""),
+      Git("checkout -f master", ""),
+      Git("pull", ""),
+      Git("checkout -b v8-roll-123455", ""),
+      Git(("commit -am \"Update V8 to version 3.22.5 "
+           "(based on bleeding_edge revision r123454).\n\n"
+           "TBR=reviewer@chromium.org\""),
+          ""),
+      Git(("cl upload --send-mail --email \"author@chromium.org\"%s"
+           % force_flag), ""),
+    ])
+
+    # Expected keyboard input in manual mode:
+    if manual:
+      self.ExpectReadline([
+        RL("reviewer@chromium.org"),  # Chromium reviewer.
+      ])
+
+    # Expected keyboard input in semi-automatic mode and forced mode:
+    if not manual:
+      self.ExpectReadline([])
+
+    args = ["-a", "author@chromium.org", "-c", TEST_CONFIG[CHROMIUM]]
+    if force: args.append("-f")
+    if manual: args.append("-m")
+    else: args += ["-r", "reviewer@chromium.org"]
+    ChromiumRoll(TEST_CONFIG, self).Run(args)
+
+    deps = FileToText(TEST_CONFIG[DEPS_FILE])
+    self.assertTrue(re.search("\"v8_revision\": \"123455\"", deps))
+
+  def testChromiumRollManual(self):
+    self._ChromiumRoll(manual=True)
+
+  def testChromiumRollSemiAutomatic(self):
+    self._ChromiumRoll()
+
+  def testChromiumRollForced(self):
+    self._ChromiumRoll(force=True)
+
   def testCheckLastPushRecently(self):
     self.ExpectGit([
       Git("svn log -1 --oneline", "r101 | Text"),