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

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

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 months 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
« no previous file with comments | « tools/push-to-trunk/auto_roll.py ('k') | tools/push-to-trunk/git_recipes.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 # disclaimer in the documentation and/or other materials provided 11 # disclaimer in the documentation and/or other materials provided
12 # with the distribution. 12 # with the distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived 14 # contributors may be used to endorse or promote products derived
15 # from this software without specific prior written permission. 15 # from this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import datetime 29 import datetime
30 import json
31 import os 30 import os
32 import re 31 import re
33 import subprocess 32 import subprocess
34 import sys 33 import sys
35 import textwrap 34 import textwrap
36 import time 35 import time
37 import urllib2 36 import urllib2
38 37
39 from git_recipes import GitRecipesMixin
40
41 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME" 38 PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME"
42 TEMP_BRANCH = "TEMP_BRANCH" 39 TEMP_BRANCH = "TEMP_BRANCH"
43 BRANCHNAME = "BRANCHNAME" 40 BRANCHNAME = "BRANCHNAME"
44 DOT_GIT_LOCATION = "DOT_GIT_LOCATION" 41 DOT_GIT_LOCATION = "DOT_GIT_LOCATION"
45 VERSION_FILE = "VERSION_FILE" 42 VERSION_FILE = "VERSION_FILE"
46 CHANGELOG_FILE = "CHANGELOG_FILE" 43 CHANGELOG_FILE = "CHANGELOG_FILE"
47 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE" 44 CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE"
48 COMMITMSG_FILE = "COMMITMSG_FILE" 45 COMMITMSG_FILE = "COMMITMSG_FILE"
49 PATCH_FILE = "PATCH_FILE" 46 PATCH_FILE = "PATCH_FILE"
50 47
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 def GetDate(self): 212 def GetDate(self):
216 return datetime.date.today().strftime("%Y-%m-%d") 213 return datetime.date.today().strftime("%Y-%m-%d")
217 214
218 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() 215 DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
219 216
220 217
221 class NoRetryException(Exception): 218 class NoRetryException(Exception):
222 pass 219 pass
223 220
224 221
225 class GitFailedException(Exception):
226 pass
227
228
229 class CommonOptions(object): 222 class CommonOptions(object):
230 def __init__(self, options, manual=True): 223 def __init__(self, options, manual=True):
231 self.requires_editor = True 224 self.requires_editor = True
232 self.wait_for_lgtm = True 225 self.wait_for_lgtm = True
233 self.s = options.s 226 self.s = options.s
234 self.force_readline_defaults = not manual 227 self.force_readline_defaults = not manual
235 self.force_upload = not manual 228 self.force_upload = not manual
236 self.manual = manual 229 self.manual = manual
237 self.reviewer = getattr(options, 'reviewer', "")
238 self.author = getattr(options, 'a', "")
239 230
240 231
241 class Step(GitRecipesMixin): 232 class Step(object):
242 def __init__(self, text, requires, number, config, state, options, handler): 233 def __init__(self, text, requires, number, config, state, options, handler):
243 self._text = text 234 self._text = text
244 self._requires = requires 235 self._requires = requires
245 self._number = number 236 self._number = number
246 self._config = config 237 self._config = config
247 self._state = state 238 self._state = state
248 self._options = options 239 self._options = options
249 self._side_effect_handler = handler 240 self._side_effect_handler = handler
250 assert self._number >= 0 241 assert self._number >= 0
251 assert self._config is not None 242 assert self._config is not None
252 assert self._state is not None 243 assert self._state is not None
253 assert self._side_effect_handler is not None 244 assert self._side_effect_handler is not None
254 assert isinstance(options, CommonOptions) 245 assert isinstance(options, CommonOptions)
255 246
256 def __getitem__(self, key):
257 # Convenience method to allow direct [] access on step classes for
258 # manipulating the backed state dict.
259 return self._state[key]
260
261 def __setitem__(self, key, value):
262 # Convenience method to allow direct [] access on step classes for
263 # manipulating the backed state dict.
264 self._state[key] = value
265
266 def Config(self, key): 247 def Config(self, key):
267 return self._config[key] 248 return self._config[key]
268 249
269 def Run(self): 250 def Run(self):
270 # Restore state. 251 if self._requires:
271 state_file = "%s-state.json" % self._config[PERSISTFILE_BASENAME] 252 self.RestoreIfUnset(self._requires)
272 if not self._state and os.path.exists(state_file): 253 if not self._state[self._requires]:
273 self._state.update(json.loads(FileToText(state_file))) 254 return
274
275 # Skip step if requirement is not met.
276 if self._requires and not self._state.get(self._requires):
277 return
278
279 print ">>> Step %d: %s" % (self._number, self._text) 255 print ">>> Step %d: %s" % (self._number, self._text)
280 self.RunStep() 256 self.RunStep()
281 257
282 # Persist state.
283 TextToFile(json.dumps(self._state), state_file)
284
285 def RunStep(self): 258 def RunStep(self):
286 raise NotImplementedError 259 raise NotImplementedError
287 260
288 def Retry(self, cb, retry_on=None, wait_plan=None): 261 def Retry(self, cb, retry_on=None, wait_plan=None):
289 """ Retry a function. 262 """ Retry a function.
290 Params: 263 Params:
291 cb: The function to retry. 264 cb: The function to retry.
292 retry_on: A callback that takes the result of the function and returns 265 retry_on: A callback that takes the result of the function and returns
293 True if the function should be retried. A function throwing an 266 True if the function should be retried. A function throwing an
294 exception is always retried. 267 exception is always retried.
(...skipping 24 matching lines...) Expand all
319 def ReadLine(self, default=None): 292 def ReadLine(self, default=None):
320 # Don't prompt in forced mode. 293 # Don't prompt in forced mode.
321 if self._options.force_readline_defaults and default is not None: 294 if self._options.force_readline_defaults and default is not None:
322 print "%s (forced)" % default 295 print "%s (forced)" % default
323 return default 296 return default
324 else: 297 else:
325 return self._side_effect_handler.ReadLine() 298 return self._side_effect_handler.ReadLine()
326 299
327 def Git(self, args="", prefix="", pipe=True, retry_on=None): 300 def Git(self, args="", prefix="", pipe=True, retry_on=None):
328 cmd = lambda: self._side_effect_handler.Command("git", args, prefix, pipe) 301 cmd = lambda: self._side_effect_handler.Command("git", args, prefix, pipe)
329 result = self.Retry(cmd, retry_on, [5, 30])
330 if result is None:
331 raise GitFailedException("'git %s' failed." % args)
332 return result
333
334 def SVN(self, args="", prefix="", pipe=True, retry_on=None):
335 cmd = lambda: self._side_effect_handler.Command("svn", args, prefix, pipe)
336 return self.Retry(cmd, retry_on, [5, 30]) 302 return self.Retry(cmd, retry_on, [5, 30])
337 303
338 def Editor(self, args): 304 def Editor(self, args):
339 if self._options.requires_editor: 305 if self._options.requires_editor:
340 return self._side_effect_handler.Command(os.environ["EDITOR"], args, 306 return self._side_effect_handler.Command(os.environ["EDITOR"], args,
341 pipe=False) 307 pipe=False)
342 308
343 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None): 309 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None):
344 wait_plan = wait_plan or [3, 60, 600] 310 wait_plan = wait_plan or [3, 60, 600]
345 cmd = lambda: self._side_effect_handler.ReadURL(url, params) 311 cmd = lambda: self._side_effect_handler.ReadURL(url, params)
(...skipping 12 matching lines...) Expand all
358 if not self._options.manual: 324 if not self._options.manual:
359 msg = msg or "Only available in manual mode." 325 msg = msg or "Only available in manual mode."
360 self.Die(msg) 326 self.Die(msg)
361 327
362 def Confirm(self, msg): 328 def Confirm(self, msg):
363 print "%s [Y/n] " % msg, 329 print "%s [Y/n] " % msg,
364 answer = self.ReadLine(default="Y") 330 answer = self.ReadLine(default="Y")
365 return answer == "" or answer == "Y" or answer == "y" 331 return answer == "" or answer == "Y" or answer == "y"
366 332
367 def DeleteBranch(self, name): 333 def DeleteBranch(self, name):
368 for line in self.GitBranch().splitlines(): 334 git_result = self.Git("branch").strip()
335 for line in git_result.splitlines():
369 if re.match(r".*\s+%s$" % name, line): 336 if re.match(r".*\s+%s$" % name, line):
370 msg = "Branch %s exists, do you want to delete it?" % name 337 msg = "Branch %s exists, do you want to delete it?" % name
371 if self.Confirm(msg): 338 if self.Confirm(msg):
372 self.GitDeleteBranch(name) 339 if self.Git("branch -D %s" % name) is None:
340 self.Die("Deleting branch '%s' failed." % name)
373 print "Branch %s deleted." % name 341 print "Branch %s deleted." % name
374 else: 342 else:
375 msg = "Can't continue. Please delete branch %s and try again." % name 343 msg = "Can't continue. Please delete branch %s and try again." % name
376 self.Die(msg) 344 self.Die(msg)
377 345
346 def Persist(self, var, value):
347 value = value or "__EMPTY__"
348 TextToFile(value, "%s-%s" % (self._config[PERSISTFILE_BASENAME], var))
349
350 def Restore(self, var):
351 value = FileToText("%s-%s" % (self._config[PERSISTFILE_BASENAME], var))
352 value = value or self.Die("Variable '%s' could not be restored." % var)
353 return "" if value == "__EMPTY__" else value
354
355 def RestoreIfUnset(self, var_name):
356 if self._state.get(var_name) is None:
357 self._state[var_name] = self.Restore(var_name)
358
378 def InitialEnvironmentChecks(self): 359 def InitialEnvironmentChecks(self):
379 # Cancel if this is not a git checkout. 360 # Cancel if this is not a git checkout.
380 if not os.path.exists(self._config[DOT_GIT_LOCATION]): 361 if not os.path.exists(self._config[DOT_GIT_LOCATION]):
381 self.Die("This is not a git checkout, this script won't work for you.") 362 self.Die("This is not a git checkout, this script won't work for you.")
382 363
383 # Cancel if EDITOR is unset or not executable. 364 # Cancel if EDITOR is unset or not executable.
384 if (self._options.requires_editor and (not os.environ.get("EDITOR") or 365 if (self._options.requires_editor and (not os.environ.get("EDITOR") or
385 Command("which", os.environ["EDITOR"]) is None)): 366 Command("which", os.environ["EDITOR"]) is None)):
386 self.Die("Please set your EDITOR environment variable, you'll need it.") 367 self.Die("Please set your EDITOR environment variable, you'll need it.")
387 368
388 def CommonPrepare(self): 369 def CommonPrepare(self):
389 # Check for a clean workdir. 370 # Check for a clean workdir.
390 if not self.GitIsWorkdirClean(): 371 if self.Git("status -s -uno").strip() != "":
391 self.Die("Workspace is not clean. Please commit or undo your changes.") 372 self.Die("Workspace is not clean. Please commit or undo your changes.")
392 373
393 # Persist current branch. 374 # Persist current branch.
394 self["current_branch"] = self.GitCurrentBranch() 375 current_branch = ""
376 git_result = self.Git("status -s -b -uno").strip()
377 for line in git_result.splitlines():
378 match = re.match(r"^## (.+)", line)
379 if match:
380 current_branch = match.group(1)
381 break
382 self.Persist("current_branch", current_branch)
395 383
396 # Fetch unfetched revisions. 384 # Fetch unfetched revisions.
397 self.GitSVNFetch() 385 if self.Git("svn fetch") is None:
386 self.Die("'git svn fetch' failed.")
398 387
399 def PrepareBranch(self): 388 def PrepareBranch(self):
400 # Get ahold of a safe temporary branch and check it out. 389 # Get ahold of a safe temporary branch and check it out.
401 if self["current_branch"] != self._config[TEMP_BRANCH]: 390 self.RestoreIfUnset("current_branch")
391 if self._state["current_branch"] != self._config[TEMP_BRANCH]:
402 self.DeleteBranch(self._config[TEMP_BRANCH]) 392 self.DeleteBranch(self._config[TEMP_BRANCH])
403 self.GitCreateBranch(self._config[TEMP_BRANCH]) 393 self.Git("checkout -b %s" % self._config[TEMP_BRANCH])
404 394
405 # Delete the branch that will be created later if it exists already. 395 # Delete the branch that will be created later if it exists already.
406 self.DeleteBranch(self._config[BRANCHNAME]) 396 self.DeleteBranch(self._config[BRANCHNAME])
407 397
408 def CommonCleanup(self): 398 def CommonCleanup(self):
409 self.GitCheckout(self["current_branch"]) 399 self.RestoreIfUnset("current_branch")
410 if self._config[TEMP_BRANCH] != self["current_branch"]: 400 self.Git("checkout -f %s" % self._state["current_branch"])
411 self.GitDeleteBranch(self._config[TEMP_BRANCH]) 401 if self._config[TEMP_BRANCH] != self._state["current_branch"]:
412 if self._config[BRANCHNAME] != self["current_branch"]: 402 self.Git("branch -D %s" % self._config[TEMP_BRANCH])
413 self.GitDeleteBranch(self._config[BRANCHNAME]) 403 if self._config[BRANCHNAME] != self._state["current_branch"]:
404 self.Git("branch -D %s" % self._config[BRANCHNAME])
414 405
415 # Clean up all temporary files. 406 # Clean up all temporary files.
416 Command("rm", "-f %s*" % self._config[PERSISTFILE_BASENAME]) 407 Command("rm", "-f %s*" % self._config[PERSISTFILE_BASENAME])
417 408
418 def ReadAndPersistVersion(self, prefix=""): 409 def ReadAndPersistVersion(self, prefix=""):
419 def ReadAndPersist(var_name, def_name): 410 def ReadAndPersist(var_name, def_name):
420 match = re.match(r"^#define %s\s+(\d*)" % def_name, line) 411 match = re.match(r"^#define %s\s+(\d*)" % def_name, line)
421 if match: 412 if match:
422 value = match.group(1) 413 value = match.group(1)
423 self["%s%s" % (prefix, var_name)] = value 414 self.Persist("%s%s" % (prefix, var_name), value)
415 self._state["%s%s" % (prefix, var_name)] = value
424 for line in LinesInFile(self._config[VERSION_FILE]): 416 for line in LinesInFile(self._config[VERSION_FILE]):
425 for (var_name, def_name) in [("major", "MAJOR_VERSION"), 417 for (var_name, def_name) in [("major", "MAJOR_VERSION"),
426 ("minor", "MINOR_VERSION"), 418 ("minor", "MINOR_VERSION"),
427 ("build", "BUILD_NUMBER"), 419 ("build", "BUILD_NUMBER"),
428 ("patch", "PATCH_LEVEL")]: 420 ("patch", "PATCH_LEVEL")]:
429 ReadAndPersist(var_name, def_name) 421 ReadAndPersist(var_name, def_name)
430 422
423 def RestoreVersionIfUnset(self, prefix=""):
424 for v in ["major", "minor", "build", "patch"]:
425 self.RestoreIfUnset("%s%s" % (prefix, v))
426
431 def WaitForLGTM(self): 427 def WaitForLGTM(self):
432 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit " 428 print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit "
433 "your change. (If you need to iterate on the patch or double check " 429 "your change. (If you need to iterate on the patch or double check "
434 "that it's sane, do so in another shell, but remember to not " 430 "that it's sane, do so in another shell, but remember to not "
435 "change the headline of the uploaded CL.") 431 "change the headline of the uploaded CL.")
436 answer = "" 432 answer = ""
437 while answer != "LGTM": 433 while answer != "LGTM":
438 print "> ", 434 print "> ",
439 answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM") 435 answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM")
440 if answer != "LGTM": 436 if answer != "LGTM":
441 print "That was not 'LGTM'." 437 print "That was not 'LGTM'."
442 438
443 def WaitForResolvingConflicts(self, patch_file): 439 def WaitForResolvingConflicts(self, patch_file):
444 print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", " 440 print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", "
445 "or resolve the conflicts, stage *all* touched files with " 441 "or resolve the conflicts, stage *all* touched files with "
446 "'git add', and type \"RESOLVED<Return>\"") 442 "'git add', and type \"RESOLVED<Return>\"")
447 self.DieNoManualMode() 443 self.DieNoManualMode()
448 answer = "" 444 answer = ""
449 while answer != "RESOLVED": 445 while answer != "RESOLVED":
450 if answer == "ABORT": 446 if answer == "ABORT":
451 self.Die("Applying the patch failed.") 447 self.Die("Applying the patch failed.")
452 if answer != "": 448 if answer != "":
453 print "That was not 'RESOLVED' or 'ABORT'." 449 print "That was not 'RESOLVED' or 'ABORT'."
454 print "> ", 450 print "> ",
455 answer = self.ReadLine() 451 answer = self.ReadLine()
456 452
457 # Takes a file containing the patch to apply as first argument. 453 # Takes a file containing the patch to apply as first argument.
458 def ApplyPatch(self, patch_file, revert=False): 454 def ApplyPatch(self, patch_file, reverse_patch=""):
459 try: 455 args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file)
460 self.GitApplyPatch(patch_file, revert) 456 if self.Git(args) is None:
461 except GitFailedException:
462 self.WaitForResolvingConflicts(patch_file) 457 self.WaitForResolvingConflicts(patch_file)
463 458
464 def FindLastTrunkPush(self, parent_hash=""):
465 push_pattern = "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based"
466 branch = "" if parent_hash else "svn/trunk"
467 return self.GitLog(n=1, format="%H", grep=push_pattern,
468 parent_hash=parent_hash, branch=branch)
469
470 459
471 class UploadStep(Step): 460 class UploadStep(Step):
472 MESSAGE = "Upload for code review." 461 MESSAGE = "Upload for code review."
473 462
474 def RunStep(self): 463 def RunStep(self):
475 if self._options.reviewer: 464 if self._options.r:
476 print "Using account %s for review." % self._options.reviewer 465 print "Using account %s for review." % self._options.r
477 reviewer = self._options.reviewer 466 reviewer = self._options.r
478 else: 467 else:
479 print "Please enter the email address of a V8 reviewer for your patch: ", 468 print "Please enter the email address of a V8 reviewer for your patch: ",
480 self.DieNoManualMode("A reviewer must be specified in forced mode.") 469 self.DieNoManualMode("A reviewer must be specified in forced mode.")
481 reviewer = self.ReadLine() 470 reviewer = self.ReadLine()
482 self.GitUpload(reviewer, self._options.author, self._options.force_upload) 471 force_flag = " -f" if self._options.force_upload else ""
472 args = "cl upload -r \"%s\" --send-mail%s" % (reviewer, force_flag)
473 # TODO(machenbach): Check output in forced mode. Verify that all required
474 # base files were uploaded, if not retry.
475 if self.Git(args, pipe=False) is None:
476 self.Die("'git cl upload' failed, please try again.")
483 477
484 478
485 def MakeStep(step_class=Step, number=0, state=None, config=None, 479 def MakeStep(step_class=Step, number=0, state=None, config=None,
486 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 480 options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
487 # Allow to pass in empty dictionaries. 481 # Allow to pass in empty dictionaries.
488 state = state if state is not None else {} 482 state = state if state is not None else {}
489 config = config if config is not None else {} 483 config = config if config is not None else {}
490 484
491 try: 485 try:
492 message = step_class.MESSAGE 486 message = step_class.MESSAGE
493 except AttributeError: 487 except AttributeError:
494 message = step_class.__name__ 488 message = step_class.__name__
495 try: 489 try:
496 requires = step_class.REQUIRES 490 requires = step_class.REQUIRES
497 except AttributeError: 491 except AttributeError:
498 requires = None 492 requires = None
499 493
500 return step_class(message, requires, number=number, config=config, 494 return step_class(message, requires, number=number, config=config,
501 state=state, options=options, 495 state=state, options=options,
502 handler=side_effect_handler) 496 handler=side_effect_handler)
503 497
504 498
505 def RunScript(step_classes, 499 def RunScript(step_classes,
506 config, 500 config,
507 options, 501 options,
508 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): 502 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER):
509 state_file = "%s-state.json" % config[PERSISTFILE_BASENAME]
510 if options.s == 0 and os.path.exists(state_file):
511 os.remove(state_file)
512 state = {} 503 state = {}
513 steps = [] 504 steps = []
514 for (number, step_class) in enumerate(step_classes): 505 for (number, step_class) in enumerate(step_classes):
515 steps.append(MakeStep(step_class, number, state, config, 506 steps.append(MakeStep(step_class, number, state, config,
516 options, side_effect_handler)) 507 options, side_effect_handler))
517 508
518 for step in steps[options.s:]: 509 for step in steps[options.s:]:
519 step.Run() 510 step.Run()
OLDNEW
« no previous file with comments | « tools/push-to-trunk/auto_roll.py ('k') | tools/push-to-trunk/git_recipes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698