blob: aab86309959ccedeff6b9adea85ea5226adecbde [file] [log] [blame]
Dan Albert74cf8ec2016-04-25 16:29:11 -07001#!/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#
17import argparse
18import glob
19import logging
20import os
21import shutil
22import subprocess
23import textwrap
24
25
26THIS_DIR = os.path.realpath(os.path.dirname(__file__))
27
28
29def logger():
30 return logging.getLogger(__name__)
31
32
33def check_call(cmd):
34 logger().debug('Running `%s`', ' '.join(cmd))
35 subprocess.check_call(cmd)
36
37
Dan Albert260ec6d2017-12-11 11:41:18 -080038def remove(path):
39 logger().debug('remove `%s`', path)
40 os.remove(path)
41
42
Dan Albert74cf8ec2016-04-25 16:29:11 -070043def fetch_artifact(branch, build, pattern):
44 fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
45 cmd = [fetch_artifact_path, '--branch', branch, '--target=linux',
46 '--bid', build, pattern]
47 check_call(cmd)
48
49
50def api_str(api_level):
51 return 'android-{}'.format(api_level)
52
53
54def start_branch(build):
55 branch_name = 'update-' + (build or 'latest')
56 logger().info('Creating branch %s', branch_name)
57 check_call(['repo', 'start', branch_name, '.'])
58
59
60def remove_old_release(install_dir):
61 if os.path.exists(os.path.join(install_dir, '.git')):
62 logger().info('Removing old install directory "%s"', install_dir)
63 check_call(['git', 'rm', '-rf', install_dir])
64
65 # Need to check again because git won't remove directories if they have
66 # non-git files in them.
67 if os.path.exists(install_dir):
68 shutil.rmtree(install_dir)
69
70
71def install_new_release(branch, build, install_dir):
72 os.makedirs(install_dir)
73
74 artifact_pattern = 'android-ndk-*.tar.bz2'
75 logger().info('Fetching %s from %s (artifacts matching %s)', build, branch,
76 artifact_pattern)
77 fetch_artifact(branch, build, artifact_pattern)
78 artifacts = glob.glob('android-ndk-*.tar.bz2')
79 try:
80 assert len(artifacts) == 1
81 artifact = artifacts[0]
82
83 logger().info('Extracting release')
84 cmd = ['tar', 'xf', artifact, '-C', install_dir, '--wildcards',
85 '--strip-components=1', '*/platforms', '*/sources',
86 '*/source.properties']
87 check_call(cmd)
88 finally:
89 for artifact in artifacts:
90 os.unlink(artifact)
91
92
Dan Albert260ec6d2017-12-11 11:41:18 -080093def remove_unneeded_files(install_dir):
94 for path, _dirs, files in os.walk(os.path.join(install_dir, 'platforms')):
95 for file_name in files:
96 if file_name.endswith('.so'):
97 file_path = os.path.join(path, file_name)
98 remove(file_path)
99
100 for path, _dirs, files in os.walk(os.path.join(install_dir, 'sources')):
101 for file_name in files:
102 if file_name == 'Android.bp':
103 file_path = os.path.join(path, file_name)
104 remove(file_path)
105
106
Dan Albert74cf8ec2016-04-25 16:29:11 -0700107def make_symlinks(install_dir):
108 old_dir = os.getcwd()
109 os.chdir(os.path.join(THIS_DIR, install_dir, 'platforms'))
110
111 first_api = 9
112 first_lp64_api = 21
Dan Albert74cf8ec2016-04-25 16:29:11 -0700113
114 for api in xrange(first_api, first_lp64_api):
115 if not os.path.exists(api_str(api)):
116 continue
117
118 for arch in ('arch-arm64', 'arch-mips64', 'arch-x86_64'):
119 src = os.path.join('..', api_str(first_lp64_api), arch)
120 dst = os.path.join(api_str(api), arch)
121 if os.path.islink(dst):
122 os.unlink(dst)
123 os.symlink(src, dst)
124
Dan Albert74cf8ec2016-04-25 16:29:11 -0700125 os.chdir(old_dir)
126
127
128def commit(branch, build, install_dir):
129 logger().info('Making commit')
130 check_call(['git', 'add', install_dir])
131 message = textwrap.dedent("""\
132 Update NDK prebuilts to build {build}.
133
134 Taken from branch {branch}.""").format(branch=branch, build=build)
135 check_call(['git', 'commit', '-m', message])
136
137
138def get_args():
139 parser = argparse.ArgumentParser()
140 parser.add_argument(
141 '-b', '--branch', default='master-ndk',
142 help='Branch to pull build from.')
143 parser.add_argument(
144 'major_release', help='Major release being installed, e.g. "r11".')
145 parser.add_argument('--build', required=True, help='Build number to pull.')
146 parser.add_argument(
147 '--use-current-branch', action='store_true',
148 help='Perform the update in the current branch. Do not repo start.')
149 parser.add_argument(
Dan Albert7c75aef2017-09-18 14:38:38 -0700150 '-v', '--verbose', action='count', default=0,
151 help='Increase output verbosity.')
Dan Albert74cf8ec2016-04-25 16:29:11 -0700152 return parser.parse_args()
153
154
155def main():
156 os.chdir(THIS_DIR)
157
158 args = get_args()
159 verbose_map = (logging.WARNING, logging.INFO, logging.DEBUG)
160 verbosity = args.verbose
161 if verbosity > 2:
162 verbosity = 2
163 logging.basicConfig(level=verbose_map[verbosity])
164
165 install_dir = os.path.realpath(args.major_release)
166
167 if not args.use_current_branch:
168 start_branch(args.build)
169 remove_old_release(install_dir)
170 install_new_release(args.branch, args.build, install_dir)
Dan Albert260ec6d2017-12-11 11:41:18 -0800171 remove_unneeded_files(install_dir)
Dan Albert74cf8ec2016-04-25 16:29:11 -0700172 make_symlinks(install_dir)
173 commit(args.branch, args.build, install_dir)
174
175
176if __name__ == '__main__':
177 main()