blob: cdedf5393cea9bbd6b5bb27620374df058a5ab08 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2021, 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 jdk
import json
import os.path
import re
import subprocess
import sys
import urllib.request
import utils
# Grep match string for 'Version X.Y.Z[-dev]'
VERSION_EXP = '^Version [[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+\(\|-dev\)$'
# R8 is located in the 'builder' library.
AGP_MAVEN = "https://dl.google.com/android/maven2/com/android/tools/build/builder"
def parse_options():
parser = argparse.ArgumentParser(description='Tag R8 Versions')
parser.add_argument('--branch',
help='The R8 branch to tag versions on, eg, origin/3.0')
parser.add_argument('--agp',
help='The AGP to compute the tag for, eg, 4.2.0-beta03')
parser.add_argument('--use-push',
default=False,
action='store_true',
help='To create the tag locally only.')
parser.add_argument(
'--dry-run',
default=False,
action='store_true',
help='Print the state changing commands without running them.')
return parser.parse_args()
def run(options, cmd):
print(' '.join(cmd))
if options.dry_run:
return
try:
subprocess.check_call(cmd)
except subprocess.CalledProcessError as e:
print(e)
def main():
args = parse_options()
if args.branch:
tag_r8_branch(args.branch, args)
elif args.agp:
if (args.agp == 'all'):
tag_all_agp_versions(args)
else:
tag_agp_version(args.agp, args)
else:
print("Should use a top-level option, such as --branch or --agp.")
return 1
return 0
def prepare_print_version(dist, temp):
wrapper_file = os.path.join(
utils.REPO_ROOT,
'src/main/java/com/android/tools/r8/utils/PrintR8Version.java')
cmd = [
jdk.GetJavacExecutable(),
wrapper_file,
'-d',
temp,
'-cp',
dist,
]
utils.PrintCmd(cmd)
subprocess.check_output(cmd)
return temp
# Testing info: To delete a tag use
#
# gob-curl --request DELETE https://r8-review.git.corp.google.com/a/projects/r8/tags/<tag>
#
def gerrit_tag(args, tag, hash, description):
data = json.dumps({
"message": description if description else tag,
"revision": hash
})
cmd = ' '.join([
'gob-curl',
'--header',
'"Content-Type: application/json; charset=UTF-8"',
'--request',
'PUT',
'--data',
"'{data}'".format(data=data),
'https://r8-review.git.corp.google.com/a/projects/r8/tags/{tag}'.format(tag=tag)
])
result = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
print(result)
def get_tag_info_on_origin(tag):
output = subprocess.check_output(
['git', 'ls-remote', '--tags', 'origin', tag]).decode('utf-8')
if len(output.strip()) == 0:
return None
return output
def tag_all_agp_versions(args):
with utils.TempDir() as temp:
url = "%s/maven-metadata.xml" % AGP_MAVEN
metadata = os.path.join(temp, "maven-metadata.xml")
try:
urllib.request.urlretrieve(url, metadata)
except urllib.error.HTTPError as e:
print('Could not find maven-metadata.xml for agp')
print(e)
return 1
with open(metadata, 'r') as file:
data = file.read()
pattern = r'<version>(.+)</version>'
matches = re.findall(pattern, data)
matches.reverse()
for version in matches:
print('Tagging agp version ' + version)
tag_agp_version(version, args)
def tag_agp_version(agp_version, args):
tag = 'agp-%s' % agp_version
result = get_tag_info_on_origin(tag)
if result:
print('Tag %s is already present' % tag)
print(result)
subprocess.call(['git', 'show', '--oneline', '-s', tag])
return 0
with utils.TempDir() as temp:
url = "%s/%s/builder-%s.jar" % (AGP_MAVEN, agp_version, agp_version)
jar = os.path.join(temp, "agp.jar")
try:
urllib.request.urlretrieve(url, jar)
except urllib.error.HTTPError as e:
print('Could not find jar for agp %s' % agp_version)
print(e)
return 1
print_version_helper = prepare_print_version(utils.R8_JAR, temp)
output = subprocess.check_output([
jdk.GetJavaExecutable(), '-cp',
':'.join([jar, print_version_helper]),
'com.android.tools.r8.utils.PrintR8Version'
]).decode('utf-8')
r8_version = output.split(' ')[0]
cmd = ' '.join(['git', 'rev-list', '-n', '1', r8_version])
hash = subprocess.check_output(cmd, shell=True).decode('utf-8').strip()
message = 'AGP version {version}'.format(version=agp_version)
run(args, ['git', 'tag', '-f', tag, '-m', message, hash])
if args.use_push:
run(args, [
'git', 'push', '-o', 'push-justification=b/313360935', 'origin', tag
])
else:
gerrit_tag(args, tag, hash, message)
def tag_r8_branch(branch, args):
if not branch.startswith('origin/'):
print('Expected branch to start with origin/')
return 1
output = subprocess.check_output(
['git', 'log', '--pretty=format:%H\t%s', '--grep', VERSION_EXP,
branch]).decode('utf-8')
for l in output.split('\n'):
(hash, subject) = l.split('\t')
m = re.search('Version (.+)', subject)
if not m:
print('Unable to find a version for line: %s' % l)
continue
version = m.group(1)
result = get_tag_info_on_origin(version)
if not result:
message = 'Version {version}'.format(version=version)
run(args, ['git', 'tag', '-a', version, '-m', message, hash])
if args.use_push:
run(args, [
'git', 'push', '-o', 'push-justification=b/313360935', 'origin',
version
])
else:
gerrit_tag(args, version, hash, message)
if args.dry_run:
print('Dry run complete. None of the above have been executed.')
if __name__ == '__main__':
sys.exit(main())