| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import argparse | 6 import argparse |
| 7 import collections | 7 import collections |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import re | 10 import re |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 status_to_name = {} | 147 status_to_name = {} |
| 148 for trybot_result in tryjob_results: | 148 for trybot_result in tryjob_results: |
| 149 status = TRYJOB_STATUS.get(trybot_result['result'], 'UNKNOWN') | 149 status = TRYJOB_STATUS.get(trybot_result['result'], 'UNKNOWN') |
| 150 status_to_name.setdefault(status, []) | 150 status_to_name.setdefault(status, []) |
| 151 status_to_name[status].append(trybot_result['builder']) | 151 status_to_name[status].append(trybot_result['builder']) |
| 152 | 152 |
| 153 print '\n========== TRYJOBS STATUS ==========' | 153 print '\n========== TRYJOBS STATUS ==========' |
| 154 for status,name_list in status_to_name.iteritems(): | 154 for status,name_list in status_to_name.iteritems(): |
| 155 print '%s: %s' % (status, ','.join(sorted(name_list))) | 155 print '%s: %s' % (status, ','.join(sorted(name_list))) |
| 156 | 156 |
| 157 | |
| 158 def _GenerateCLDescriptionCommand(webrtc_current, webrtc_new): | |
| 159 def GetChangeLogURL(git_repo_url, current_hash, new_hash): | |
| 160 return '%s/+log/%s..%s' % (git_repo_url, current_hash[0:7], new_hash[0:7]) | |
| 161 | |
| 162 webrtc_str = 'WebRTC %s:%s' % (webrtc_current.commit_position, | |
| 163 webrtc_new.commit_position) | |
| 164 webrtc_changelog_url = GetChangeLogURL(webrtc_current.git_repo_url, | |
| 165 webrtc_current.git_commit, | |
| 166 webrtc_new.git_commit) | |
| 167 | |
| 168 description = [ '-m', 'Roll ' + webrtc_str ] | |
| 169 description.extend(['-m', 'Changes: %s' % webrtc_changelog_url]) | |
| 170 description.extend(['-m', 'TBR=']) | |
| 171 description.extend(['-m', 'CQ_INCLUDE_TRYBOTS=%s' % EXTRA_TRYBOTS]) | |
| 172 return description | |
| 173 | |
| 174 | |
| 175 class AutoRoller(object): | 157 class AutoRoller(object): |
| 176 def __init__(self, chromium_src): | 158 def __init__(self, chromium_src): |
| 177 self._chromium_src = chromium_src | 159 self._chromium_src = chromium_src |
| 178 | 160 |
| 179 def _RunCommand(self, command, working_dir=None, ignore_exit_code=False, | 161 def _RunCommand(self, command, working_dir=None, ignore_exit_code=False, |
| 180 extra_env=None): | 162 extra_env=None): |
| 181 """Runs a command and returns the stdout from that command. | 163 """Runs a command and returns the stdout from that command. |
| 182 | 164 |
| 183 If the command fails (exit code != 0), the function will exit the process. | 165 If the command fails (exit code != 0), the function will exit the process. |
| 184 """ | 166 """ |
| 185 working_dir = working_dir or self._chromium_src | 167 working_dir = working_dir or self._chromium_src |
| 186 logging.debug('cmd: %s cwd: %s', ' '.join(command), working_dir) | 168 logging.debug('cmd: %s cwd: %s', ' '.join(command), working_dir) |
| 187 env = os.environ.copy() | 169 env = os.environ.copy() |
| 188 if extra_env: | 170 if extra_env: |
| 189 logging.debug('extra env: %s', extra_env) | 171 logging.debug('extra env: %s', extra_env) |
| 190 env.update(extra_env) | 172 env.update(extra_env) |
| 191 p = subprocess.Popen(command, stdout=subprocess.PIPE, | 173 p = subprocess.Popen(command, stdout=subprocess.PIPE, |
| 192 stderr=subprocess.PIPE, shell=IS_WIN, env=env, | 174 stderr=subprocess.PIPE, shell=IS_WIN, env=env, |
| 193 cwd=working_dir, universal_newlines=True) | 175 cwd=working_dir, universal_newlines=True) |
| 194 output = p.stdout.read() | 176 output = p.stdout.read() |
| 195 p.wait() | 177 p.wait() |
| 196 p.stdout.close() | 178 p.stdout.close() |
| 197 p.stderr.close() | 179 p.stderr.close() |
| 198 | 180 |
| 199 if not ignore_exit_code and p.returncode != 0: | 181 if not ignore_exit_code and p.returncode != 0: |
| 200 logging.error('Command failed: %s\n%s', str(command), output) | 182 logging.error('Command failed: %s\n%s', str(command), output) |
| 201 sys.exit(p.returncode) | 183 sys.exit(p.returncode) |
| 202 return output | 184 return output |
| 203 | 185 |
| 186 def _GenerateCLDescriptionCommand(self, webrtc_current, webrtc_new): |
| 187 commit_range = '%s..%s' % (webrtc_current.git_commit[:7], |
| 188 webrtc_new.git_commit[:7]) |
| 189 |
| 190 webrtc_changelog_url = '%s/+log/%s' % (webrtc_current.git_repo_url, |
| 191 commit_range) |
| 192 |
| 193 git_log_cmd = ['git', 'log', commit_range, '--date=short', '--no-merges', |
| 194 '--format=%ad %ae %s'] |
| 195 |
| 196 working_dir = os.path.join(self._chromium_src, WEBRTC_PATH) |
| 197 git_log = self._RunCommand(git_log_cmd, working_dir=working_dir) |
| 198 |
| 199 nb_commits = git_log.count('\n') |
| 200 webrtc_header = 'Roll WebRTC %s:%s (%d commit%s)' % ( |
| 201 webrtc_current.commit_position, webrtc_new.commit_position, |
| 202 nb_commits, 's' if nb_commits > 1 else '') |
| 203 |
| 204 description = ('%s\n\n' |
| 205 'Changes: %s\n\n' |
| 206 '$ %s\n' |
| 207 '%s\n' |
| 208 'TBR=\n' |
| 209 'CQ_INCLUDE_TRYBOTS=%s\n') % ( |
| 210 webrtc_header, |
| 211 webrtc_changelog_url, |
| 212 ' '.join(git_log_cmd), |
| 213 git_log, |
| 214 EXTRA_TRYBOTS) |
| 215 |
| 216 return description |
| 217 |
| 204 def _GetCommitInfo(self, path_below_src, git_hash=None, git_repo_url=None): | 218 def _GetCommitInfo(self, path_below_src, git_hash=None, git_repo_url=None): |
| 205 working_dir = os.path.join(self._chromium_src, path_below_src) | 219 working_dir = os.path.join(self._chromium_src, path_below_src) |
| 206 self._RunCommand(['git', 'fetch', 'origin'], working_dir=working_dir) | 220 self._RunCommand(['git', 'fetch', 'origin'], working_dir=working_dir) |
| 207 revision_range = git_hash or 'origin' | 221 revision_range = git_hash or 'origin' |
| 208 ret = self._RunCommand( | 222 ret = self._RunCommand( |
| 209 ['git', '--no-pager', 'log', revision_range, '--pretty=full', '-1'], | 223 ['git', '--no-pager', 'log', revision_range, '--pretty=full', '-1'], |
| 210 working_dir=working_dir) | 224 working_dir=working_dir) |
| 211 return CommitInfo(_ParseGitCommitPosition(ret), _ParseGitCommitHash(ret), | 225 return CommitInfo(_ParseGitCommitPosition(ret), _ParseGitCommitHash(ret), |
| 212 git_repo_url) | 226 git_repo_url) |
| 213 | 227 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 if IS_WIN: | 305 if IS_WIN: |
| 292 # Make sure the roll script doesn't use Windows line endings. | 306 # Make sure the roll script doesn't use Windows line endings. |
| 293 self._RunCommand(['git', 'config', 'core.autocrlf', 'true']) | 307 self._RunCommand(['git', 'config', 'core.autocrlf', 'true']) |
| 294 | 308 |
| 295 self._UpdateDep(deps_filename, WEBRTC_PATH, webrtc_latest) | 309 self._UpdateDep(deps_filename, WEBRTC_PATH, webrtc_latest) |
| 296 | 310 |
| 297 if self._IsTreeClean(): | 311 if self._IsTreeClean(): |
| 298 print 'The latest revision is already rolled for WebRTC.' | 312 print 'The latest revision is already rolled for WebRTC.' |
| 299 self._DeleteRollBranch() | 313 self._DeleteRollBranch() |
| 300 else: | 314 else: |
| 301 description = _GenerateCLDescriptionCommand( | 315 description = self._GenerateCLDescriptionCommand( |
| 302 webrtc_current, webrtc_latest) | 316 webrtc_current, webrtc_latest) |
| 303 logging.debug('Committing changes locally.') | 317 logging.debug('Committing changes locally.') |
| 304 self._RunCommand(['git', 'add', '--update', '.']) | 318 self._RunCommand(['git', 'add', '--update', '.']) |
| 305 self._RunCommand(['git', 'commit'] + description) | 319 self._RunCommand(['git', 'commit', '-m', description]) |
| 306 logging.debug('Uploading changes...') | 320 logging.debug('Uploading changes...') |
| 307 self._RunCommand(['git', 'cl', 'upload'], | 321 self._RunCommand(['git', 'cl', 'upload'], |
| 308 extra_env={'EDITOR': 'true'}) | 322 extra_env={'EDITOR': 'true'}) |
| 309 cl_info = self._GetCLInfo() | 323 cl_info = self._GetCLInfo() |
| 310 logging.debug('Issue: %d URL: %s', cl_info.issue, cl_info.url) | 324 logging.debug('Issue: %d URL: %s', cl_info.issue, cl_info.url) |
| 311 | 325 |
| 312 if not dry_run and not no_commit: | 326 if not dry_run and not no_commit: |
| 313 logging.debug('Sending the CL to the CQ...') | 327 logging.debug('Sending the CL to the CQ...') |
| 314 self._RunCommand(['git', 'cl', 'set_commit']) | 328 self._RunCommand(['git', 'cl', 'set_commit']) |
| 315 logging.debug('Sent the CL to the CQ. Monitor here: %s', cl_info.url) | 329 logging.debug('Sent the CL to the CQ. Monitor here: %s', cl_info.url) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 if args.abort: | 428 if args.abort: |
| 415 return autoroller.Abort() | 429 return autoroller.Abort() |
| 416 elif args.wait_for_trybots: | 430 elif args.wait_for_trybots: |
| 417 return autoroller.WaitForTrybots() | 431 return autoroller.WaitForTrybots() |
| 418 else: | 432 else: |
| 419 return autoroller.PrepareRoll(args.dry_run, args.ignore_checks, | 433 return autoroller.PrepareRoll(args.dry_run, args.ignore_checks, |
| 420 args.no_commit, args.close_previous_roll) | 434 args.no_commit, args.close_previous_roll) |
| 421 | 435 |
| 422 if __name__ == '__main__': | 436 if __name__ == '__main__': |
| 423 sys.exit(main()) | 437 sys.exit(main()) |
| OLD | NEW |