Add named options to push-to-trunk script.

Also make sure that on exceptions from the test infrastructure there is no retry.

BUG=
R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18313 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7e75d197
...@@ -38,6 +38,12 @@ CONFIG = { ...@@ -38,6 +38,12 @@ CONFIG = {
} }
class AutoRollOptions(CommonOptions):
def __init__(self, options):
super(AutoRollOptions, self).__init__(options)
self.requires_editor = False
class Preparation(Step): class Preparation(Step):
MESSAGE = "Preparation." MESSAGE = "Preparation."
...@@ -137,7 +143,7 @@ def Main(): ...@@ -137,7 +143,7 @@ def Main():
print "You need to specify the chromium src location and a reviewer." print "You need to specify the chromium src location and a reviewer."
parser.print_help() parser.print_help()
return 1 return 1
RunAutoRoll(CONFIG, options) RunAutoRoll(CONFIG, AutoRollOptions(options))
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(Main()) sys.exit(Main())
...@@ -212,6 +212,19 @@ class SideEffectHandler(object): ...@@ -212,6 +212,19 @@ class SideEffectHandler(object):
DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
class NoRetryException(Exception):
pass
class CommonOptions(object):
def __init__(self, options, manual=True):
self.requires_editor = True
self.wait_for_lgtm = True
self.s = options.s
self.force_readline_defaults = not manual
self.force_upload = not manual
self.manual = manual
class Step(object): class Step(object):
def __init__(self, text, requires, number, config, state, options, handler): def __init__(self, text, requires, number, config, state, options, handler):
self._text = text self._text = text
...@@ -225,16 +238,11 @@ class Step(object): ...@@ -225,16 +238,11 @@ class Step(object):
assert self._config is not None assert self._config is not None
assert self._state is not None assert self._state is not None
assert self._side_effect_handler is not None assert self._side_effect_handler is not None
assert isinstance(options, CommonOptions)
def Config(self, key): def Config(self, key):
return self._config[key] return self._config[key]
def IsForced(self):
return self._options and self._options.f
def IsManual(self):
return self._options and self._options.m
def Run(self): def Run(self):
if self._requires: if self._requires:
self.RestoreIfUnset(self._requires) self.RestoreIfUnset(self._requires)
...@@ -263,6 +271,8 @@ class Step(object): ...@@ -263,6 +271,8 @@ class Step(object):
got_exception = False got_exception = False
try: try:
result = cb() result = cb()
except NoRetryException, e:
raise e
except Exception: except Exception:
got_exception = True got_exception = True
if got_exception or retry_on(result): if got_exception or retry_on(result):
...@@ -277,7 +287,7 @@ class Step(object): ...@@ -277,7 +287,7 @@ class Step(object):
def ReadLine(self, default=None): def ReadLine(self, default=None):
# Don't prompt in forced mode. # Don't prompt in forced mode.
if not self.IsManual() and default is not None: if self._options.force_readline_defaults and default is not None:
print "%s (forced)" % default print "%s (forced)" % default
return default return default
else: else:
...@@ -288,7 +298,7 @@ class Step(object): ...@@ -288,7 +298,7 @@ class Step(object):
return self.Retry(cmd, retry_on, [5, 30]) return self.Retry(cmd, retry_on, [5, 30])
def Editor(self, args): def Editor(self, args):
if not self.IsForced(): if self._options.requires_editor:
return self._side_effect_handler.Command(os.environ["EDITOR"], args, return self._side_effect_handler.Command(os.environ["EDITOR"], args,
pipe=False) pipe=False)
...@@ -307,7 +317,7 @@ class Step(object): ...@@ -307,7 +317,7 @@ class Step(object):
raise Exception(msg) raise Exception(msg)
def DieNoManualMode(self, msg=""): def DieNoManualMode(self, msg=""):
if not self.IsManual(): if not self._options.manual:
msg = msg or "Only available in manual mode." msg = msg or "Only available in manual mode."
self.Die(msg) self.Die(msg)
...@@ -348,7 +358,7 @@ class Step(object): ...@@ -348,7 +358,7 @@ class Step(object):
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.")
# Cancel if EDITOR is unset or not executable. # Cancel if EDITOR is unset or not executable.
if (not self.IsForced() and (not os.environ.get("EDITOR") or if (self._options.requires_editor and (not os.environ.get("EDITOR") or
Command("which", os.environ["EDITOR"]) is None)): Command("which", os.environ["EDITOR"]) is None)):
self.Die("Please set your EDITOR environment variable, you'll need it.") self.Die("Please set your EDITOR environment variable, you'll need it.")
...@@ -418,7 +428,7 @@ class Step(object): ...@@ -418,7 +428,7 @@ class Step(object):
answer = "" answer = ""
while answer != "LGTM": while answer != "LGTM":
print "> ", print "> ",
answer = self.ReadLine("LGTM" if self.IsForced() else None) answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM")
if answer != "LGTM": if answer != "LGTM":
print "That was not 'LGTM'." print "That was not 'LGTM'."
...@@ -454,7 +464,7 @@ class UploadStep(Step): ...@@ -454,7 +464,7 @@ class UploadStep(Step):
print "Please enter the email address of a V8 reviewer for your patch: ", print "Please enter the email address of a V8 reviewer for your patch: ",
self.DieNoManualMode("A reviewer must be specified in forced mode.") self.DieNoManualMode("A reviewer must be specified in forced mode.")
reviewer = self.ReadLine() reviewer = self.ReadLine()
force_flag = " -f" if not self.IsManual() else "" force_flag = " -f" if self._options.force_upload else ""
args = "cl upload -r \"%s\" --send-mail%s" % (reviewer, force_flag) args = "cl upload -r \"%s\" --send-mail%s" % (reviewer, force_flag)
# TODO(machenbach): Check output in forced mode. Verify that all required # TODO(machenbach): Check output in forced mode. Verify that all required
# base files were uploaded, if not retry. # base files were uploaded, if not retry.
......
...@@ -52,6 +52,16 @@ CONFIG = { ...@@ -52,6 +52,16 @@ CONFIG = {
} }
class PushToTrunkOptions(CommonOptions):
def __init__(self, options):
super(PushToTrunkOptions, self).__init__(options, options.m)
self.requires_editor = not options.f
self.wait_for_lgtm = not options.f
self.tbr_commit = not options.m
self.l = options.l
self.r = options.r
self.c = options.c
class Preparation(Step): class Preparation(Step):
MESSAGE = "Preparation." MESSAGE = "Preparation."
...@@ -214,7 +224,7 @@ class CommitLocal(Step): ...@@ -214,7 +224,7 @@ class CommitLocal(Step):
# Include optional TBR only in the git command. The persisted commit # Include optional TBR only in the git command. The persisted commit
# message is used for finding the commit again later. # message is used for finding the commit again later.
review = "\n\nTBR=%s" % self._options.r if not self.IsManual() else "" review = "\n\nTBR=%s" % self._options.r if self._options.tbr_commit else ""
if self.Git("commit -a -m \"%s%s\"" % (prep_commit_msg, review)) is None: if self.Git("commit -a -m \"%s%s\"" % (prep_commit_msg, review)) is None:
self.Die("'git commit -a' failed.") self.Die("'git commit -a' failed.")
...@@ -441,7 +451,7 @@ class UploadCL(Step): ...@@ -441,7 +451,7 @@ 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"])
if self._options and self._options.r: if self._options.r:
print "Using account %s for review." % self._options.r print "Using account %s for review." % self._options.r
rev = self._options.r rev = self._options.r
else: else:
...@@ -451,7 +461,7 @@ class UploadCL(Step): ...@@ -451,7 +461,7 @@ class UploadCL(Step):
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.")
force_flag = " -f" if not self.IsManual() else "" force_flag = " -f" if self._options.force_upload else ""
if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None: if self.Git("cl upload --send-mail%s" % force_flag, pipe=False) is None:
self.Die("'git cl upload' failed, please try again.") self.Die("'git cl upload' failed, please try again.")
print "CL uploaded." print "CL uploaded."
...@@ -569,7 +579,7 @@ def Main(): ...@@ -569,7 +579,7 @@ def Main():
if not ProcessOptions(options): if not ProcessOptions(options):
parser.print_help() parser.print_help()
return 1 return 1
RunPushToTrunk(CONFIG, options) RunPushToTrunk(CONFIG, PushToTrunkOptions(options))
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(Main()) sys.exit(Main())
...@@ -35,8 +35,9 @@ from common_includes import * ...@@ -35,8 +35,9 @@ from common_includes import *
import push_to_trunk import push_to_trunk
from push_to_trunk import * from push_to_trunk import *
import auto_roll import auto_roll
from auto_roll import FetchLatestRevision from auto_roll import AutoRollOptions
from auto_roll import CheckLastPush from auto_roll import CheckLastPush
from auto_roll import FetchLatestRevision
TEST_CONFIG = { TEST_CONFIG = {
...@@ -230,14 +231,14 @@ class SimpleMock(object): ...@@ -230,14 +231,14 @@ class SimpleMock(object):
# The number of arguments in the expectation must match the actual # The number of arguments in the expectation must match the actual
# arguments. # arguments.
if len(args) > len(expected_call): if len(args) > len(expected_call):
raise Exception("When calling %s with arguments, the expectations " raise NoRetryException("When calling %s with arguments, the "
"must consist of at least as many arguments.") "expectations must consist of at least as many arguments.")
# Compare expected and actual arguments. # Compare expected and actual arguments.
for (expected_arg, actual_arg) in zip(expected_call, args): for (expected_arg, actual_arg) in zip(expected_call, args):
if expected_arg != actual_arg: if expected_arg != actual_arg:
raise Exception("Expected: %s - Actual: %s" raise NoRetryException("Expected: %s - Actual: %s"
% (expected_arg, actual_arg)) % (expected_arg, actual_arg))
# The expectation list contains a mandatory return value and an optional # The expectation list contains a mandatory return value and an optional
# callback for checking the context at the time of the call. # callback for checking the context at the time of the call.
...@@ -252,8 +253,8 @@ class SimpleMock(object): ...@@ -252,8 +253,8 @@ class SimpleMock(object):
def AssertFinished(self): def AssertFinished(self):
if self._index < len(self._recipe) -1: if self._index < len(self._recipe) -1:
raise Exception("Called %s too seldom: %d vs. %d" raise NoRetryException("Called %s too seldom: %d vs. %d"
% (self._name, self._index, len(self._recipe))) % (self._name, self._index, len(self._recipe)))
class ScriptTest(unittest.TestCase): class ScriptTest(unittest.TestCase):
...@@ -278,7 +279,7 @@ class ScriptTest(unittest.TestCase): ...@@ -278,7 +279,7 @@ class ScriptTest(unittest.TestCase):
def MakeStep(self, step_class=Step, state=None, options=None): def MakeStep(self, step_class=Step, state=None, options=None):
"""Convenience wrapper.""" """Convenience wrapper."""
options = options or MakeOptions() options = options or CommonOptions(MakeOptions())
return MakeStep(step_class=step_class, number=0, state=state, return MakeStep(step_class=step_class, number=0, state=state,
config=TEST_CONFIG, options=options, config=TEST_CONFIG, options=options,
side_effect_handler=self) side_effect_handler=self)
...@@ -710,7 +711,7 @@ Performance and stability improvements on all platforms.""" ...@@ -710,7 +711,7 @@ Performance and stability improvements on all platforms."""
options = MakeOptions(f=force, m=manual, options = MakeOptions(f=force, m=manual,
r="reviewer@chromium.org" if not manual else None, r="reviewer@chromium.org" if not manual else None,
c = TEST_CONFIG[CHROMIUM]) c = TEST_CONFIG[CHROMIUM])
RunPushToTrunk(TEST_CONFIG, options, self) RunPushToTrunk(TEST_CONFIG, PushToTrunkOptions(options), self)
deps = FileToText(TEST_CONFIG[DEPS_FILE]) deps = FileToText(TEST_CONFIG[DEPS_FILE])
self.assertTrue(re.search("\"v8_revision\": \"123456\"", deps)) self.assertTrue(re.search("\"v8_revision\": \"123456\"", deps))
...@@ -759,7 +760,9 @@ Performance and stability improvements on all platforms.""" ...@@ -759,7 +760,9 @@ Performance and stability improvements on all platforms."""
["svn log -1 --oneline ChangeLog", "r65 | Prepare push to trunk..."], ["svn log -1 --oneline ChangeLog", "r65 | Prepare push to trunk..."],
]) ])
auto_roll.RunAutoRoll(TEST_CONFIG, MakeOptions(m=False, f=True), self) auto_roll.RunAutoRoll(TEST_CONFIG,
AutoRollOptions(MakeOptions(m=False, f=True)),
self)
self.assertEquals("100", self.MakeStep().Restore("lkgr")) self.assertEquals("100", self.MakeStep().Restore("lkgr"))
self.assertEquals("101", self.MakeStep().Restore("latest")) self.assertEquals("101", self.MakeStep().Restore("latest"))
...@@ -768,7 +771,7 @@ Performance and stability improvements on all platforms.""" ...@@ -768,7 +771,7 @@ Performance and stability improvements on all platforms."""
class SystemTest(unittest.TestCase): class SystemTest(unittest.TestCase):
def testReload(self): def testReload(self):
step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={}, step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
options=None, options=CommonOptions(MakeOptions()),
side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER) side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
body = step.Reload( body = step.Reload(
"""------------------------------------------------------------------------ """------------------------------------------------------------------------
......
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