Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 | 265 |
| 266 def Fetch(self): | 266 def Fetch(self): |
| 267 raise NotImplementedError() | 267 raise NotImplementedError() |
| 268 | 268 |
| 269 def GetTags(self): | 269 def GetTags(self): |
| 270 raise NotImplementedError() | 270 raise NotImplementedError() |
| 271 | 271 |
| 272 def GetBranches(self): | 272 def GetBranches(self): |
| 273 raise NotImplementedError() | 273 raise NotImplementedError() |
| 274 | 274 |
| 275 def GitSvn(self, hsh, branch=""): | |
| 276 raise NotImplementedError() | |
| 277 | |
| 278 def SvnGit(self, rev, branch=""): | |
| 279 raise NotImplementedError() | |
| 280 | |
| 281 def MasterBranch(self): | 275 def MasterBranch(self): |
| 282 raise NotImplementedError() | 276 raise NotImplementedError() |
| 283 | 277 |
| 284 def CandidateBranch(self): | 278 def CandidateBranch(self): |
| 285 raise NotImplementedError() | 279 raise NotImplementedError() |
| 286 | 280 |
| 287 def RemoteMasterBranch(self): | 281 def RemoteMasterBranch(self): |
| 288 raise NotImplementedError() | 282 raise NotImplementedError() |
| 289 | 283 |
| 290 def RemoteCandidateBranch(self): | 284 def RemoteCandidateBranch(self): |
| 291 raise NotImplementedError() | 285 raise NotImplementedError() |
| 292 | 286 |
| 293 def RemoteBranch(self, name): | 287 def RemoteBranch(self, name): |
| 294 raise NotImplementedError() | 288 raise NotImplementedError() |
| 295 | 289 |
| 296 def Land(self): | 290 def Land(self): |
| 297 raise NotImplementedError() | 291 raise NotImplementedError() |
| 298 | 292 |
| 299 def CLLand(self): | 293 def CLLand(self): |
| 300 raise NotImplementedError() | 294 raise NotImplementedError() |
| 301 | 295 |
| 302 # TODO(machenbach): There is some svn knowledge in this interface. In svn, | |
| 303 # tag and commit are different remote commands, while in git we would commit | |
| 304 # and tag locally and then push/land in one unique step. | |
| 305 def Tag(self, tag, remote, message): | 296 def Tag(self, tag, remote, message): |
| 306 """Sets a tag for the current commit. | 297 """Sets a tag for the current commit. |
| 307 | 298 |
| 308 Assumptions: The commit already landed and the commit message is unique. | 299 Assumptions: The commit already landed and the commit message is unique. |
| 309 """ | 300 """ |
| 310 raise NotImplementedError() | 301 raise NotImplementedError() |
| 311 | 302 |
| 312 | 303 |
| 313 class GitSvnInterface(VCInterface): | 304 class GitInterface(VCInterface): |
| 314 def Pull(self): | |
| 315 self.step.GitSVNRebase() | |
| 316 | |
| 317 def Fetch(self): | |
| 318 self.step.GitSVNFetch() | |
| 319 | |
| 320 def GetTags(self): | |
| 321 # Get remote tags. | |
| 322 tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s), | |
| 323 self.step.GitRemotes()) | |
| 324 | |
| 325 # Remove 'svn/tags/' prefix. | |
| 326 return map(lambda s: s[9:], tags) | |
| 327 | |
| 328 def GetBranches(self): | |
| 329 # Get relevant remote branches, e.g. "svn/3.25". | |
| 330 branches = filter(lambda s: re.match(r"^svn/\d+\.\d+$", s), | |
| 331 self.step.GitRemotes()) | |
| 332 # Remove 'svn/' prefix. | |
| 333 return map(lambda s: s[4:], branches) | |
| 334 | |
| 335 def GitSvn(self, hsh, branch=""): | |
| 336 return self.step.GitSVNFindSVNRev(hsh, branch) | |
| 337 | |
| 338 def SvnGit(self, rev, branch=""): | |
| 339 return self.step.GitSVNFindGitHash(rev, branch) | |
| 340 | |
| 341 def MasterBranch(self): | |
| 342 return "bleeding_edge" | |
| 343 | |
| 344 def CandidateBranch(self): | |
| 345 return "trunk" | |
| 346 | |
| 347 def RemoteMasterBranch(self): | |
| 348 return "svn/bleeding_edge" | |
| 349 | |
| 350 def RemoteCandidateBranch(self): | |
| 351 return "svn/trunk" | |
| 352 | |
| 353 def RemoteBranch(self, name): | |
| 354 return "svn/%s" % name | |
| 355 | |
| 356 def Land(self): | |
| 357 self.step.GitSVNDCommit() | |
| 358 | |
| 359 def CLLand(self): | |
| 360 self.step.GitDCommit() | |
| 361 | |
| 362 def Tag(self, tag, remote, _): | |
| 363 self.step.GitSVNFetch() | |
| 364 self.step.Git("rebase %s" % remote) | |
| 365 self.step.GitSVNTag(tag) | |
| 366 | |
| 367 | |
| 368 class GitTagsOnlyMixin(VCInterface): | |
| 369 def Pull(self): | 305 def Pull(self): |
| 370 self.step.GitPull() | 306 self.step.GitPull() |
| 371 | 307 |
| 372 def Fetch(self): | 308 def Fetch(self): |
| 373 self.step.Git("fetch") | 309 self.step.Git("fetch") |
| 374 self.step.GitSVNFetch() | |
| 375 | 310 |
| 376 def GetTags(self): | 311 def GetTags(self): |
| 377 return self.step.Git("tag").strip().splitlines() | 312 return self.step.Git("tag").strip().splitlines() |
| 378 | 313 |
| 379 def GetBranches(self): | 314 def GetBranches(self): |
| 380 # Get relevant remote branches, e.g. "branch-heads/3.25". | 315 # Get relevant remote branches, e.g. "branch-heads/3.25". |
| 381 branches = filter( | 316 branches = filter( |
| 382 lambda s: re.match(r"^branch\-heads/\d+\.\d+$", s), | 317 lambda s: re.match(r"^branch\-heads/\d+\.\d+$", s), |
| 383 self.step.GitRemotes()) | 318 self.step.GitRemotes()) |
| 384 # Remove 'branch-heads/' prefix. | 319 # Remove 'branch-heads/' prefix. |
| 385 return map(lambda s: s[13:], branches) | 320 return map(lambda s: s[13:], branches) |
| 386 | 321 |
| 387 def MasterBranch(self): | 322 def MasterBranch(self): |
| 388 return "master" | 323 return "master" |
| 389 | 324 |
| 390 def CandidateBranch(self): | 325 def CandidateBranch(self): |
| 391 return "candidates" | 326 return "candidates" |
| 392 | 327 |
| 393 def RemoteMasterBranch(self): | 328 def RemoteMasterBranch(self): |
| 394 return "origin/master" | 329 return "origin/master" |
| 395 | 330 |
| 396 def RemoteCandidateBranch(self): | 331 def RemoteCandidateBranch(self): |
| 397 return "origin/candidates" | 332 return "origin/candidates" |
| 398 | 333 |
| 399 def RemoteBranch(self, name): | 334 def RemoteBranch(self, name): |
| 400 if name in ["candidates", "master"]: | 335 if name in ["candidates", "master"]: |
| 401 return "origin/%s" % name | 336 return "origin/%s" % name |
| 402 return "branch-heads/%s" % name | 337 return "branch-heads/%s" % name |
| 403 | 338 |
| 404 def PushRef(self, ref): | |
| 405 self.step.Git("push origin %s" % ref) | |
| 406 | |
| 407 def Tag(self, tag, remote, message): | 339 def Tag(self, tag, remote, message): |
| 408 # Wait for the commit to appear. Assumes unique commit message titles (this | 340 # Wait for the commit to appear. Assumes unique commit message titles (this |
| 409 # is the case for all automated merge and push commits - also no title is | 341 # is the case for all automated merge and push commits - also no title is |
| 410 # the prefix of another title). | 342 # the prefix of another title). |
| 411 commit = None | 343 commit = None |
| 412 for wait_interval in [3, 7, 15, 35, 45, 60]: | 344 for wait_interval in [3, 7, 15, 35, 45, 60]: |
| 413 self.step.Git("fetch") | 345 self.step.Git("fetch") |
| 414 commit = self.step.GitLog(n=1, format="%H", grep=message, branch=remote) | 346 commit = self.step.GitLog(n=1, format="%H", grep=message, branch=remote) |
| 415 if commit: | 347 if commit: |
| 416 break | 348 break |
| 417 print("The commit has not replicated to git. Waiting for %s seconds." % | 349 print("The commit has not replicated to git. Waiting for %s seconds." % |
| 418 wait_interval) | 350 wait_interval) |
| 419 self.step._side_effect_handler.Sleep(wait_interval) | 351 self.step._side_effect_handler.Sleep(wait_interval) |
| 420 else: | 352 else: |
| 421 self.step.Die("Couldn't determine commit for setting the tag. Maybe the " | 353 self.step.Die("Couldn't determine commit for setting the tag. Maybe the " |
| 422 "git updater is lagging behind?") | 354 "git updater is lagging behind?") |
| 423 | 355 |
| 424 self.step.Git("tag %s %s" % (tag, commit)) | 356 self.step.Git("tag %s %s" % (tag, commit)) |
| 425 self.PushRef(tag) | 357 self.step.Git("push origin %s" % tag) |
| 426 | |
| 427 | |
| 428 class GitReadSvnWriteInterface(GitTagsOnlyMixin, GitSvnInterface): | |
| 429 pass | |
| 430 | |
| 431 | |
| 432 class GitInterface(GitTagsOnlyMixin): | |
| 433 def Fetch(self): | |
| 434 self.step.Git("fetch") | |
| 435 | |
| 436 def GitSvn(self, hsh, branch=""): | |
| 437 return "" | |
| 438 | |
| 439 def SvnGit(self, rev, branch=""): | |
| 440 raise NotImplementedError() | |
| 441 | 358 |
| 442 def Land(self): | 359 def Land(self): |
| 443 # FIXME(machenbach): This will not work with checkouts from bot_update | |
| 444 # after flag day because it will push to the cache. Investigate if it | |
| 445 # will work with "cl land". | |
| 446 self.step.Git("push origin") | 360 self.step.Git("push origin") |
| 447 | 361 |
| 448 def CLLand(self): | 362 def CLLand(self): |
| 449 self.step.GitCLLand() | 363 self.step.GitCLLand() |
| 450 | 364 |
| 451 def PushRef(self, ref): | |
| 452 self.step.Git("push https://chromium.googlesource.com/v8/v8 %s" % ref) | |
|
Michael Achenbach
2014/11/12 10:56:12
This is no longer needed as all scripts have an ex
| |
| 453 | |
| 454 | |
| 455 VC_INTERFACES = { | |
| 456 "git_svn": GitSvnInterface, | |
| 457 "git_read_svn_write": GitReadSvnWriteInterface, | |
| 458 "git": GitInterface, | |
| 459 } | |
| 460 | |
| 461 | 365 |
| 462 class Step(GitRecipesMixin): | 366 class Step(GitRecipesMixin): |
| 463 def __init__(self, text, number, config, state, options, handler): | 367 def __init__(self, text, number, config, state, options, handler): |
| 464 self._text = text | 368 self._text = text |
| 465 self._number = number | 369 self._number = number |
| 466 self._config = config | 370 self._config = config |
| 467 self._state = state | 371 self._state = state |
| 468 self._options = options | 372 self._options = options |
| 469 self._side_effect_handler = handler | 373 self._side_effect_handler = handler |
| 470 self.vc = VC_INTERFACES[options.vc_interface]() | 374 self.vc = GitInterface() |
| 471 self.vc.InjectStep(self) | 375 self.vc.InjectStep(self) |
| 472 | 376 |
| 473 # The testing configuration might set a different default cwd. | 377 # The testing configuration might set a different default cwd. |
| 474 self.default_cwd = (self._config.get("DEFAULT_CWD") or | 378 self.default_cwd = (self._config.get("DEFAULT_CWD") or |
| 475 os.path.join(self._options.work_dir, "v8")) | 379 os.path.join(self._options.work_dir, "v8")) |
| 476 | 380 |
| 477 assert self._number >= 0 | 381 assert self._number >= 0 |
| 478 assert self._config is not None | 382 assert self._config is not None |
| 479 assert self._state is not None | 383 assert self._state is not None |
| 480 assert self._side_effect_handler is not None | 384 assert self._side_effect_handler is not None |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 return self.Retry(cmd, None, [5]) | 458 return self.Retry(cmd, None, [5]) |
| 555 | 459 |
| 556 def Git(self, args="", prefix="", pipe=True, retry_on=None, cwd=None): | 460 def Git(self, args="", prefix="", pipe=True, retry_on=None, cwd=None): |
| 557 cmd = lambda: self._side_effect_handler.Command( | 461 cmd = lambda: self._side_effect_handler.Command( |
| 558 "git", args, prefix, pipe, cwd=cwd or self.default_cwd) | 462 "git", args, prefix, pipe, cwd=cwd or self.default_cwd) |
| 559 result = self.Retry(cmd, retry_on, [5, 30]) | 463 result = self.Retry(cmd, retry_on, [5, 30]) |
| 560 if result is None: | 464 if result is None: |
| 561 raise GitFailedException("'git %s' failed." % args) | 465 raise GitFailedException("'git %s' failed." % args) |
| 562 return result | 466 return result |
| 563 | 467 |
| 564 def SVN(self, args="", prefix="", pipe=True, retry_on=None, cwd=None): | |
| 565 cmd = lambda: self._side_effect_handler.Command( | |
| 566 "svn", args, prefix, pipe, cwd=cwd or self.default_cwd) | |
| 567 return self.Retry(cmd, retry_on, [5, 30]) | |
| 568 | |
| 569 def Editor(self, args): | 468 def Editor(self, args): |
| 570 if self._options.requires_editor: | 469 if self._options.requires_editor: |
| 571 return self._side_effect_handler.Command( | 470 return self._side_effect_handler.Command( |
| 572 os.environ["EDITOR"], | 471 os.environ["EDITOR"], |
| 573 args, | 472 args, |
| 574 pipe=False, | 473 pipe=False, |
| 575 cwd=self.default_cwd) | 474 cwd=self.default_cwd) |
| 576 | 475 |
| 577 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None): | 476 def ReadURL(self, url, params=None, retry_on=None, wait_plan=None): |
| 578 wait_plan = wait_plan or [3, 60, 600] | 477 wait_plan = wait_plan or [3, 60, 600] |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 line = re.sub("\d+$", self[prefix + "major"], line) | 619 line = re.sub("\d+$", self[prefix + "major"], line) |
| 721 elif line.startswith("#define MINOR_VERSION"): | 620 elif line.startswith("#define MINOR_VERSION"): |
| 722 line = re.sub("\d+$", self[prefix + "minor"], line) | 621 line = re.sub("\d+$", self[prefix + "minor"], line) |
| 723 elif line.startswith("#define BUILD_NUMBER"): | 622 elif line.startswith("#define BUILD_NUMBER"): |
| 724 line = re.sub("\d+$", self[prefix + "build"], line) | 623 line = re.sub("\d+$", self[prefix + "build"], line) |
| 725 elif line.startswith("#define PATCH_LEVEL"): | 624 elif line.startswith("#define PATCH_LEVEL"): |
| 726 line = re.sub("\d+$", self[prefix + "patch"], line) | 625 line = re.sub("\d+$", self[prefix + "patch"], line) |
| 727 output += "%s\n" % line | 626 output += "%s\n" % line |
| 728 TextToFile(output, version_file) | 627 TextToFile(output, version_file) |
| 729 | 628 |
| 730 def SVNCommit(self, root, commit_message): | |
| 731 patch = self.GitDiff("HEAD^", "HEAD") | |
| 732 TextToFile(patch, self._config["PATCH_FILE"]) | |
| 733 self.Command("svn", "update", cwd=self._options.svn) | |
| 734 if self.Command("svn", "status", cwd=self._options.svn) != "": | |
| 735 self.Die("SVN checkout not clean.") | |
| 736 if not self.Command("patch", "-d %s -p1 -i %s" % | |
| 737 (root, self._config["PATCH_FILE"]), | |
| 738 cwd=self._options.svn): | |
| 739 self.Die("Could not apply patch.") | |
| 740 for line in self.Command( | |
| 741 "svn", "status", cwd=self._options.svn).splitlines(): | |
| 742 # Check for added and removed items. Svn status has seven status columns. | |
| 743 # The first contains ? for unknown and ! for missing. | |
| 744 match = re.match(r"^(.)...... (.*)$", line) | |
| 745 if match and match.group(1) == "?": | |
| 746 self.Command("svn", "add --force %s" % match.group(2), | |
| 747 cwd=self._options.svn) | |
| 748 if match and match.group(1) == "!": | |
| 749 self.Command("svn", "delete --force %s" % match.group(2), | |
| 750 cwd=self._options.svn) | |
| 751 | |
| 752 self.Command( | |
| 753 "svn", | |
| 754 "commit --non-interactive --username=%s --config-dir=%s -m \"%s\"" % | |
| 755 (self._options.author, self._options.svn_config, commit_message), | |
| 756 cwd=self._options.svn) | |
| 757 | |
| 758 | 629 |
| 759 class BootstrapStep(Step): | 630 class BootstrapStep(Step): |
| 760 MESSAGE = "Bootstapping v8 checkout." | 631 MESSAGE = "Bootstapping v8 checkout." |
| 761 | 632 |
| 762 def RunStep(self): | 633 def RunStep(self): |
| 763 if os.path.realpath(self.default_cwd) == os.path.realpath(V8_BASE): | 634 if os.path.realpath(self.default_cwd) == os.path.realpath(V8_BASE): |
| 764 self.Die("Can't use v8 checkout with calling script as work checkout.") | 635 self.Die("Can't use v8 checkout with calling script as work checkout.") |
| 765 # Directory containing the working v8 checkout. | 636 # Directory containing the working v8 checkout. |
| 766 if not os.path.exists(self._options.work_dir): | 637 if not os.path.exists(self._options.work_dir): |
| 767 os.makedirs(self._options.work_dir) | 638 os.makedirs(self._options.work_dir) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 parser.add_argument("--dry-run", default=False, action="store_true", | 737 parser.add_argument("--dry-run", default=False, action="store_true", |
| 867 help="Perform only read-only actions.") | 738 help="Perform only read-only actions.") |
| 868 parser.add_argument("-g", "--googlers-mapping", | 739 parser.add_argument("-g", "--googlers-mapping", |
| 869 help="Path to the script mapping google accounts.") | 740 help="Path to the script mapping google accounts.") |
| 870 parser.add_argument("-r", "--reviewer", default="", | 741 parser.add_argument("-r", "--reviewer", default="", |
| 871 help="The account name to be used for reviews.") | 742 help="The account name to be used for reviews.") |
| 872 parser.add_argument("--sheriff", default=False, action="store_true", | 743 parser.add_argument("--sheriff", default=False, action="store_true", |
| 873 help=("Determine current sheriff to review CLs. On " | 744 help=("Determine current sheriff to review CLs. On " |
| 874 "success, this will overwrite the reviewer " | 745 "success, this will overwrite the reviewer " |
| 875 "option.")) | 746 "option.")) |
| 876 parser.add_argument("--svn", | |
| 877 help=("Optional full svn checkout for the commit." | |
| 878 "The folder needs to be the svn root.")) | |
| 879 parser.add_argument("--svn-config", | |
| 880 help=("Optional folder used as svn --config-dir.")) | |
| 881 parser.add_argument("-s", "--step", | 747 parser.add_argument("-s", "--step", |
| 882 help="Specify the step where to start work. Default: 0.", | 748 help="Specify the step where to start work. Default: 0.", |
| 883 default=0, type=int) | 749 default=0, type=int) |
| 884 parser.add_argument("--vc-interface", | |
| 885 help=("Choose VC interface out of git_svn|" | |
| 886 "git_read_svn_write.")) | |
| 887 parser.add_argument("--work-dir", | 750 parser.add_argument("--work-dir", |
| 888 help=("Location where to bootstrap a working v8 " | 751 help=("Location where to bootstrap a working v8 " |
| 889 "checkout.")) | 752 "checkout.")) |
| 890 self._PrepareOptions(parser) | 753 self._PrepareOptions(parser) |
| 891 | 754 |
| 892 if args is None: # pragma: no cover | 755 if args is None: # pragma: no cover |
| 893 options = parser.parse_args() | 756 options = parser.parse_args() |
| 894 else: | 757 else: |
| 895 options = parser.parse_args(args) | 758 options = parser.parse_args(args) |
| 896 | 759 |
| 897 # Process common options. | 760 # Process common options. |
| 898 if options.step < 0: # pragma: no cover | 761 if options.step < 0: # pragma: no cover |
| 899 print "Bad step number %d" % options.step | 762 print "Bad step number %d" % options.step |
| 900 parser.print_help() | 763 parser.print_help() |
| 901 return None | 764 return None |
| 902 if options.sheriff and not options.googlers_mapping: # pragma: no cover | 765 if options.sheriff and not options.googlers_mapping: # pragma: no cover |
| 903 print "To determine the current sheriff, requires the googler mapping" | 766 print "To determine the current sheriff, requires the googler mapping" |
| 904 parser.print_help() | 767 parser.print_help() |
| 905 return None | 768 return None |
| 906 if options.svn and not options.svn_config: | |
| 907 print "Using pure svn for committing requires also --svn-config" | |
| 908 parser.print_help() | |
| 909 return None | |
| 910 | 769 |
| 911 # Defaults for options, common to all scripts. | 770 # Defaults for options, common to all scripts. |
| 912 options.manual = getattr(options, "manual", True) | 771 options.manual = getattr(options, "manual", True) |
| 913 options.force = getattr(options, "force", False) | 772 options.force = getattr(options, "force", False) |
| 914 options.bypass_upload_hooks = False | 773 options.bypass_upload_hooks = False |
| 915 | 774 |
| 916 # Derived options. | 775 # Derived options. |
| 917 options.requires_editor = not options.force | 776 options.requires_editor = not options.force |
| 918 options.wait_for_lgtm = not options.force | 777 options.wait_for_lgtm = not options.force |
| 919 options.force_readline_defaults = not options.manual | 778 options.force_readline_defaults = not options.manual |
| 920 options.force_upload = not options.manual | 779 options.force_upload = not options.manual |
| 921 | 780 |
| 922 # Process script specific options. | 781 # Process script specific options. |
| 923 if not self._ProcessOptions(options): | 782 if not self._ProcessOptions(options): |
| 924 parser.print_help() | 783 parser.print_help() |
| 925 return None | 784 return None |
| 926 | 785 |
| 927 if not options.vc_interface: | |
| 928 options.vc_interface = "git_read_svn_write" | |
| 929 if not options.work_dir: | 786 if not options.work_dir: |
| 930 options.work_dir = "/tmp/v8-release-scripts-work-dir" | 787 options.work_dir = "/tmp/v8-release-scripts-work-dir" |
| 931 return options | 788 return options |
| 932 | 789 |
| 933 def RunSteps(self, step_classes, args=None): | 790 def RunSteps(self, step_classes, args=None): |
| 934 options = self.MakeOptions(args) | 791 options = self.MakeOptions(args) |
| 935 if not options: | 792 if not options: |
| 936 return 1 | 793 return 1 |
| 937 | 794 |
| 938 state_file = "%s-state.json" % self._config["PERSISTFILE_BASENAME"] | 795 state_file = "%s-state.json" % self._config["PERSISTFILE_BASENAME"] |
| 939 if options.step == 0 and os.path.exists(state_file): | 796 if options.step == 0 and os.path.exists(state_file): |
| 940 os.remove(state_file) | 797 os.remove(state_file) |
| 941 | 798 |
| 942 steps = [] | 799 steps = [] |
| 943 for (number, step_class) in enumerate([BootstrapStep] + step_classes): | 800 for (number, step_class) in enumerate([BootstrapStep] + step_classes): |
| 944 steps.append(MakeStep(step_class, number, self._state, self._config, | 801 steps.append(MakeStep(step_class, number, self._state, self._config, |
| 945 options, self._side_effect_handler)) | 802 options, self._side_effect_handler)) |
| 946 for step in steps[options.step:]: | 803 for step in steps[options.step:]: |
| 947 if step.Run(): | 804 if step.Run(): |
| 948 return 0 | 805 return 0 |
| 949 return 0 | 806 return 0 |
| 950 | 807 |
| 951 def Run(self, args=None): | 808 def Run(self, args=None): |
| 952 return self.RunSteps(self._Steps(), args) | 809 return self.RunSteps(self._Steps(), args) |
| OLD | NEW |