Add forced mode to push-to-trunk script.

This CL depends on https://codereview.chromium.org/65933003/.

BUG=
R=jkummerow@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17893 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6fcd94cc
...@@ -166,6 +166,7 @@ class Step(object): ...@@ -166,6 +166,7 @@ class Step(object):
def __init__(self, text="", requires=None): def __init__(self, text="", requires=None):
self._text = text self._text = text
self._number = -1 self._number = -1
self._options = None
self._requires = requires self._requires = requires
self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER
...@@ -202,8 +203,13 @@ class Step(object): ...@@ -202,8 +203,13 @@ class Step(object):
def RunStep(self): def RunStep(self):
raise NotImplementedError raise NotImplementedError
def ReadLine(self): def ReadLine(self, default=None):
return self._side_effect_handler.ReadLine() # Don't prompt in forced mode.
if self._options and self._options.f and default is not None:
print "%s (forced)" % default
return default
else:
return self._side_effect_handler.ReadLine()
def Git(self, args="", prefix="", pipe=True): def Git(self, args="", prefix="", pipe=True):
return self._side_effect_handler.Command("git", args, prefix, pipe) return self._side_effect_handler.Command("git", args, prefix, pipe)
...@@ -218,9 +224,14 @@ class Step(object): ...@@ -218,9 +224,14 @@ class Step(object):
print "Exiting" print "Exiting"
raise Exception(msg) raise Exception(msg)
def DieInForcedMode(self, msg=""):
if self._options and self._options.f:
msg = msg or "Not implemented in forced mode."
self.Die(msg)
def Confirm(self, msg): def Confirm(self, msg):
print "%s [Y/n] " % msg, print "%s [Y/n] " % msg,
answer = self.ReadLine() answer = self.ReadLine(default="Y")
return answer == "" or answer == "Y" or answer == "y" return answer == "" or answer == "Y" or answer == "y"
def DeleteBranch(self, name): def DeleteBranch(self, name):
...@@ -254,6 +265,8 @@ class Step(object): ...@@ -254,6 +265,8 @@ class Step(object):
if not os.path.exists(self._config[DOT_GIT_LOCATION]): if not os.path.exists(self._config[DOT_GIT_LOCATION]):
self.Die("This is not a git checkout, this script won't work for you.") self.Die("This is not a git checkout, this script won't work for you.")
# TODO(machenbach): Don't use EDITOR in forced mode as soon as script is
# well tested.
# Cancel if EDITOR is unset or not executable. # Cancel if EDITOR is unset or not executable.
if (not os.environ.get("EDITOR") or if (not os.environ.get("EDITOR") or
Command("which", os.environ["EDITOR"]) is None): Command("which", os.environ["EDITOR"]) is None):
...@@ -325,6 +338,8 @@ class Step(object): ...@@ -325,6 +338,8 @@ class Step(object):
answer = "" answer = ""
while answer != "LGTM": while answer != "LGTM":
print "> ", print "> ",
# TODO(machenbach): Add default="LGTM" to avoid prompt when script is
# well tested and when prepare push cl has TBR flag.
answer = self.ReadLine() answer = self.ReadLine()
if answer != "LGTM": if answer != "LGTM":
print "That was not 'LGTM'." print "That was not 'LGTM'."
...@@ -333,6 +348,7 @@ class Step(object): ...@@ -333,6 +348,7 @@ class Step(object):
print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", " print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", "
"or resolve the conflicts, stage *all* touched files with " "or resolve the conflicts, stage *all* touched files with "
"'git add', and type \"RESOLVED<Return>\"") "'git add', and type \"RESOLVED<Return>\"")
self.DieInForcedMode()
answer = "" answer = ""
while answer != "RESOLVED": while answer != "RESOLVED":
if answer == "ABORT": if answer == "ABORT":
...@@ -354,8 +370,13 @@ class UploadStep(Step): ...@@ -354,8 +370,13 @@ class UploadStep(Step):
Step.__init__(self, "Upload for code review.") Step.__init__(self, "Upload for code review.")
def RunStep(self): def RunStep(self):
print "Please enter the email address of a V8 reviewer for your patch: ", if self._options and self._options.r:
reviewer = self.ReadLine() print "Using account %s for review." % self._options.r
reviewer = self._options.r
else:
print "Please enter the email address of a V8 reviewer for your patch: ",
self.DieInForcedMode("A reviewer must be specified in forced mode.")
reviewer = self.ReadLine()
args = "cl upload -r \"%s\" --send-mail" % reviewer args = "cl upload -r \"%s\" --send-mail" % reviewer
if self.Git(args,pipe=False) is None: if self.Git(args,pipe=False) is None:
self.Die("'git cl upload' failed, please try again.") self.Die("'git cl upload' failed, please try again.")
......
...@@ -135,8 +135,10 @@ class EditChangeLog(Step): ...@@ -135,8 +135,10 @@ class EditChangeLog(Step):
print ("Please press <Return> to have your EDITOR open the ChangeLog " print ("Please press <Return> to have your EDITOR open the ChangeLog "
"entry, then edit its contents to your liking. When you're done, " "entry, then edit its contents to your liking. When you're done, "
"save the file and exit your EDITOR. ") "save the file and exit your EDITOR. ")
self.ReadLine() self.ReadLine(default="")
# TODO(machenbach): Don't use EDITOR in forced mode as soon as script is
# well tested.
self.Editor(self.Config(CHANGELOG_ENTRY_FILE)) self.Editor(self.Config(CHANGELOG_ENTRY_FILE))
handle, new_changelog = tempfile.mkstemp() handle, new_changelog = tempfile.mkstemp()
os.close(handle) os.close(handle)
...@@ -354,6 +356,7 @@ class CommitSVN(Step): ...@@ -354,6 +356,7 @@ class CommitSVN(Step):
print("Sorry, grepping for the SVN revision failed. Please look for it " print("Sorry, grepping for the SVN revision failed. Please look for it "
"in the last command's output above and provide it manually (just " "in the last command's output above and provide it manually (just "
"the number, without the leading \"r\").") "the number, without the leading \"r\").")
self.DieInForcedMode("Can't prompt in forced mode.")
while not trunk_revision: while not trunk_revision:
print "> ", print "> ",
trunk_revision = self.ReadLine() trunk_revision = self.ReadLine()
...@@ -380,6 +383,8 @@ class CheckChromium(Step): ...@@ -380,6 +383,8 @@ class CheckChromium(Step):
def Run(self): def Run(self):
chrome_path = self._options.c chrome_path = self._options.c
if not chrome_path: if not chrome_path:
self.DieInForcedMode("Please specify the path to a Chromium checkout in "
"forced mode.")
print ("Do you have a \"NewGit\" Chromium checkout and want " print ("Do you have a \"NewGit\" Chromium checkout and want "
"this script to automate creation of the roll CL? If yes, enter the " "this script to automate creation of the roll CL? If yes, enter the "
"path to (and including) the \"src\" directory here, otherwise just " "path to (and including) the \"src\" directory here, otherwise just "
...@@ -442,8 +447,13 @@ class UploadCL(Step): ...@@ -442,8 +447,13 @@ class UploadCL(Step):
ver = "%s.%s.%s" % (self._state["major"], ver = "%s.%s.%s" % (self._state["major"],
self._state["minor"], self._state["minor"],
self._state["build"]) self._state["build"])
print "Please enter the email address of a reviewer for the roll CL: ", if self._options and self._options.r:
rev = self.ReadLine() print "Using account %s for review." % self._options.r
rev = self._options.r
else:
print "Please enter the email address of a reviewer for the roll CL: ",
self.DieInForcedMode("A reviewer must be specified in forced mode.")
rev = self.ReadLine()
args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev) args = "commit -am \"Update V8 to version %s.\n\nTBR=%s\"" % (ver, rev)
if self.Git(args) is None: if self.Git(args) is None:
self.Die("'git commit' failed.") self.Die("'git commit' failed.")
...@@ -523,15 +533,20 @@ def RunPushToTrunk(config, ...@@ -523,15 +533,20 @@ def RunPushToTrunk(config,
def BuildOptions(): def BuildOptions():
result = optparse.OptionParser() result = optparse.OptionParser()
result.add_option("-s", "--step", dest="s",
help="Specify the step where to start work. Default: 0.",
default=0, type="int")
result.add_option("-l", "--last-push", dest="l",
help=("Manually specify the git commit ID "
"of the last push to trunk."))
result.add_option("-c", "--chromium", dest="c", result.add_option("-c", "--chromium", dest="c",
help=("Specify the path to your Chromium src/ " help=("Specify the path to your Chromium src/ "
"directory to automate the V8 roll.")) "directory to automate the V8 roll."))
result.add_option("-f", "--force", dest="f",
help="Don't prompt the user.",
default=False, action="store_true")
result.add_option("-l", "--last-push", dest="l",
help=("Manually specify the git commit ID "
"of the last push to trunk."))
result.add_option("-r", "--reviewer", dest="r",
help=("Specify the account name to be used for reviews."))
result.add_option("-s", "--step", dest="s",
help="Specify the step where to start work. Default: 0.",
default=0, type="int")
return result return result
......
...@@ -430,7 +430,7 @@ class ScriptTest(unittest.TestCase): ...@@ -430,7 +430,7 @@ class ScriptTest(unittest.TestCase):
patch = FileToText(TEST_CONFIG[ PATCH_FILE]) patch = FileToText(TEST_CONFIG[ PATCH_FILE])
self.assertTrue(re.search(r"patch content", patch)) self.assertTrue(re.search(r"patch content", patch))
def testPushToTrunk(self): def _PushToTrunk(self, force=False):
TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile() TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile() TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile()
TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile() TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
...@@ -518,6 +518,12 @@ class ScriptTest(unittest.TestCase): ...@@ -518,6 +518,12 @@ class ScriptTest(unittest.TestCase):
"Y", # Sanity check. "Y", # Sanity check.
"reviewer@chromium.org", # Chromium reviewer. "reviewer@chromium.org", # Chromium reviewer.
] ]
if force:
# TODO(machenbach): The lgtm for the prepare push is just temporary.
# There should be no user input in "force" mode.
self._rl_recipe = [
"LGTM", # Enter LGTM for V8 CL.
]
class Options( object ): class Options( object ):
pass pass
...@@ -525,6 +531,8 @@ class ScriptTest(unittest.TestCase): ...@@ -525,6 +531,8 @@ class ScriptTest(unittest.TestCase):
options = Options() options = Options()
options.s = 0 options.s = 0
options.l = None options.l = None
options.f = force
options.r = "reviewer@chromium.org" if force else None
options.c = TEST_CONFIG[CHROMIUM] options.c = TEST_CONFIG[CHROMIUM]
RunPushToTrunk(TEST_CONFIG, options, self) RunPushToTrunk(TEST_CONFIG, options, self)
...@@ -540,3 +548,9 @@ class ScriptTest(unittest.TestCase): ...@@ -540,3 +548,9 @@ class ScriptTest(unittest.TestCase):
# Note: The version file is on build number 5 again in the end of this test # Note: The version file is on build number 5 again in the end of this test
# since the git command that merges to the bleeding edge branch is mocked # since the git command that merges to the bleeding edge branch is mocked
# out. # out.
def testPushToTrunk(self):
self._PushToTrunk()
def testPushToTrunkForced(self):
self._PushToTrunk(force=True)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment