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