1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#!/usr/bin/env python3
# Copyright 2021 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.
# based on an almost identical script by: jyrki@google.com (Jyrki Alakuijala)
"""Updates the commit message used in the auto-roller.
Merges several small commit logs into a single more useful commit message.
Usage:
update_commit_message.py --old-revision=<sha1>
"""
import argparse
import logging
import os
import platform
import re
import shutil
import subprocess
import sys
import tempfile
GCLIENT_LINE = r'([^:]+): ([^@]+)@(.*)'
CHANGE_TEMPLATE = '* %s: %s.git/+log/%s..%s'
EXIT_SUCCESS = 0
EXIT_FAILURE = 1
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
GCLIENT = """\
solutions = [{
'name': '.',
'url': 'https://chromium.googlesource.com/vulkan-deps.git',
'deps_file': 'DEPS',
'managed': False,
}]
"""
INSERT_NEEDLE = 'If this roll has caused a breakage'
def run(cmd, args):
exe = ('%s.bat' % cmd) if platform.system() == 'Windows' else cmd
cmd_args = [exe] + list(args)
return subprocess.check_output(cmd_args).decode('ascii').strip()
def git(*args):
return run('git', args)
def gclient(*args):
return run('gclient', args)
def parse_revinfo(output):
expr = re.compile(GCLIENT_LINE)
config = dict()
urls = dict()
for line in output.split('\n'):
match = expr.match(line.strip())
if match:
dep = match.group(1)
urls[dep] = match.group(2)
config[dep] = match.group(3)
return config, urls
def _local_commit_amend(commit_msg, dry_run):
logging.info('Amending changes to local commit.')
old_commit_msg = git('log', '-1', '--pretty=%B')
logging.debug('Existing commit message:\n%s\n', old_commit_msg)
insert_index = old_commit_msg.rfind(INSERT_NEEDLE)
if insert_index == -1:
logging.exception('"%s" not found in commit message.' % INSERT_NEEDLE)
new_commit_msg = old_commit_msg[:insert_index] + commit_msg + '\n\n' + old_commit_msg[insert_index:]
logging.debug('New commit message:\n%s\n', new_commit_msg)
if not dry_run:
with tempfile.NamedTemporaryFile(delete=False, mode="w") as ntf:
ntf.write(new_commit_msg)
ntf.close()
git('commit', '--amend', '--no-edit', '--file=%s' % ntf.name)
os.unlink(ntf.name)
def main(raw_args):
parser = argparse.ArgumentParser()
parser.add_argument('--old-revision', help='Old git revision in the roll.', required=True)
parser.add_argument(
'--dry-run',
help='Test out functionality without making changes.',
action='store_true',
default=False)
parser.add_argument(
'-v', '--verbose', help='Verbose debug logging.', action='store_true', default=False)
args = parser.parse_args(raw_args)
if args.verbose:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
cwd = os.getcwd()
os.chdir(SCRIPT_DIR)
old_deps_content = git('show', '%s:DEPS' % args.old_revision)
with tempfile.TemporaryDirectory() as tempdir:
os.chdir(tempdir)
# Add the gclientfile.
with open(os.path.join(tempdir, '.gclient'), 'w') as gcfile:
gcfile.write(GCLIENT)
gcfile.close()
# Get the current config.
shutil.copyfile(os.path.join(SCRIPT_DIR, 'DEPS'), os.path.join(tempdir, 'DEPS'))
gclient_head_output = gclient('revinfo')
# Get the prior config.
with open('DEPS', 'w') as deps:
deps.write(old_deps_content)
deps.close()
gclient_old_output = gclient('revinfo')
os.chdir(SCRIPT_DIR)
head_config, urls = parse_revinfo(gclient_head_output)
old_config, _ = parse_revinfo(gclient_old_output)
changed_deps = []
for dep, new_sha1 in head_config.items():
if dep in old_config:
old_sha1 = old_config[dep]
if new_sha1 != old_sha1:
dep_short = dep.replace('\\', '/').split('/')[0]
repo = urls[dep]
logging.debug('Found change: %s to %s' % (dep, new_sha1))
changed_deps.append(CHANGE_TEMPLATE %
(dep_short, repo, old_sha1[:10], new_sha1[:10]))
if not changed_deps:
print('No changed dependencies, early exit.')
return EXIT_SUCCESS
commit_msg = 'Changed dependencies:\n%s' % '\n'.join(sorted(changed_deps))
os.chdir(cwd)
_local_commit_amend(commit_msg, args.dry_run)
return EXIT_SUCCESS
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
|