| 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 20 matching lines...) Expand all Loading... |
| 31 import sys | 31 import sys |
| 32 | 32 |
| 33 from common_includes import * | 33 from common_includes import * |
| 34 | 34 |
| 35 CONFIG = { | 35 CONFIG = { |
| 36 PERSISTFILE_BASENAME: "/tmp/v8-auto-roll-tempfile", | 36 PERSISTFILE_BASENAME: "/tmp/v8-auto-roll-tempfile", |
| 37 DOT_GIT_LOCATION: ".git", | 37 DOT_GIT_LOCATION: ".git", |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 class AutoRollOptions(CommonOptions): |
| 42 def __init__(self, options): |
| 43 super(AutoRollOptions, self).__init__(options) |
| 44 self.requires_editor = False |
| 45 |
| 46 |
| 41 class Preparation(Step): | 47 class Preparation(Step): |
| 42 MESSAGE = "Preparation." | 48 MESSAGE = "Preparation." |
| 43 | 49 |
| 44 def RunStep(self): | 50 def RunStep(self): |
| 45 self.InitialEnvironmentChecks() | 51 self.InitialEnvironmentChecks() |
| 46 self.CommonPrepare() | 52 self.CommonPrepare() |
| 47 | 53 |
| 48 | 54 |
| 49 class FetchLatestRevision(Step): | 55 class FetchLatestRevision(Step): |
| 50 MESSAGE = "Fetching latest V8 revision." | 56 MESSAGE = "Fetching latest V8 revision." |
| 51 | 57 |
| 52 def RunStep(self): | 58 def RunStep(self): |
| 53 log = self.Git("svn log -1 --oneline").strip() | 59 log = self.Git("svn log -1 --oneline").strip() |
| 54 match = re.match(r"^r(\d+) ", log) | 60 match = re.match(r"^r(\d+) ", log) |
| 55 if not match: | 61 if not match: |
| 56 self.Die("Could not extract current svn revision from log.") | 62 self.Die("Could not extract current svn revision from log.") |
| 57 self.Persist("latest", match.group(1)) | 63 self.Persist("latest", match.group(1)) |
| 58 | 64 |
| 59 | 65 |
| 66 class CheckLastPush(Step): |
| 67 MESSAGE = "Checking last V8 push to trunk." |
| 68 |
| 69 def RunStep(self): |
| 70 self.RestoreIfUnset("latest") |
| 71 log = self.Git("svn log -1 --oneline ChangeLog").strip() |
| 72 match = re.match(r"^r(\d+) \| Prepare push to trunk", log) |
| 73 if match: |
| 74 latest = int(self._state["latest"]) |
| 75 last_push = int(match.group(1)) |
| 76 # TODO(machebach): This metric counts all revisions. It could be |
| 77 # improved by counting only the revisions on bleeding_edge. |
| 78 if latest - last_push < 10: |
| 79 # This makes sure the script doesn't push twice in a row when the cron |
| 80 # job retries several times. |
| 81 self.Die("Last push too recently: %d" % last_push) |
| 82 |
| 83 |
| 60 class FetchLKGR(Step): | 84 class FetchLKGR(Step): |
| 61 MESSAGE = "Fetching V8 LKGR." | 85 MESSAGE = "Fetching V8 LKGR." |
| 62 | 86 |
| 63 def RunStep(self): | 87 def RunStep(self): |
| 64 lkgr_url = "https://v8-status.appspot.com/lkgr" | 88 lkgr_url = "https://v8-status.appspot.com/lkgr" |
| 65 # Retry several times since app engine might have issues. | 89 # Retry several times since app engine might have issues. |
| 66 self.Persist("lkgr", self.ReadURL(lkgr_url, wait_plan=[5, 20, 300, 300])) | 90 self.Persist("lkgr", self.ReadURL(lkgr_url, wait_plan=[5, 20, 300, 300])) |
| 67 | 91 |
| 68 | 92 |
| 69 class PushToTrunk(Step): | 93 class PushToTrunk(Step): |
| 70 MESSAGE = "Pushing to trunk if possible." | 94 MESSAGE = "Pushing to trunk if possible." |
| 71 | 95 |
| 72 def RunStep(self): | 96 def RunStep(self): |
| 73 self.RestoreIfUnset("latest") | 97 self.RestoreIfUnset("latest") |
| 74 self.RestoreIfUnset("lkgr") | 98 self.RestoreIfUnset("lkgr") |
| 75 latest = int(self._state["latest"]) | 99 latest = int(self._state["latest"]) |
| 76 lkgr = int(self._state["lkgr"]) | 100 lkgr = int(self._state["lkgr"]) |
| 77 if latest == lkgr: | 101 if latest == lkgr: |
| 78 print "ToT (r%d) is clean. Pushing to trunk." % latest | 102 print "ToT (r%d) is clean. Pushing to trunk." % latest |
| 79 # TODO(machenbach): Call push to trunk script. | 103 # TODO(machenbach): Call push to trunk script. |
| 104 # TODO(machenbach): Update the script before calling it. |
| 105 # self._side_effect_handler.Command( |
| 106 # "tools/push-to-trunk/push-to-trunk.py", |
| 107 # "-f -c %s -r %s" % (self._options.c, self._options.r)) |
| 80 else: | 108 else: |
| 81 print("ToT (r%d) is ahead of the LKGR (r%d). Skipping push to trunk." | 109 print("ToT (r%d) is ahead of the LKGR (r%d). Skipping push to trunk." |
| 82 % (latest, lkgr)) | 110 % (latest, lkgr)) |
| 83 | 111 |
| 84 | 112 |
| 85 def RunAutoRoll(config, | 113 def RunAutoRoll(config, |
| 86 options, | 114 options, |
| 87 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): | 115 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): |
| 88 step_classes = [ | 116 step_classes = [ |
| 89 Preparation, | 117 Preparation, |
| 90 FetchLatestRevision, | 118 FetchLatestRevision, |
| 119 CheckLastPush, |
| 91 FetchLKGR, | 120 FetchLKGR, |
| 92 PushToTrunk, | 121 PushToTrunk, |
| 93 ] | 122 ] |
| 94 RunScript(step_classes, config, options, side_effect_handler) | 123 RunScript(step_classes, config, options, side_effect_handler) |
| 95 | 124 |
| 96 | 125 |
| 97 def BuildOptions(): | 126 def BuildOptions(): |
| 98 result = optparse.OptionParser() | 127 result = optparse.OptionParser() |
| 99 result.add_option("-f", "--force", dest="f", | 128 result.add_option("-c", "--chromium", dest="c", |
| 100 help="Don't prompt the user.", | 129 help=("Specify the path to your Chromium src/ " |
| 101 default=True, action="store_true") | 130 "directory to automate the V8 roll.")) |
| 131 result.add_option("-r", "--reviewer", dest="r", |
| 132 help=("Specify the account name to be used for reviews.")) |
| 102 result.add_option("-s", "--step", dest="s", | 133 result.add_option("-s", "--step", dest="s", |
| 103 help="Specify the step where to start work. Default: 0.", | 134 help="Specify the step where to start work. Default: 0.", |
| 104 default=0, type="int") | 135 default=0, type="int") |
| 105 return result | 136 return result |
| 106 | 137 |
| 107 | 138 |
| 108 def Main(): | 139 def Main(): |
| 109 parser = BuildOptions() | 140 parser = BuildOptions() |
| 110 (options, args) = parser.parse_args() | 141 (options, args) = parser.parse_args() |
| 111 RunAutoRoll(CONFIG, options) | 142 if not options.c or not options.r: |
| 143 print "You need to specify the chromium src location and a reviewer." |
| 144 parser.print_help() |
| 145 return 1 |
| 146 RunAutoRoll(CONFIG, AutoRollOptions(options)) |
| 112 | 147 |
| 113 if __name__ == "__main__": | 148 if __name__ == "__main__": |
| 114 sys.exit(Main()) | 149 sys.exit(Main()) |
| OLD | NEW |