1*67e74705SXin Li#!/usr/bin/env python 2*67e74705SXin Li# 3*67e74705SXin Li# Copyright (C) 2015 The Android Open Source Project 4*67e74705SXin Li# 5*67e74705SXin Li# Licensed under the Apache License, Version 2.0 (the "License"); 6*67e74705SXin Li# you may not use this file except in compliance with the License. 7*67e74705SXin Li# You may obtain a copy of the License at 8*67e74705SXin Li# 9*67e74705SXin Li# http://www.apache.org/licenses/LICENSE-2.0 10*67e74705SXin Li# 11*67e74705SXin Li# Unless required by applicable law or agreed to in writing, software 12*67e74705SXin Li# distributed under the License is distributed on an "AS IS" BASIS, 13*67e74705SXin Li# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*67e74705SXin Li# See the License for the specific language governing permissions and 15*67e74705SXin Li# limitations under the License. 16*67e74705SXin Li# 17*67e74705SXin Li 18*67e74705SXin Li"""Update the prebuilt clang from the build server.""" 19*67e74705SXin Lifrom __future__ import print_function 20*67e74705SXin Li 21*67e74705SXin Liimport argparse 22*67e74705SXin Liimport inspect 23*67e74705SXin Liimport os 24*67e74705SXin Liimport shutil 25*67e74705SXin Liimport subprocess 26*67e74705SXin Liimport sys 27*67e74705SXin Li 28*67e74705SXin Li 29*67e74705SXin LiTHIS_DIR = os.path.realpath(os.path.dirname(__name__)) 30*67e74705SXin LiANDROID_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..')) 31*67e74705SXin Li 32*67e74705SXin LiBRANCH = 'aosp-llvm' 33*67e74705SXin Li 34*67e74705SXin Li 35*67e74705SXin Lidef android_path(*args): 36*67e74705SXin Li return os.path.join(ANDROID_DIR, *args) 37*67e74705SXin Li 38*67e74705SXin Li 39*67e74705SXin Liclass ArgParser(argparse.ArgumentParser): 40*67e74705SXin Li def __init__(self): 41*67e74705SXin Li super(ArgParser, self).__init__( 42*67e74705SXin Li description=inspect.getdoc(sys.modules[__name__])) 43*67e74705SXin Li 44*67e74705SXin Li self.add_argument( 45*67e74705SXin Li 'build', metavar='BUILD', 46*67e74705SXin Li help='Build number to pull from the build server.') 47*67e74705SXin Li 48*67e74705SXin Li self.add_argument( 49*67e74705SXin Li '-b', '--bug', type=int, 50*67e74705SXin Li help='Bug to reference in commit message.') 51*67e74705SXin Li 52*67e74705SXin Li self.add_argument( 53*67e74705SXin Li '--use-current-branch', action='store_true', 54*67e74705SXin Li help='Do not repo start a new branch for the update.') 55*67e74705SXin Li 56*67e74705SXin Li 57*67e74705SXin Lidef host_to_build_host(host): 58*67e74705SXin Li """Gets the build host name for an NDK host tag. 59*67e74705SXin Li 60*67e74705SXin Li The Windows builds are done from Linux. 61*67e74705SXin Li """ 62*67e74705SXin Li return { 63*67e74705SXin Li 'darwin': 'mac', 64*67e74705SXin Li 'linux': 'linux', 65*67e74705SXin Li 'windows': 'linux', 66*67e74705SXin Li }[host] 67*67e74705SXin Li 68*67e74705SXin Li 69*67e74705SXin Lidef build_name(host): 70*67e74705SXin Li """Gets the build name for a given host. 71*67e74705SXin Li 72*67e74705SXin Li The build name is either "linux" or "darwin", with any Windows builds 73*67e74705SXin Li coming from "linux". 74*67e74705SXin Li """ 75*67e74705SXin Li return { 76*67e74705SXin Li 'darwin': 'darwin', 77*67e74705SXin Li 'linux': 'linux', 78*67e74705SXin Li 'windows': 'linux', 79*67e74705SXin Li }[host] 80*67e74705SXin Li 81*67e74705SXin Li 82*67e74705SXin Lidef manifest_name(build_number): 83*67e74705SXin Li """Returns the manifest file name for a given build. 84*67e74705SXin Li 85*67e74705SXin Li >>> manifest_name('1234') 86*67e74705SXin Li 'manifest_1234.xml' 87*67e74705SXin Li """ 88*67e74705SXin Li return 'manifest_{}.xml'.format(build_number) 89*67e74705SXin Li 90*67e74705SXin Li 91*67e74705SXin Lidef package_name(build_number, host): 92*67e74705SXin Li """Returns the file name for a given package configuration. 93*67e74705SXin Li 94*67e74705SXin Li >>> package_name('1234', 'linux') 95*67e74705SXin Li 'clang-1234-linux-x86.tar.bz2' 96*67e74705SXin Li """ 97*67e74705SXin Li return 'clang-{}-{}-x86.tar.bz2'.format(build_number, host) 98*67e74705SXin Li 99*67e74705SXin Li 100*67e74705SXin Lidef download_build(host, build_number, download_dir): 101*67e74705SXin Li filename = package_name(build_number, host) 102*67e74705SXin Li return download_file(host, build_number, filename, download_dir) 103*67e74705SXin Li 104*67e74705SXin Li 105*67e74705SXin Lidef download_manifest(host, build_number, download_dir): 106*67e74705SXin Li filename = manifest_name(build_number) 107*67e74705SXin Li return download_file(host, build_number, filename, download_dir) 108*67e74705SXin Li 109*67e74705SXin Li 110*67e74705SXin Lidef download_file(host, build_number, pkg_name, download_dir): 111*67e74705SXin Li url_base = 'https://android-build-uber.corp.google.com' 112*67e74705SXin Li path = 'builds/{branch}-{build_host}-{build_name}/{build_num}'.format( 113*67e74705SXin Li branch=BRANCH, 114*67e74705SXin Li build_host=host_to_build_host(host), 115*67e74705SXin Li build_name=build_name(host), 116*67e74705SXin Li build_num=build_number) 117*67e74705SXin Li 118*67e74705SXin Li url = '{}/{}/{}'.format(url_base, path, pkg_name) 119*67e74705SXin Li 120*67e74705SXin Li TIMEOUT = '60' # In seconds. 121*67e74705SXin Li out_file_path = os.path.join(download_dir, pkg_name) 122*67e74705SXin Li with open(out_file_path, 'w') as out_file: 123*67e74705SXin Li print('Downloading {} to {}'.format(url, out_file_path)) 124*67e74705SXin Li subprocess.check_call( 125*67e74705SXin Li ['sso_client', '--location', '--request_timeout', TIMEOUT, url], 126*67e74705SXin Li stdout=out_file) 127*67e74705SXin Li return out_file_path 128*67e74705SXin Li 129*67e74705SXin Li 130*67e74705SXin Lidef extract_package(package, install_dir): 131*67e74705SXin Li cmd = ['tar', 'xf', package, '-C', install_dir] 132*67e74705SXin Li print('Extracting {}...'.format(package)) 133*67e74705SXin Li subprocess.check_call(cmd) 134*67e74705SXin Li 135*67e74705SXin Li 136*67e74705SXin Lidef update_clang(host, build_number, use_current_branch, download_dir, bug): 137*67e74705SXin Li host_tag = host + '-x86' 138*67e74705SXin Li prebuilt_dir = android_path('prebuilts/clang/host', host_tag) 139*67e74705SXin Li os.chdir(prebuilt_dir) 140*67e74705SXin Li 141*67e74705SXin Li if not use_current_branch: 142*67e74705SXin Li subprocess.check_call( 143*67e74705SXin Li ['repo', 'start', 'update-clang-{}'.format(build_number), '.']) 144*67e74705SXin Li 145*67e74705SXin Li package = download_build(host, build_number, download_dir) 146*67e74705SXin Li manifest = download_manifest(host, build_number, download_dir) 147*67e74705SXin Li 148*67e74705SXin Li install_subdir = 'clang-' + build_number 149*67e74705SXin Li extract_package(package, prebuilt_dir) 150*67e74705SXin Li shutil.copy(manifest, prebuilt_dir + '/' + install_subdir) 151*67e74705SXin Li 152*67e74705SXin Li print('Adding files to index...') 153*67e74705SXin Li subprocess.check_call(['git', 'add', install_subdir]) 154*67e74705SXin Li 155*67e74705SXin Li version_file_path = os.path.join(install_subdir, 'AndroidVersion.txt') 156*67e74705SXin Li with open(version_file_path) as version_file: 157*67e74705SXin Li version = version_file.read().strip() 158*67e74705SXin Li 159*67e74705SXin Li print('Committing update...') 160*67e74705SXin Li message_lines = [ 161*67e74705SXin Li 'Update prebuilt Clang to build {}.'.format(build_number), 162*67e74705SXin Li '', 163*67e74705SXin Li 'Built from version {}.'.format(version), 164*67e74705SXin Li ] 165*67e74705SXin Li if bug is not None: 166*67e74705SXin Li message_lines.append('') 167*67e74705SXin Li message_lines.append('Bug: http://b/{}'.format(bug)) 168*67e74705SXin Li message = '\n'.join(message_lines) 169*67e74705SXin Li subprocess.check_call(['git', 'commit', '-m', message]) 170*67e74705SXin Li 171*67e74705SXin Li 172*67e74705SXin Lidef main(): 173*67e74705SXin Li args = ArgParser().parse_args() 174*67e74705SXin Li 175*67e74705SXin Li download_dir = os.path.realpath('.download') 176*67e74705SXin Li if os.path.isdir(download_dir): 177*67e74705SXin Li shutil.rmtree(download_dir) 178*67e74705SXin Li os.makedirs(download_dir) 179*67e74705SXin Li 180*67e74705SXin Li try: 181*67e74705SXin Li hosts = ('darwin', 'linux', 'windows') 182*67e74705SXin Li for host in hosts: 183*67e74705SXin Li update_clang(host, args.build, args.use_current_branch, 184*67e74705SXin Li download_dir, args.bug) 185*67e74705SXin Li finally: 186*67e74705SXin Li shutil.rmtree(download_dir) 187*67e74705SXin Li 188*67e74705SXin Li 189*67e74705SXin Liif __name__ == '__main__': 190*67e74705SXin Li main() 191