blob: 28b3175513e1521dc2c3a7a5e0d71d3d9a75043c [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2018 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.
#
# pylint: disable=relative-import
"""Update the prebuilt lldb from the build server."""
import argparse
import inspect
import logging
import os
import shutil
import subprocess
import sys
import utils
def logger():
"""Returns the module level logger."""
return logging.getLogger(__name__)
def unchecked_call(cmd, *args, **kwargs):
"""subprocess.call with logging."""
logger().info('unchecked_call: %s', subprocess.list2cmdline(cmd))
return subprocess.call(cmd, *args, **kwargs)
def check_call(cmd, *args, **kwargs):
"""subprocess.check_call with logging."""
logger().info('check_call: %s', subprocess.list2cmdline(cmd))
subprocess.check_call(cmd, *args, **kwargs)
class ArgParser(argparse.ArgumentParser):
def __init__(self):
super(ArgParser, self).__init__(
description=inspect.getdoc(sys.modules[__name__]))
self.add_argument(
'build', metavar='BUILD',
help='Build number to pull from the build server.')
self.add_argument(
'-b', '--bug', type=int,
help='Bug to reference in commit message.')
self.add_argument(
'--use-current-branch', action='store_true',
help='Do not repo start a new branch for the update.')
self.add_argument(
'--skip-fetch',
'-sf',
action='store_true',
default=False,
help='Skip the fetch, and only do the extraction step')
self.add_argument(
'--skip-cleanup',
'-sc',
action='store_true',
default=False,
help='Skip the cleanup, and leave intermediate files')
def fetch_artifact(branch, target, build, pattern):
fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
cmd = [fetch_artifact_path, '--branch={}'.format(branch),
'--target={}'.format(target), '--bid={}'.format(build), pattern]
check_call(cmd)
def get_lldb_package(target, build_number):
return 'lldb-{}-{}.zip'.format(target[1], build_number)
def get_android_package(build_number):
return 'lldb-android-{}.zip'.format(build_number)
def get_manifest(build_number):
return 'manifest_{}.xml'.format(build_number)
def extract_package(package, install_dir):
cmd = ['unzip', package, '-d', install_dir]
check_call(cmd)
def update_lldb(target, build_number, use_current_branch, download_dir, bug):
prebuilt_dir = utils.android_path('prebuilts/clang/host',
target[1] + '-x86')
os.chdir(prebuilt_dir)
install_subdir = os.path.join(prebuilt_dir, 'lldb')
if not use_current_branch:
branch_name = 'update-lldb-{}'.format(build_number)
unchecked_call(
['repo', 'abandon', branch_name, '.'])
check_call(
['repo', 'start', branch_name, '.'])
package = os.path.join(download_dir, get_lldb_package(target, build_number))
if os.path.isdir(install_subdir):
shutil.rmtree(install_subdir)
os.makedirs(install_subdir)
extract_package(package, install_subdir)
android_package = os.path.join(download_dir,
get_android_package(build_number))
android_dir = os.path.join(install_subdir, "android")
os.makedirs(android_dir)
extract_package(android_package, android_dir)
manifest = os.path.join(download_dir, get_manifest(build_number))
shutil.copy(manifest, install_subdir)
check_call(['git', 'add', install_subdir])
# If there is no difference with the new files, we are already done.
diff = unchecked_call(['git', 'diff', '--cached', '--quiet'])
if diff == 0:
logger().info('Bypassed commit with no diff')
return
message_lines = [
'Update prebuilt LLDB to build {}.'.format(build_number),
]
if bug is not None:
message_lines.append('')
message_lines.append('Bug: http://b/{}'.format(bug))
message_lines.append('Test: N/A')
message = '\n'.join(message_lines)
check_call(['git', 'commit', '-m', message])
def fetch(targets, build_number):
branch = 'git_lldb-master-dev'
fetch_artifact(branch, targets[0][0], build_number,
get_android_package(build_number))
for target in targets:
fetch_artifact(branch, target[0], build_number,
get_manifest(build_number))
fetch_artifact(branch, target[0], build_number,
get_lldb_package(target, build_number))
def main():
args = ArgParser().parse_args()
logging.basicConfig(level=logging.INFO)
do_fetch = not args.skip_fetch
do_cleanup = not args.skip_cleanup
download_dir = os.path.realpath('.download')
if do_fetch:
if os.path.isdir(download_dir):
shutil.rmtree(download_dir)
os.makedirs(download_dir)
os.chdir(download_dir)
targets = [['lldb', 'linux']]
try:
if do_fetch:
fetch(targets, args.build)
for target in targets:
update_lldb(target, args.build, args.use_current_branch,
download_dir, args.bug)
finally:
if do_cleanup:
shutil.rmtree(download_dir)
return 0
if __name__ == '__main__':
main()