169 lines
5.1 KiB
Python
Executable file
169 lines
5.1 KiB
Python
Executable file
#!/usr/bin/env python
|
|
#
|
|
# Copyright (C) 2016 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
import argparse
|
|
import glob
|
|
import logging
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import textwrap
|
|
|
|
|
|
THIS_DIR = os.path.realpath(os.path.dirname(__file__))
|
|
|
|
|
|
def logger():
|
|
return logging.getLogger(__name__)
|
|
|
|
|
|
def check_call(cmd):
|
|
logger().debug('Running `%s`', ' '.join(cmd))
|
|
subprocess.check_call(cmd)
|
|
|
|
|
|
def fetch_artifact(branch, build, pattern):
|
|
fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
|
|
cmd = [fetch_artifact_path, '--branch', branch, '--target=linux',
|
|
'--bid', build, pattern]
|
|
check_call(cmd)
|
|
|
|
|
|
def api_str(api_level):
|
|
return 'android-{}'.format(api_level)
|
|
|
|
|
|
def start_branch(build):
|
|
branch_name = 'update-' + (build or 'latest')
|
|
logger().info('Creating branch %s', branch_name)
|
|
check_call(['repo', 'start', branch_name, '.'])
|
|
|
|
|
|
def remove_old_release(install_dir):
|
|
if os.path.exists(os.path.join(install_dir, '.git')):
|
|
logger().info('Removing old install directory "%s"', install_dir)
|
|
check_call(['git', 'rm', '-rf', install_dir])
|
|
|
|
# Need to check again because git won't remove directories if they have
|
|
# non-git files in them.
|
|
if os.path.exists(install_dir):
|
|
shutil.rmtree(install_dir)
|
|
|
|
|
|
def install_new_release(branch, build, install_dir):
|
|
os.makedirs(install_dir)
|
|
|
|
artifact_pattern = 'android-ndk-*.tar.bz2'
|
|
logger().info('Fetching %s from %s (artifacts matching %s)', build, branch,
|
|
artifact_pattern)
|
|
fetch_artifact(branch, build, artifact_pattern)
|
|
artifacts = glob.glob('android-ndk-*.tar.bz2')
|
|
try:
|
|
assert len(artifacts) == 1
|
|
artifact = artifacts[0]
|
|
|
|
logger().info('Extracting release')
|
|
cmd = ['tar', 'xf', artifact, '-C', install_dir, '--wildcards',
|
|
'--strip-components=1', '*/platforms', '*/sources',
|
|
'*/source.properties']
|
|
check_call(cmd)
|
|
finally:
|
|
for artifact in artifacts:
|
|
os.unlink(artifact)
|
|
|
|
|
|
def symlink_gaps(first, last):
|
|
for api in xrange(first, last + 1):
|
|
if os.path.exists(api_str(api)):
|
|
continue
|
|
|
|
# Not all API levels have a platform directory. Make a symlink to the
|
|
# previous API level. For example, symlink android-10 to android-9.
|
|
assert api != 9
|
|
os.symlink(api_str(api - 1), api_str(api))
|
|
|
|
|
|
def make_symlinks(install_dir):
|
|
old_dir = os.getcwd()
|
|
os.chdir(os.path.join(THIS_DIR, install_dir, 'platforms'))
|
|
|
|
first_api = 9
|
|
first_lp64_api = 21
|
|
latest_api = 23
|
|
|
|
for api in xrange(first_api, first_lp64_api):
|
|
if not os.path.exists(api_str(api)):
|
|
continue
|
|
|
|
for arch in ('arch-arm64', 'arch-mips64', 'arch-x86_64'):
|
|
src = os.path.join('..', api_str(first_lp64_api), arch)
|
|
dst = os.path.join(api_str(api), arch)
|
|
if os.path.islink(dst):
|
|
os.unlink(dst)
|
|
os.symlink(src, dst)
|
|
|
|
symlink_gaps(first_api, latest_api)
|
|
os.chdir(old_dir)
|
|
|
|
|
|
def commit(branch, build, install_dir):
|
|
logger().info('Making commit')
|
|
check_call(['git', 'add', install_dir])
|
|
message = textwrap.dedent("""\
|
|
Update NDK prebuilts to build {build}.
|
|
|
|
Taken from branch {branch}.""").format(branch=branch, build=build)
|
|
check_call(['git', 'commit', '-m', message])
|
|
|
|
|
|
def get_args():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
'-b', '--branch', default='master-ndk',
|
|
help='Branch to pull build from.')
|
|
parser.add_argument(
|
|
'major_release', help='Major release being installed, e.g. "r11".')
|
|
parser.add_argument('--build', required=True, help='Build number to pull.')
|
|
parser.add_argument(
|
|
'--use-current-branch', action='store_true',
|
|
help='Perform the update in the current branch. Do not repo start.')
|
|
parser.add_argument(
|
|
'-v', '--verbose', action='count', help='Increase output verbosity.')
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
os.chdir(THIS_DIR)
|
|
|
|
args = get_args()
|
|
verbose_map = (logging.WARNING, logging.INFO, logging.DEBUG)
|
|
verbosity = args.verbose
|
|
if verbosity > 2:
|
|
verbosity = 2
|
|
logging.basicConfig(level=verbose_map[verbosity])
|
|
|
|
install_dir = os.path.realpath(args.major_release)
|
|
|
|
if not args.use_current_branch:
|
|
start_branch(args.build)
|
|
remove_old_release(install_dir)
|
|
install_new_release(args.branch, args.build, install_dir)
|
|
make_symlinks(install_dir)
|
|
commit(args.branch, args.build, install_dir)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|