Sync: support implicit permanent folders in commits.
[chromium-blink-merge.git] / tools / roll_swarming_client.py
blobb5c14480b4957f5b1a10ee25817444f2fca4bc26
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Rolls swarming_client.
8 While it is currently hard coded for swarming_client/, it is potentially
9 modifiable to allow different dependencies. Works only with git checkout and git
10 dependencies.
11 """
13 import optparse
14 import os
15 import re
16 import subprocess
17 import sys
19 SRC_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
22 def is_pristine(root, merge_base='origin/master'):
23 """Returns True is a git checkout is pristine."""
24 cmd = ['git', 'diff', '--ignore-submodules', merge_base]
25 return not (
26 subprocess.check_output(cmd, cwd=root).strip() or
27 subprocess.check_output(cmd + ['--cached'], cwd=root).strip())
30 def roll(deps_dir, key, reviewer, bug):
31 if not is_pristine(SRC_ROOT):
32 print >> sys.stderr, 'Ensure %s is clean first.' % SRC_ROOT
33 return 1
35 full_dir = os.path.join(SRC_ROOT, deps_dir)
36 head = subprocess.check_output(
37 ['git', 'rev-parse', 'HEAD'], cwd=full_dir).strip()
38 deps = os.path.join(SRC_ROOT, 'DEPS')
39 with open(deps, 'rb') as f:
40 deps_content = f.read()
42 if not head in deps_content:
43 print('Warning: %s is not checked out at the expected revision in DEPS' %
44 deps_dir)
45 # It happens if the user checked out a branch in the dependency by himself.
46 # Fall back to reading the DEPS to figure out the original commit.
47 for i in deps_content.splitlines():
48 m = re.match(r'\s+"' + key + '": "([a-z0-9]{40})",', i)
49 if m:
50 head = m.group(1)
51 break
52 else:
53 print >> sys.stderr, 'Expected to find commit %s for %s in DEPS' % (
54 head, key)
55 return 1
57 print('Found old revision %s' % head)
59 subprocess.check_call(['git', 'fetch', 'origin'], cwd=full_dir)
60 master = subprocess.check_output(
61 ['git', 'rev-parse', 'origin/master'], cwd=full_dir).strip()
62 print('Found new revision %s' % master)
64 if master == head:
65 print('No revision to roll!')
66 return 1
68 commit_range = '%s..%s' % (head[:9], master[:9])
69 logs = subprocess.check_output(
70 ['git', 'log', commit_range, '--date=short', '--format=%ad %ae %s'],
71 cwd=full_dir).strip()
72 logs = logs.replace('@chromium.org', '')
73 cmd = (
74 'git log %s --date=short --format=\'%%ad %%ae %%s\' | '
75 'sed \'s/@chromium\.org//\'') % commit_range
77 msg = (
78 'Roll %s/ to %s.\n'
79 '\n'
80 '$ %s\n'
81 '%s\n\n'
82 'R=%s\n'
83 'BUG=%s') % (
84 deps_dir,
85 master,
86 cmd,
87 logs,
88 reviewer,
89 bug)
91 print('Commit message:')
92 print('\n'.join(' ' + i for i in msg.splitlines()))
93 deps_content = deps_content.replace(head, master)
94 with open(deps, 'wb') as f:
95 f.write(deps_content)
96 subprocess.check_call(['git', 'add', 'DEPS'], cwd=SRC_ROOT)
97 subprocess.check_call(['git', 'commit', '-m', msg], cwd=SRC_ROOT)
98 print('Run:')
99 print(' git cl upl --send-mail')
100 return 0
103 def main():
104 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
105 parser.add_option(
106 '-r', '--reviewer', default='',
107 help='To specify multiple reviewers, use comma separated list, e.g. '
108 '-r joe,jack,john. Defaults to @chromium.org')
109 parser.add_option('-b', '--bug', default='')
110 options, args = parser.parse_args()
111 if args:
112 parser.error('Unknown argument %s' % args)
113 if not options.reviewer:
114 parser.error('Pass a reviewer right away with -r/--reviewer')
116 reviewers = options.reviewer.split(',')
117 for i, r in enumerate(reviewers):
118 if not '@' in r:
119 reviewers[i] = r + '@chromium.org'
121 return roll(
122 'tools/swarming_client',
123 'swarming_revision',
124 ','.join(reviewers),
125 options.bug)
128 if __name__ == '__main__':
129 sys.exit(main())