| #!/usr/bin/env python |
| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Rolls swarming_client. |
| |
| While it is currently hard coded for swarming_client/, it is potentially |
| modifiable to allow different dependencies. Works only with git checkout and git |
| dependencies. |
| """ |
| |
| import optparse |
| import os |
| import re |
| import subprocess |
| import sys |
| |
| SRC_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| |
| |
| def is_pristine(root, merge_base='origin/master'): |
| """Returns True is a git checkout is pristine.""" |
| cmd = ['git', 'diff', '--ignore-submodules', merge_base] |
| return not ( |
| subprocess.check_output(cmd, cwd=root).strip() or |
| subprocess.check_output(cmd + ['--cached'], cwd=root).strip()) |
| |
| |
| def roll(deps_dir, key, reviewer, bug): |
| if not is_pristine(SRC_ROOT): |
| print >> sys.stderr, 'Ensure %s is clean first.' % SRC_ROOT |
| return 1 |
| |
| full_dir = os.path.join(SRC_ROOT, deps_dir) |
| head = subprocess.check_output( |
| ['git', 'rev-parse', 'HEAD'], cwd=full_dir).strip() |
| deps = os.path.join(SRC_ROOT, 'DEPS') |
| with open(deps, 'rb') as f: |
| deps_content = f.read() |
| |
| if not head in deps_content: |
| print('Warning: %s is not checked out at the expected revision in DEPS' % |
| deps_dir) |
| # It happens if the user checked out a branch in the dependency by himself. |
| # Fall back to reading the DEPS to figure out the original commit. |
| for i in deps_content.splitlines(): |
| m = re.match(r'\s+"' + key + '": "([a-z0-9]{40})",', i) |
| if m: |
| head = m.group(1) |
| break |
| else: |
| print >> sys.stderr, 'Expected to find commit %s for %s in DEPS' % ( |
| head, key) |
| return 1 |
| |
| print('Found old revision %s' % head) |
| |
| subprocess.check_call(['git', 'fetch', 'origin'], cwd=full_dir) |
| master = subprocess.check_output( |
| ['git', 'rev-parse', 'origin/master'], cwd=full_dir).strip() |
| print('Found new revision %s' % master) |
| |
| if master == head: |
| print('No revision to roll!') |
| return 1 |
| |
| commit_range = '%s..%s' % (head[:9], master[:9]) |
| logs = subprocess.check_output( |
| ['git', 'log', commit_range, '--date=short', '--format=%ad %ae %s'], |
| cwd=full_dir).strip() |
| logs = logs.replace('@chromium.org', '') |
| cmd = ( |
| 'git log %s --date=short --format=\'%%ad %%ae %%s\' | ' |
| 'sed \'s/@chromium\.org//\'') % commit_range |
| |
| msg = ( |
| 'Roll %s/ to %s.\n' |
| '\n' |
| '$ %s\n' |
| '%s\n\n' |
| 'R=%s\n' |
| 'BUG=%s') % ( |
| deps_dir, |
| master, |
| cmd, |
| logs, |
| reviewer, |
| bug) |
| |
| print('Commit message:') |
| print('\n'.join(' ' + i for i in msg.splitlines())) |
| deps_content = deps_content.replace(head, master) |
| with open(deps, 'wb') as f: |
| f.write(deps_content) |
| subprocess.check_call(['git', 'add', 'DEPS'], cwd=SRC_ROOT) |
| subprocess.check_call(['git', 'commit', '-m', msg], cwd=SRC_ROOT) |
| print('Run:') |
| print(' git cl upl --send-mail') |
| return 0 |
| |
| |
| def main(): |
| parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) |
| parser.add_option( |
| '-r', '--reviewer', default='', |
| help='To specify multiple reviewers, use comma separated list, e.g. ' |
| '-r joe,jack,john. Defaults to @chromium.org') |
| parser.add_option('-b', '--bug', default='') |
| options, args = parser.parse_args() |
| if args: |
| parser.error('Unknown argument %s' % args) |
| if not options.reviewer: |
| parser.error('Pass a reviewer right away with -r/--reviewer') |
| |
| reviewers = options.reviewer.split(',') |
| for i, r in enumerate(reviewers): |
| if not '@' in r: |
| reviewers[i] = r + '@chromium.org' |
| |
| return roll( |
| 'tools/swarming_client', |
| 'swarming_revision', |
| ','.join(reviewers), |
| options.bug) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |