2 # Copyright 2021 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.
5 # based on an almost identical script by: jyrki@google.com (Jyrki Alakuijala)
6 """Updates the commit message used in the auto-roller.
8 Merges several small commit logs into a single more useful commit message.
11 update_commit_message.py --old-revision=<sha1>
24 GCLIENT_LINE = r'([^:]+): ([^@]+)@(.*)'
25 CHANGE_TEMPLATE = '* %s: %s.git/+log/%s..%s'
28 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
32 'url': 'https://chromium.googlesource.com/vulkan-deps.git',
37 INSERT_NEEDLE = 'If this roll has caused a breakage'
41 exe = ('%s.bat' % cmd) if platform.system() == 'Windows' else cmd
42 cmd_args = [exe] + list(args)
43 return subprocess.check_output(cmd_args).decode('ascii').strip()
47 return run('git', args)
51 return run('gclient', args)
54 def parse_revinfo(output):
55 expr = re.compile(GCLIENT_LINE)
58 for line in output.split('\n'):
59 match = expr.match(line.strip())
62 urls[dep] = match.group(2)
63 config[dep] = match.group(3)
67 def _local_commit_amend(commit_msg, dry_run):
68 logging.info('Amending changes to local commit.')
69 old_commit_msg = git('log', '-1', '--pretty=%B')
70 logging.debug('Existing commit message:\n%s\n', old_commit_msg)
71 insert_index = old_commit_msg.rfind(INSERT_NEEDLE)
72 if insert_index == -1:
73 logging.exception('"%s" not found in commit message.' % INSERT_NEEDLE)
75 new_commit_msg = old_commit_msg[:insert_index] + commit_msg + '\n\n' + old_commit_msg[insert_index:]
76 logging.debug('New commit message:\n%s\n', new_commit_msg)
78 with tempfile.NamedTemporaryFile(delete=False, mode="w") as ntf:
79 ntf.write(new_commit_msg)
81 git('commit', '--amend', '--no-edit', '--file=%s' % ntf.name)
86 parser = argparse.ArgumentParser()
87 parser.add_argument('--old-revision', help='Old git revision in the roll.', required=True)
90 help='Test out functionality without making changes.',
94 '-v', '--verbose', help='Verbose debug logging.', action='store_true', default=False)
95 args = parser.parse_args(raw_args)
98 logging.basicConfig(level=logging.DEBUG)
100 logging.basicConfig(level=logging.INFO)
105 old_deps_content = git('show', '%s:DEPS' % args.old_revision)
107 with tempfile.TemporaryDirectory() as tempdir:
110 # Add the gclientfile.
111 with open(os.path.join(tempdir, '.gclient'), 'w') as gcfile:
112 gcfile.write(GCLIENT)
115 # Get the current config.
116 shutil.copyfile(os.path.join(SCRIPT_DIR, 'DEPS'), os.path.join(tempdir, 'DEPS'))
117 gclient_head_output = gclient('revinfo')
119 # Get the prior config.
120 with open('DEPS', 'w') as deps:
121 deps.write(old_deps_content)
123 gclient_old_output = gclient('revinfo')
126 head_config, urls = parse_revinfo(gclient_head_output)
127 old_config, _ = parse_revinfo(gclient_old_output)
131 for dep, new_sha1 in head_config.items():
132 if dep in old_config:
133 old_sha1 = old_config[dep]
134 if new_sha1 != old_sha1:
135 dep_short = dep.replace('\\', '/').split('/')[0]
137 logging.debug('Found change: %s to %s' % (dep, new_sha1))
138 changed_deps.append(CHANGE_TEMPLATE %
139 (dep_short, repo, old_sha1[:10], new_sha1[:10]))
142 print('No changed dependencies, early exit.')
145 commit_msg = 'Changed dependencies:\n%s' % '\n'.join(sorted(changed_deps))
148 _local_commit_amend(commit_msg, args.dry_run)
153 if __name__ == '__main__':
154 sys.exit(main(sys.argv[1:]))