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

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

Issue 67763005: Add forced mode to push-to-trunk script. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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
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
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 def ReadLine(self): 169 def ReadLine(self):
170 return sys.stdin.readline().strip() 170 return sys.stdin.readline().strip()
171 171
172 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() 172 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
173 173
174 174
175 class Step(object): 175 class Step(object):
176 def __init__(self, text="", requires=None): 176 def __init__(self, text="", requires=None):
177 self._text = text 177 self._text = text
178 self._number = -1 178 self._number = -1
179 self._options = None
179 self._requires = requires 180 self._requires = requires
180 self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER 181 self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER
181 182
182 def SetNumber(self, number): 183 def SetNumber(self, number):
183 self._number = number 184 self._number = number
184 185
185 def SetConfig(self, config): 186 def SetConfig(self, config):
186 self._config = config 187 self._config = config
187 188
188 def SetState(self, state): 189 def SetState(self, state):
(...skipping 16 matching lines...) Expand all
205 if self._requires: 206 if self._requires:
206 self.RestoreIfUnset(self._requires) 207 self.RestoreIfUnset(self._requires)
207 if not self._state[self._requires]: 208 if not self._state[self._requires]:
208 return 209 return
209 print ">>> Step %d: %s" % (self._number, self._text) 210 print ">>> Step %d: %s" % (self._number, self._text)
210 self.RunStep() 211 self.RunStep()
211 212
212 def RunStep(self): 213 def RunStep(self):
213 raise NotImplementedError 214 raise NotImplementedError
214 215
215 def ReadLine(self): 216 def ReadLine(self, default=None):
216 return self._side_effect_handler.ReadLine() 217 # Don't prompt in forced mode.
218 if self._options and self._options.f and default is not None:
219 print "%s (forced)" % default
220 return default
221 else:
222 return self._side_effect_handler.ReadLine()
217 223
218 def Git(self, args="", prefix="", pipe=True): 224 def Git(self, args="", prefix="", pipe=True):
219 return self._side_effect_handler.Command("git", args, prefix, pipe) 225 return self._side_effect_handler.Command("git", args, prefix, pipe)
220 226
221 def Editor(self, args): 227 def Editor(self, args):
222 return self._side_effect_handler.Command(os.environ["EDITOR"], args, 228 return self._side_effect_handler.Command(os.environ["EDITOR"], args,
223 pipe=False) 229 pipe=False)
224 230
225 def Die(self, msg=""): 231 def Die(self, msg=""):
226 if msg != "": 232 if msg != "":
227 print "Error: %s" % msg 233 print "Error: %s" % msg
228 print "Exiting" 234 print "Exiting"
229 raise Exception(msg) 235 raise Exception(msg)
230 236
237 def DieInFocedMode(self, msg=""):
Jakob Kummerow 2013/11/19 13:46:11 s/Foced/Forced/
Michael Achenbach 2013/11/19 15:09:37 Done.
238 if self._options and self._options.f:
239 msg = msg or "Not implemented in forced mode."
240 self.Die(msg)
241
231 def Confirm(self, msg): 242 def Confirm(self, msg):
232 print "%s [Y/n] " % msg, 243 print "%s [Y/n] " % msg,
233 answer = self.ReadLine() 244 answer = self.ReadLine(default="Y")
234 return answer == "" or answer == "Y" or answer == "y" 245 return answer == "" or answer == "Y" or answer == "y"
235 246
236 def DeleteBranch(self, name): 247 def DeleteBranch(self, name):
237 git_result = self.Git("branch").strip() 248 git_result = self.Git("branch").strip()
238 for line in git_result.splitlines(): 249 for line in git_result.splitlines():
239 if re.match(r".*\s+%s$" % name, line): 250 if re.match(r".*\s+%s$" % name, line):
240 msg = "Branch %s exists, do you want to delete it?" % name 251 msg = "Branch %s exists, do you want to delete it?" % name
241 if self.Confirm(msg): 252 if self.Confirm(msg):
242 if self.Git("branch -D %s" % name) is None: 253 if self.Git("branch -D %s" % name) is None:
243 self.Die("Deleting branch '%s' failed." % name) 254 self.Die("Deleting branch '%s' failed." % name)
(...skipping 13 matching lines...) Expand all
257 268
258 def RestoreIfUnset(self, var_name): 269 def RestoreIfUnset(self, var_name):
259 if self._state.get(var_name) is None: 270 if self._state.get(var_name) is None:
260 self._state[var_name] = self.Restore(var_name) 271 self._state[var_name] = self.Restore(var_name)
261 272
262 def InitialEnvironmentChecks(self): 273 def InitialEnvironmentChecks(self):
263 # Cancel if this is not a git checkout. 274 # Cancel if this is not a git checkout.
264 if not os.path.exists(self._config[DOT_GIT_LOCATION]): 275 if not os.path.exists(self._config[DOT_GIT_LOCATION]):
265 self.Die("This is not a git checkout, this script won't work for you.") 276 self.Die("This is not a git checkout, this script won't work for you.")
266 277
278 # TODO(machenbach): Don't use EDITOR in forced mode as soon as script is
279 # well tested.
267 # Cancel if EDITOR is unset or not executable. 280 # Cancel if EDITOR is unset or not executable.
268 if (not os.environ.get("EDITOR") or 281 if (not os.environ.get("EDITOR") or
269 Command("which", os.environ["EDITOR"]) is None): 282 Command("which", os.environ["EDITOR"]) is None):
270 self.Die("Please set your EDITOR environment variable, you'll need it.") 283 self.Die("Please set your EDITOR environment variable, you'll need it.")
271 284
272 def CommonPrepare(self): 285 def CommonPrepare(self):
273 # Check for a clean workdir. 286 # Check for a clean workdir.
274 if self.Git("status -s -uno").strip() != "": 287 if self.Git("status -s -uno").strip() != "":
275 self.Die("Workspace is not clean. Please commit or undo your changes.") 288 self.Die("Workspace is not clean. Please commit or undo your changes.")
276 289
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 self.RestoreIfUnset("%s%s" % (prefix, v)) 341 self.RestoreIfUnset("%s%s" % (prefix, v))
329 342
330 def WaitForLGTM(self): 343 def WaitForLGTM(self):
331 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit " 344 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit "
332 "your change. (If you need to iterate on the patch or double check " 345 "your change. (If you need to iterate on the patch or double check "
333 "that it's sane, do so in another shell, but remember to not " 346 "that it's sane, do so in another shell, but remember to not "
334 "change the headline of the uploaded CL.") 347 "change the headline of the uploaded CL.")
335 answer = "" 348 answer = ""
336 while answer != "LGTM": 349 while answer != "LGTM":
337 print "> ", 350 print "> ",
351 # TODO(machenbach): Add default="LGTM" to avoid prompt when script is
352 # well tested and when prepare push cl has TBR flag.
338 answer = self.ReadLine() 353 answer = self.ReadLine()
339 if answer != "LGTM": 354 if answer != "LGTM":
340 print "That was not 'LGTM'." 355 print "That was not 'LGTM'."
341 356
342 def WaitForResolvingConflicts(self, patch_file): 357 def WaitForResolvingConflicts(self, patch_file):
343 print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", " 358 print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", "
344 "or resolve the conflicts, stage *all* touched files with " 359 "or resolve the conflicts, stage *all* touched files with "
345 "'git add', and type \"RESOLVED<Return>\"") 360 "'git add', and type \"RESOLVED<Return>\"")
361 self.DieInFocedMode()
346 answer = "" 362 answer = ""
347 while answer != "RESOLVED": 363 while answer != "RESOLVED":
348 if answer == "ABORT": 364 if answer == "ABORT":
349 self.Die("Applying the patch failed.") 365 self.Die("Applying the patch failed.")
350 if answer != "": 366 if answer != "":
351 print "That was not 'RESOLVED' or 'ABORT'." 367 print "That was not 'RESOLVED' or 'ABORT'."
352 print "> ", 368 print "> ",
353 answer = self.ReadLine() 369 answer = self.ReadLine()
354 370
355 # Takes a file containing the patch to apply as first argument. 371 # Takes a file containing the patch to apply as first argument.
356 def ApplyPatch(self, patch_file, reverse_patch=""): 372 def ApplyPatch(self, patch_file, reverse_patch=""):
357 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file) 373 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file)
358 if self.Git(args) is None: 374 if self.Git(args) is None:
359 self.WaitForResolvingConflicts(patch_file) 375 self.WaitForResolvingConflicts(patch_file)
360 376
361 377
362 class UploadStep(Step): 378 class UploadStep(Step):
363 def __init__(self): 379 def __init__(self):
364 Step.__init__(self, "Upload for code review.") 380 Step.__init__(self, "Upload for code review.")
365 381
366 def RunStep(self): 382 def RunStep(self):
367 print "Please enter the email address of a V8 reviewer for your patch: ", 383 if self._options and self._options.r:
368 reviewer = self.ReadLine() 384 print "Using account %s for review." % self._options.r
385 reviewer = self._options.r
386 else:
387 print "Please enter the email address of a V8 reviewer for your patch: ",
388 self.DieInFocedMode("A reviewer must be specified in forced mode.")
389 reviewer = self.ReadLine()
369 args = "cl upload -r \"%s\" --send-mail" % reviewer 390 args = "cl upload -r \"%s\" --send-mail" % reviewer
370 if self.Git(args,pipe=False) is None: 391 if self.Git(args,pipe=False) is None:
371 self.Die("'git cl upload' failed, please try again.") 392 self.Die("'git cl upload' failed, please try again.")
372 393
373 394
374 def RunScript(step_classes, 395 def RunScript(step_classes,
375 config, 396 config,
376 options, 397 options,
377 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 398 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
378 state = {} 399 state = {}
379 steps = [] 400 steps = []
380 number = 0 401 number = 0
381 402
382 for step_class in step_classes: 403 for step_class in step_classes:
383 # TODO(machenbach): Factory methods. 404 # TODO(machenbach): Factory methods.
384 step = step_class() 405 step = step_class()
385 step.SetNumber(number) 406 step.SetNumber(number)
386 step.SetConfig(config) 407 step.SetConfig(config)
387 step.SetOptions(options) 408 step.SetOptions(options)
388 step.SetState(state) 409 step.SetState(state)
389 step.SetSideEffectHandler(side_effect_handler) 410 step.SetSideEffectHandler(side_effect_handler)
390 steps.append(step) 411 steps.append(step)
391 number += 1 412 number += 1
392 413
393 for step in steps[options.s:]: 414 for step in steps[options.s:]:
394 step.Run() 415 step.Run()
OLDNEW
« no previous file with comments | « no previous file | tools/push-to-trunk/push_to_trunk.py » ('j') | tools/push-to-trunk/push_to_trunk.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698