Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 # Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 # | 3 # |
| 4 # Use of this source code is governed by a BSD-style license | 4 # Use of this source code is governed by a BSD-style license |
| 5 # that can be found in the LICENSE file in the root of the source | 5 # that can be found in the LICENSE file in the root of the source |
| 6 # tree. An additional intellectual property rights grant can be found | 6 # tree. An additional intellectual property rights grant can be found |
| 7 # in the file PATENTS. All contributing project authors may | 7 # in the file PATENTS. All contributing project authors may |
| 8 # be found in the AUTHORS file in the root of the source tree. | 8 # be found in the AUTHORS file in the root of the source tree. |
| 9 | 9 |
| 10 """Script to roll chromium_revision in the WebRTC DEPS file.""" | 10 """Script to roll chromium_revision in the WebRTC DEPS file.""" |
| 11 | 11 |
| 12 import argparse | 12 import argparse |
| 13 import base64 | 13 import base64 |
| 14 import collections | 14 import collections |
| 15 import logging | 15 import logging |
| 16 import os | 16 import os |
| 17 import re | 17 import re |
| 18 import subprocess | 18 import subprocess |
| 19 import sys | 19 import sys |
| 20 import urllib | 20 import urllib |
| 21 | 21 |
| 22 | 22 |
| 23 CHROMIUM_LKGR_URL = 'https://chromium-status.appspot.com/lkgr' | 23 CHROMIUM_LKGR_URL = 'https://chromium-status.appspot.com/lkgr' |
| 24 CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src' | 24 CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src' |
| 25 CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s' | 25 CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s' |
| 26 CHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s' | |
| 26 CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s' | 27 CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s' |
| 27 | 28 |
| 28 COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$') | 29 COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$') |
| 29 CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION=(\d+)$') | 30 CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION=(\d+)$') |
| 30 ROLL_BRANCH_NAME = 'roll_chromium_revision' | 31 ROLL_BRANCH_NAME = 'roll_chromium_revision' |
| 31 | 32 |
| 32 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | 33 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 33 CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, os.pardir, | 34 CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(SCRIPT_DIR, os.pardir, |
| 34 os.pardir)) | 35 os.pardir)) |
| 35 sys.path.append(CHECKOUT_ROOT_DIR) | 36 sys.path.append(CHECKOUT_ROOT_DIR) |
| 36 import setup_links | 37 import setup_links |
| 37 | 38 |
| 38 sys.path.append(os.path.join(CHECKOUT_ROOT_DIR, 'tools')) | 39 sys.path.append(os.path.join(CHECKOUT_ROOT_DIR, 'tools')) |
| 39 import find_depot_tools | 40 import find_depot_tools |
| 40 find_depot_tools.add_depot_tools_to_path() | 41 find_depot_tools.add_depot_tools_to_path() |
| 41 from gclient import GClientKeywords | 42 from gclient import GClientKeywords |
| 42 | 43 |
| 43 CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.sh' | 44 CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.sh' |
| 44 CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join('tools', 'clang', 'scripts', | 45 CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join('tools', 'clang', 'scripts', |
| 45 'update.sh') | 46 'update.sh') |
| 46 | 47 |
| 47 DepsEntry = collections.namedtuple('DepsEntry', 'path url revision') | 48 DepsEntry = collections.namedtuple('DepsEntry', 'path url revision') |
| 48 ChangedDep = collections.namedtuple('ChangedDep', 'path current_rev new_rev') | 49 ChangedDep = collections.namedtuple('ChangedDep', |
| 50 'path url current_rev new_rev') | |
| 49 | 51 |
| 50 | 52 |
| 51 def ParseDepsDict(deps_content): | 53 def ParseDepsDict(deps_content): |
| 52 local_scope = {} | 54 local_scope = {} |
| 53 var = GClientKeywords.VarImpl({}, local_scope) | 55 var = GClientKeywords.VarImpl({}, local_scope) |
| 54 global_scope = { | 56 global_scope = { |
| 55 'File': GClientKeywords.FileImpl, | 57 'File': GClientKeywords.FileImpl, |
| 56 'From': GClientKeywords.FromImpl, | 58 'From': GClientKeywords.FromImpl, |
| 57 'Var': var.Lookup, | 59 'Var': var.Lookup, |
| 58 'deps_os': {}, | 60 'deps_os': {}, |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 213 for deps_dir in all_deps_dirs: | 215 for deps_dir in all_deps_dirs: |
| 214 # All deps have 'src' prepended to the path in the Chromium DEPS file. | 216 # All deps have 'src' prepended to the path in the Chromium DEPS file. |
| 215 dir_path = 'src/%s' % deps_dir | 217 dir_path = 'src/%s' % deps_dir |
| 216 | 218 |
| 217 for entry in GetMatchingDepsEntries(current_entries, dir_path): | 219 for entry in GetMatchingDepsEntries(current_entries, dir_path): |
| 218 new_matching_entries = GetMatchingDepsEntries(new_entries, entry.path) | 220 new_matching_entries = GetMatchingDepsEntries(new_entries, entry.path) |
| 219 assert len(new_matching_entries) <= 1, ( | 221 assert len(new_matching_entries) <= 1, ( |
| 220 'Should never find more than one entry matching %s in %s, found %d' % | 222 'Should never find more than one entry matching %s in %s, found %d' % |
| 221 (entry.path, new_entries, len(new_matching_entries))) | 223 (entry.path, new_entries, len(new_matching_entries))) |
| 222 if not new_matching_entries: | 224 if not new_matching_entries: |
| 223 result.append(ChangedDep(entry.path, entry.revision, 'None')) | 225 result.append(ChangedDep(entry.path, entry.url, entry.revision, 'None')) |
| 224 elif entry != new_matching_entries[0]: | 226 elif entry != new_matching_entries[0]: |
| 225 result.append(ChangedDep(entry.path, entry.revision, | 227 result.append(ChangedDep(entry.path, entry.url, entry.revision, |
| 226 new_matching_entries[0].revision)) | 228 new_matching_entries[0].revision)) |
| 227 return result | 229 return result |
| 228 | 230 |
| 229 | 231 |
| 230 def CalculateChangedClang(new_cr_rev): | 232 def CalculateChangedClang(new_cr_rev): |
| 231 def GetClangRev(lines): | 233 def GetClangRev(lines): |
| 232 for line in lines: | 234 for line in lines: |
| 233 match = CLANG_REVISION_RE.match(line) | 235 match = CLANG_REVISION_RE.match(line) |
| 234 if match: | 236 if match: |
| 235 return match.group(1) | 237 return match.group(1) |
| 236 return None | 238 return None |
| 237 | 239 |
| 238 chromium_src_path = os.path.join(CHECKOUT_ROOT_DIR, 'chromium', 'src', | 240 chromium_src_path = os.path.join(CHECKOUT_ROOT_DIR, 'chromium', 'src', |
| 239 CLANG_UPDATE_SCRIPT_LOCAL_PATH) | 241 CLANG_UPDATE_SCRIPT_LOCAL_PATH) |
| 240 with open(chromium_src_path, 'rb') as f: | 242 with open(chromium_src_path, 'rb') as f: |
| 241 current_lines = f.readlines() | 243 current_lines = f.readlines() |
| 242 current_rev = GetClangRev(current_lines) | 244 current_rev = GetClangRev(current_lines) |
| 243 | 245 |
| 244 new_clang_update_sh = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH, | 246 new_clang_update_sh = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH, |
| 245 new_cr_rev).splitlines() | 247 new_cr_rev).splitlines() |
| 246 new_rev = GetClangRev(new_clang_update_sh) | 248 new_rev = GetClangRev(new_clang_update_sh) |
| 247 return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, current_rev, new_rev) | 249 return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, current_rev, new_rev) |
| 248 | 250 |
| 249 | 251 |
| 250 def GenerateCommitMessage(current_cr_rev, new_cr_rev, changed_deps_list, | 252 def GenerateCommitMessage(current_cr_rev, new_cr_rev, current_git_number, |
| 251 clang_change): | 253 new_git_number, changed_deps_list, clang_change): |
| 252 current_cr_rev = current_cr_rev[0:7] | 254 current_cr_rev = current_cr_rev[0:7] |
| 253 new_cr_rev = new_cr_rev[0:7] | 255 new_cr_rev = new_cr_rev[0:7] |
| 254 rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev) | 256 rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev) |
| 255 | |
| 256 current_git_number = ParseCommitPosition(ReadRemoteCrCommit(current_cr_rev)) | |
| 257 new_git_number = ParseCommitPosition(ReadRemoteCrCommit(new_cr_rev)) | |
| 258 git_number_interval = '%s:%s' % (current_git_number, new_git_number) | 257 git_number_interval = '%s:%s' % (current_git_number, new_git_number) |
| 259 | 258 |
| 260 commit_msg = ['Roll chromium_revision %s (%s)' % (rev_interval, | 259 commit_msg = ['Roll chromium_revision %s (%s)\n' % (rev_interval, |
| 261 git_number_interval)] | 260 git_number_interval)] |
| 262 | 261 commit_msg.append('Change log: %s' % (CHROMIUM_LOG_TEMPLATE % rev_interval)) |
| 262 commit_msg.append('Full diff: %s\n' % (CHROMIUM_COMMIT_TEMPLATE % | |
| 263 rev_interval)) | |
| 263 if changed_deps_list: | 264 if changed_deps_list: |
| 264 commit_msg.append('\nRelevant changes:') | 265 commit_msg.append('Changed dependencies:') |
| 265 | 266 |
| 266 for c in changed_deps_list: | 267 for c in changed_deps_list: |
| 267 commit_msg.append('* %s: %s..%s' % (c.path, c.current_rev[0:7], | 268 commit_msg.append('* %s: %s/+log/%s..%s' % (c.path, c.url, |
| 268 c.new_rev[0:7])) | 269 c.current_rev[0:7], |
| 269 | 270 c.new_rev[0:7])) |
| 270 change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS') | 271 change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS') |
| 271 commit_msg.append('Details: %s' % change_url) | 272 commit_msg.append('DEPS diff: %s\n' % change_url) |
| 273 else: | |
| 274 commit_msg.append('No dependencies changed.') | |
| 272 | 275 |
| 273 if clang_change.current_rev != clang_change.new_rev: | 276 if clang_change.current_rev != clang_change.new_rev: |
| 274 commit_msg.append('\nClang version changed %s:%s' % | 277 commit_msg.append('Clang version changed %s:%s' % |
| 275 (clang_change.current_rev, clang_change.new_rev)) | 278 (clang_change.current_rev, clang_change.new_rev)) |
| 276 change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, | 279 change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, |
| 277 CLANG_UPDATE_SCRIPT_URL_PATH) | 280 CLANG_UPDATE_SCRIPT_URL_PATH) |
| 278 commit_msg.append('Details: %s' % change_url) | 281 commit_msg.append('Details: %s' % change_url) |
| 279 else: | 282 else: |
| 280 commit_msg.append('\nClang version was not updated in this roll.') | 283 commit_msg.append('No update to Clang.') |
| 281 return '\n'.join(commit_msg) | 284 return '\n'.join(commit_msg) |
| 282 | 285 |
| 283 | 286 |
| 284 def UpdateDeps(deps_filename, old_cr_revision, new_cr_revision): | 287 def UpdateDeps(deps_filename, old_cr_revision, new_cr_revision): |
| 285 """Update the DEPS file with the new revision.""" | 288 """Update the DEPS file with the new revision.""" |
| 286 with open(deps_filename, 'rb') as deps_file: | 289 with open(deps_filename, 'rb') as deps_file: |
| 287 deps_content = deps_file.read() | 290 deps_content = deps_file.read() |
| 288 deps_content = deps_content.replace(old_cr_revision, new_cr_revision) | 291 deps_content = deps_content.replace(old_cr_revision, new_cr_revision) |
| 289 with open(deps_filename, 'wb') as deps_file: | 292 with open(deps_filename, 'wb') as deps_file: |
| 290 deps_file.write(deps_content) | 293 deps_file.write(deps_content) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 p = argparse.ArgumentParser() | 354 p = argparse.ArgumentParser() |
| 352 p.add_argument('--clean', action='store_true', default=False, | 355 p.add_argument('--clean', action='store_true', default=False, |
| 353 help='Removes any previous local roll branch.') | 356 help='Removes any previous local roll branch.') |
| 354 p.add_argument('-r', '--revision', | 357 p.add_argument('-r', '--revision', |
| 355 help=('Chromium Git revision to roll to. Defaults to the ' | 358 help=('Chromium Git revision to roll to. Defaults to the ' |
| 356 'Chromium LKGR revision if omitted.')) | 359 'Chromium LKGR revision if omitted.')) |
| 357 p.add_argument('--dry-run', action='store_true', default=False, | 360 p.add_argument('--dry-run', action='store_true', default=False, |
| 358 help=('Calculate changes and modify DEPS, but don\'t create ' | 361 help=('Calculate changes and modify DEPS, but don\'t create ' |
| 359 'any local branch, commit, upload CL or send any ' | 362 'any local branch, commit, upload CL or send any ' |
| 360 'tryjobs.')) | 363 'tryjobs.')) |
| 364 p.add_argument('--allow-reverse', action='store_true', default=False, | |
| 365 help=('Allow rolling back in time (disabled by default but ' | |
| 366 'may be useful to be able do to manually).')) | |
| 361 p.add_argument('-s', '--skip-try', action='store_true', default=False, | 367 p.add_argument('-s', '--skip-try', action='store_true', default=False, |
| 362 help='Do everything except sending tryjobs.') | 368 help='Do everything except sending tryjobs.') |
| 363 p.add_argument('-v', '--verbose', action='store_true', default=False, | 369 p.add_argument('-v', '--verbose', action='store_true', default=False, |
| 364 help='Be extra verbose in printing of log messages.') | 370 help='Be extra verbose in printing of log messages.') |
| 365 opts = p.parse_args() | 371 opts = p.parse_args() |
| 366 | 372 |
| 367 if opts.verbose: | 373 if opts.verbose: |
| 368 logging.basicConfig(level=logging.DEBUG) | 374 logging.basicConfig(level=logging.DEBUG) |
| 369 else: | 375 else: |
| 370 logging.basicConfig(level=logging.INFO) | 376 logging.basicConfig(level=logging.INFO) |
| 371 | 377 |
| 372 if not _IsTreeClean(): | 378 if not _IsTreeClean(): |
| 373 logging.error('Please clean your local checkout first.') | 379 logging.error('Please clean your local checkout first.') |
| 374 return 1 | 380 return 1 |
| 375 | 381 |
| 376 if opts.clean: | 382 if opts.clean: |
| 377 _RemovePreviousRollBranch(opts.dry_run) | 383 _RemovePreviousRollBranch(opts.dry_run) |
| 378 | 384 |
| 379 _EnsureUpdatedMasterBranch(opts.dry_run) | 385 _EnsureUpdatedMasterBranch(opts.dry_run) |
| 380 | 386 |
| 381 if not opts.revision: | 387 new_cr_rev = opts.revision |
| 388 if not new_cr_rev: | |
| 382 lkgr_contents = ReadUrlContent(CHROMIUM_LKGR_URL) | 389 lkgr_contents = ReadUrlContent(CHROMIUM_LKGR_URL) |
| 383 logging.info('No revision specified. Using LKGR: %s', lkgr_contents[0]) | 390 logging.info('No revision specified. Using LKGR: %s', lkgr_contents[0]) |
| 384 opts.revision = lkgr_contents[0] | 391 new_cr_rev = lkgr_contents[0] |
| 385 | 392 |
| 386 deps_filename = os.path.join(CHECKOUT_ROOT_DIR, 'DEPS') | 393 deps_filename = os.path.join(CHECKOUT_ROOT_DIR, 'DEPS') |
| 387 local_deps = ParseLocalDepsFile(deps_filename) | 394 local_deps = ParseLocalDepsFile(deps_filename) |
| 388 current_cr_rev = local_deps['vars']['chromium_revision'] | 395 current_cr_rev = local_deps['vars']['chromium_revision'] |
| 389 | 396 |
| 397 current_git_number = ParseCommitPosition(ReadRemoteCrCommit(current_cr_rev)) | |
|
phoglund
2015/10/02 06:53:42
Nit: current_git_pos or current_commit_pos? That i
kjellander_webrtc
2015/10/02 07:10:36
Good idea, I incorporated it in PS#3.
| |
| 398 new_git_number = ParseCommitPosition(ReadRemoteCrCommit(new_cr_rev)) | |
|
phoglund
2015/10/02 06:53:42
Ditto
kjellander_webrtc
2015/10/02 07:10:36
Done.
| |
| 399 | |
| 390 current_cr_deps = ParseRemoteCrDepsFile(current_cr_rev) | 400 current_cr_deps = ParseRemoteCrDepsFile(current_cr_rev) |
| 391 new_cr_deps = ParseRemoteCrDepsFile(opts.revision) | 401 new_cr_deps = ParseRemoteCrDepsFile(new_cr_rev) |
| 392 | 402 |
| 393 changed_deps = sorted(CalculateChangedDeps(current_cr_deps, new_cr_deps)) | 403 if new_git_number > current_git_number or opts.allow_reverse: |
| 394 clang_change = CalculateChangedClang(opts.revision) | 404 changed_deps = sorted(CalculateChangedDeps(current_cr_deps, new_cr_deps)) |
| 395 if changed_deps or clang_change: | 405 clang_change = CalculateChangedClang(new_cr_rev) |
| 396 commit_msg = GenerateCommitMessage(current_cr_rev, opts.revision, | 406 commit_msg = GenerateCommitMessage(current_cr_rev, new_cr_rev, |
| 407 current_git_number, new_git_number, | |
| 397 changed_deps, clang_change) | 408 changed_deps, clang_change) |
| 398 logging.debug('Commit message:\n%s', commit_msg) | 409 logging.debug('Commit message:\n%s', commit_msg) |
| 399 else: | 410 else: |
| 400 logging.info('No deps changes detected when rolling from %s to %s. ' | 411 logging.info('Currently pinned chromium_revision: %s (#%s) is newer than ' |
| 401 'Aborting without action.', current_cr_rev, opts.revision) | 412 '%s (#%s). To roll to older revisions, you must pass the ' |
| 413 '--allow-reverse flag.\n' | |
| 414 'Aborting without action.', current_cr_rev, current_git_number, | |
| 415 new_cr_rev, new_git_number) | |
| 402 return 0 | 416 return 0 |
| 403 | 417 |
| 404 _CreateRollBranch(opts.dry_run) | 418 _CreateRollBranch(opts.dry_run) |
| 405 UpdateDeps(deps_filename, current_cr_rev, opts.revision) | 419 UpdateDeps(deps_filename, current_cr_rev, new_cr_rev) |
| 406 _LocalCommit(commit_msg, opts.dry_run) | 420 _LocalCommit(commit_msg, opts.dry_run) |
| 407 _UploadCL(opts.dry_run) | 421 _UploadCL(opts.dry_run) |
| 408 _LaunchTrybots(opts.dry_run, opts.skip_try) | 422 _LaunchTrybots(opts.dry_run, opts.skip_try) |
| 409 return 0 | 423 return 0 |
| 410 | 424 |
| 411 | 425 |
| 412 if __name__ == '__main__': | 426 if __name__ == '__main__': |
| 413 sys.exit(main()) | 427 sys.exit(main()) |
| OLD | NEW |