blob: 3b708708c099942684186f11f2745a703b2a3497 [file] [log] [blame]
#!/usr/bin/python
#
# Copyright 2014 Google Inc. All Rights Reserved.
import argparse
import os
import re
import shutil
import subprocess
import sys
import zipfile
ANDROID_SYSTEM_JAR = "android_system.jar"
ANDROID_JAR = "android.jar"
parser = argparse.ArgumentParser(
description=('Update prebuilt android SDK'))
parser.add_argument(
'buildId',
type=int,
nargs='?',
help='Build server build ID')
parser.add_argument(
'--target',
default='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)
platformZipRE = re.compile(r'^sdk-repo-linux-platforms-.*\.zip$')
platformZipFile = None
for fname in listing:
if platformZipRE.match(fname):
platformZipFile = fname
break
if not platformZipFile:
src = 'directory' if args.localDir else 'build'
print >> sys.stderr, "FAIL: The specified %s contains no platform ZIP" % src
sys.exit(1)
try:
FetchFile(platformZipFile, platformZipFile)
FetchFile(ANDROID_SYSTEM_JAR, ANDROID_JAR)
except:
print >> sys.stderr, "FAIL: Unable to fetch %s" % platformZipFile
sys.exit(1)
try: # make sure we delete the downloaded ZIP
PLATFORM_DIRS = [
('android-5.0/data', 'data'),
('android-5.0/skins', 'skins'),
('android-5.0/templates', 'templates'),
]
PLATFORM_FILES = [
('android-5.0/build.prop', 'build.prop'),
('android-5.0/framework.aidl', 'framework.aidl'),
('android-5.0/sdk.properties', 'sdk.properties'),
('android-5.0/source.properties', 'source.properties'),
('android-5.0/uiautomator.jar', 'uiautomator.jar'),
]
subprocess.check_call(['git', 'add', ANDROID_JAR])
with zipfile.ZipFile(platformZipFile) as platformZip:
for fileEntry in PLATFORM_FILES:
if os.path.exists(fileEntry[1]):
if os.path.isdir(fileEntry[1]):
subprocess.check_call(['git', 'rm', '-rf', fileEntry[1]])
else:
subprocess.check_call(['git', 'rm', fileEntry[1]])
with platformZip.open(fileEntry[0], 'r') as infile:
with open(fileEntry[1], 'w+') as outfile:
shutil.copyfileobj(infile, outfile)
subprocess.check_call(['git', 'add', fileEntry[1]])
for dirEntry in PLATFORM_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 platformZip.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 platformZip.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 build.prop and source.properties
subprocess.check_call(['sed', '-i', 's/AndroidVersion.ApiLevel=20/AndroidVersion.ApiLevel=21/',
'source.properties'])
subprocess.check_call(['sed', '-i', '/AndroidVersion.CodeName=L/d', 'source.properties'])
subprocess.check_call(['sed', '-i',
's/ro.build.version.sdk=20/ro.build.version.sdk=21/', 'build.prop'])
subprocess.check_call(['sed', '-i',
's/ro.build.version.codename=L/ro.build.version.codename=REL/', 'build.prop'])
subprocess.check_call(['git', 'add', 'source.properties'])
subprocess.check_call(['git', 'add', 'build.prop'])
if not args.no_git:
# commit all changes
if not args.localDir:
# gather useful info
buildInfo = dict(
buildURL = buildURL,
buildId = args.buildId,
branch = branch,
platformZipFile = platformZipFile,
androidJar = ANDROID_SYSTEM_JAR,
)
msg = """Import L SDK from {branch} build {buildId}
{buildURL}/{platformZipFile}
{buildURL}/{androidJar}
build.prop & source.properties have been modified to make this appear
as API 21
android_system.jar has been submitted as android.jar
""".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 the support library as well.'
if args.target == 'sdk':
print '\tcd support && ./update_support_libs.py %s' % (args.buildId)
else:
print '\tcd support && ./update_support_libs.py --target %s %s' % (args.target,
args.buildId)
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!!!"