blob: a51ed0066a46bac5288dff1dcb132206afd05f29 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import argparse
import os
import subprocess
import sys
import utils
VERSION_FILE = 'src/main/java/com/android/tools/r8/Version.java'
VERSION_PREFIX = 'String LABEL = "'
def parse_options():
parser = argparse.ArgumentParser(description='Release r8')
parser.add_argument('--branch',
metavar=('<branch>'),
help='Branch to cherry-pick to')
parser.add_argument('--current-checkout', '--current_checkout',
default=False,
action='store_true',
help='Perform cherry picks into the current checkout')
parser.add_argument('--no-upload', '--no_upload',
default=False,
action='store_true',
help='Do not upload to Gerrit')
parser.add_argument('hashes', metavar='<hash>', nargs='+',
help='Hashed to merge')
return parser.parse_args()
def run(args):
# Checkout the branch.
subprocess.check_output(['git', 'checkout', args.branch])
if (args.current_checkout):
for i in range(len(args.hashes) + 1):
branch = 'cherry-%d' % (i + 1)
print('Deleting branch %s' % branch)
subprocess.run(['git', 'branch', branch, '-D'])
bugs = set()
count = 1
for hash in args.hashes:
branch = 'cherry-%d' % count
print('Cherry-picking %s in %s' % (hash, branch))
if (count == 1):
subprocess.run(['git', 'new-branch', branch, '--upstream', 'origin/%s' % args.branch])
else:
subprocess.run(['git', 'new-branch', branch, '--upstream-current'])
subprocess.run(['git', 'cherry-pick', hash])
commit_message = subprocess.check_output(['git', 'log', '--format=%B', '-n', '1', 'HEAD'])
commit_lines = [l.strip() for l in commit_message.decode('UTF-8').split('\n')]
for line in commit_lines:
if line.startswith('Bug: '):
normalized = line.replace('Bug: ', '').replace('b/', '')
if len(normalized) > 0:
bugs.add(normalized)
confirm_and_upload(branch, args)
count = count + 1
branch = 'cherry-%d' % count
subprocess.run(['git', 'new-branch', branch, '--upstream-current'])
old_version = 'unknown'
for line in open(VERSION_FILE, 'r'):
index = line.find(VERSION_PREFIX)
if index > 0:
index += len(VERSION_PREFIX)
subline = line[index:]
old_version = subline[:subline.index('"')]
break
new_version = 'unknown'
if old_version.find('.') > 0:
split_version = old_version.split('.')
new_version = '.'.join(split_version[:-1] + [str(int(split_version[-1]) + 1)])
subprocess.run(['sed', '-i', 's/%s/%s/' % (old_version, new_version), VERSION_FILE])
else:
editor = os.environ.get('VISUAL')
if not editor:
editor = os.environ.get('EDITOR')
if not editor:
editor = 'vi'
else:
print("Opening %s for version update with %s" % (VERSION_FILE, editor))
subprocess.run([editor, VERSION_FILE])
message = ("Version %s\n\n" % new_version)
for bug in sorted(bugs):
message += 'Bug: b/%s\n' % bug
subprocess.run(['git', 'commit', '-a', '-m', message])
confirm_and_upload(branch, args)
if (not args.current_checkout):
answer = input('Done, press enter to delete checkout in %s' % os.getcwd())
def confirm_and_upload(branch, args):
question = ('Ready to continue (cwd %s, will not upload to Gerrit)' % os.getcwd()
if args.no_upload else
'Ready to upload %s (cwd %s)' % (branch, os.getcwd()))
answer = input(question + ' [y/N]?')
if answer != 'y':
print('Aborting new branch for %s' % branch_version)
sys.exit(1)
if (not args.no_upload):
subprocess.run(['git', 'cl', 'upload', '--bypass-hooks'])
def main():
args = parse_options()
if (not args.current_checkout):
with utils.TempDir() as temp:
print("Performing cherry-picking in %s" % temp)
subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
with utils.ChangedWorkingDirectory(temp):
run(args)
else:
# Run in current directory.
print("Performing cherry-picking in %s" % os.getcwd())
subprocess.check_output(['git', 'fetch', 'origin'])
run(args)
if __name__ == '__main__':
sys.exit(main())