From d2d4171ae36a8b4a5d3a0b1cfae8dcd0f17a2969 Mon Sep 17 00:00:00 2001 From: Qiwen Zhao Date: Fri, 10 Apr 2015 09:42:04 -0700 Subject: add update script. --- update_build_tools.py | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100755 update_build_tools.py diff --git a/update_build_tools.py b/update_build_tools.py new file mode 100755 index 0000000..671ce14 --- /dev/null +++ b/update_build_tools.py @@ -0,0 +1,192 @@ +#!/usr/bin/python +# +# Copyright 2014 Google Inc. All Rights Reserved. + +import argparse +import os +import re +import shutil +import subprocess +import sys +import zipfile + +parser = argparse.ArgumentParser( + description=('Update prebuilt android build tools')) +parser.add_argument( + 'buildId', + type=int, + nargs='?', + help='Build server build ID') +parser.add_argument( + '--target', + default='sdk_phone_armv7-win_sdk', + help='Download from the specified build server target') +parser.add_argument( + '--from-local-dir', + dest='localDir', + help='Copy prebuilts from local directory instead of buildserver') +parser.add_argument( + '--no-git', + action='store_true', + help='Do not create a git commit for the import') +args = parser.parse_args() + +if not args.buildId and not args.localDir: + parser.error("you must specify either a build ID or --from-local-dir") + sys.exit(1) + + +if not args.no_git: + # Make sure we don't overwrite any pending changes + try: + subprocess.check_call(['git', 'diff', '--quiet', '--', '**']) + subprocess.check_call(['git', 'diff', '--quiet', '--cached', '--', '**']) + except subprocess.CalledProcessError: + print >> sys.stderr, "FAIL: There are uncommitted changes here; please revert or stash" + sys.exit(1) + + +def GetSSOCmdline(url): + return ['sso_client', '--location', '--request_timeout', '90', '--url', url] +def SSOFetch(url): + return subprocess.check_output(GetSSOCmdline(url), stderr=subprocess.STDOUT) +def FetchFile(srcFile, dstFile): + if not args.localDir: + fileURL = buildURL + '/' + srcFile + subprocess.check_call(' '.join(GetSSOCmdline(fileURL) + ['>', dstFile]), shell=True) + else: + shutil.copyfile(os.path.join(args.localDir, srcFile), dstFile) + + +if not args.localDir: + # to start, find the build server branch we're downloading from + try: + branch = SSOFetch("http://android-build/buildbot-update?op=GET-BRANCH&bid=%d" % args.buildId) + except subprocess.CalledProcessError: + print >> sys.stderr, "FAIL: Unable to retrieve branch for build ID %d" % args.buildId + sys.exit(1) + buildURL = "http://android-build/builds/%s-linux-%s/%d" % (branch, args.target, args.buildId) + + # fetch the list build artifacts + try: + listingText = SSOFetch(buildURL + "?output=text") + except subprocess.CalledProcessError: + print >> sys.stderr, "FAIL: Unable to retrieve listing for build ID %d" % args.buildId + sys.exit(1) + + listing = listingText.strip().split('\n') +else: + listing = os.listdir(args.localDir) + + +buildToolsZipRE = re.compile(r'^sdk-repo-linux-build-tools-.*\.zip$') +buildToolsZipFile = None +for fname in listing: + if buildToolsZipRE.match(fname): + buildToolsZipFile = fname + break +if not buildToolsZipFile: + src = 'directory' if args.localDir else 'build' + print >> sys.stderr, "FAIL: The specified %s contains no platform ZIP" % src + sys.exit(1) + +try: + FetchFile(buildToolsZipFile, buildToolsZipFile) +except: + print >> sys.stderr, "FAIL: Unable to fetch %s" % buildToolsZipFile + sys.exit(1) + + +try: # make sure we delete the downloaded ZIP + BUILD_TOOLS_DIRS = [ + ('android-5.1/lib', 'lib'), + ('android-5.1/renderscript', 'renderscript'), + ] + + executableMap = {} + with zipfile.ZipFile(buildToolsZipFile) as buildToolsZip: + files = filter(lambda x: x.count('/') == 1 and not x[-1] == '/', buildToolsZip.namelist()) + for fileEntry in map(lambda x: (x, x[x.find('/')+1:]) , files): + executable = False + if os.path.exists(fileEntry[1]): + if os.path.isdir(fileEntry[1]): + subprocess.check_call(['git', 'rm', '-rf', fileEntry[1]]) + else: + executable = os.access(fileEntry[1], os.X_OK) + subprocess.check_call(['git', 'rm', fileEntry[1]]) + + with buildToolsZip.open(fileEntry[0], 'r') as infile: + with open(fileEntry[1], 'w+') as outfile: + shutil.copyfileobj(infile, outfile) + if executable: + subprocess.check_call(['chmod', '+x', fileEntry[1]]) + subprocess.check_call(['git', 'add', fileEntry[1]]) + + for dirEntry in BUILD_TOOLS_DIRS: + if os.path.exists(dirEntry[1]): + if os.path.isdir(dirEntry[1]): + subprocess.check_call(['git', 'rm', '-rf', dirEntry[1]]) + else: + subprocess.check_call(['git', 'rm', dirEntry[1]]) + + # extract the new version of the directory + fileZipDir = dirEntry[0] + '/' + + for fname in buildToolsZip.namelist(): + if (fname[-1] != '/' + and fname.startswith(dirEntry[0])): + relativePath = fname[len(fileZipDir):] + subdirs = os.path.join(dirEntry[1], os.path.dirname(relativePath)) + if not os.path.exists(subdirs): + os.makedirs(subdirs) + with buildToolsZip.open(fname, 'r') as infile: + with open(os.path.join(dirEntry[1], relativePath), 'w+') as outfile: + shutil.copyfileobj(infile, outfile) + + subprocess.check_call(['git', 'add', dirEntry[1]]) + + # modify the source.properties + subprocess.check_call(['sed', '-i', 's/Pkg.Revision=/\/\/Pkg.Revision=/', + 'source.properties']) + + subprocess.check_call(' '.join(['echo', '-e', + '"Archive.Os=LINUX\nPkg.Revision=22.0.0\nArchive.Arch=ANY"'] + + ['>>', 'source.properties']), shell=True) + + subprocess.check_call(['git', 'add', 'source.properties']) + + if not args.no_git: + # commit all changes + if not args.localDir: + # gather useful info + buildInfo = dict( + buildURL = buildURL, + buildId = args.buildId, + branch = branch, + buildToolsZipFile = buildToolsZipFile, + ) + msg = """Import L Build Tools from {branch} build {buildId} + +{buildURL}/{buildToolsZipFile} + +source.properties has been modified to make this appear as API 22 +""".format(**buildInfo) + else: + msg = "DO NOT SUBMIT Import locally built android platform from %s" % args.localDir + + subprocess.check_call(['git', 'commit', '-m', msg]) + print 'Update successful.' + + if not args.localDir: + print 'Be sure to upload this manually to gerrit.' + +finally: + # revert all stray files, including the downloaded zip + try: + with open(os.devnull, 'w') as bitbucket: + subprocess.check_call(['git', 'add', '-Af', '.'], stdout=bitbucket) + subprocess.check_call( + ['git', 'commit', '-m', 'COMMIT TO REVERT - RESET ME!!!'], stdout=bitbucket) + subprocess.check_call(['git', 'reset', '--hard', 'HEAD~1'], stdout=bitbucket) + except subprocess.CalledProcessError: + print >> sys.stderr, "ERROR: Failed cleaning up, manual cleanup required!!!" -- cgit v1.2.3