• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2
3import argparse
4import os
5import re
6import subprocess
7import sys
8import tempfile
9import zipfile
10
11from collections import defaultdict
12
13# See go/fetch_artifact for details on this script.
14FETCH_ARTIFACT = '/google/data/ro/projects/android/fetch_artifact'
15BUILD_TARGET = 'mainline_modules-userdebug'
16ARTIFACT_PATTERN = 'mainline-sdks/*-%d.zip'
17COMMIT_TEMPLATE = """Finalize artifacts for extension SDK %d
18
19Import from build id %s.
20
21Generated with:
22$ %s
23
24Bug: %d
25Test: presubmit"""
26
27def fail(*args, **kwargs):
28    print(*args, file=sys.stderr, **kwargs)
29    sys.exit(1)
30
31def fetch_artifacts(target, build_id, artifact_path):
32    tmpdir = tempfile.TemporaryDirectory().name
33    os.mkdir(tmpdir)
34    print('Fetching %s from %s ...' % (artifact_path, target))
35    fetch_cmd = [FETCH_ARTIFACT]
36    fetch_cmd.extend(['--bid', str(build_id)])
37    fetch_cmd.extend(['--target', target])
38    fetch_cmd.append(artifact_path)
39    fetch_cmd.append(tmpdir)
40    print("Running: " + ' '.join(fetch_cmd))
41    try:
42        subprocess.check_output(fetch_cmd, stderr=subprocess.STDOUT)
43    except subprocess.CalledProcessError:
44        fail('FAIL: Unable to retrieve %s artifact for build ID %s' % (artifact_path, build_id))
45    return tmpdir
46
47def repo_for_sdk(filename):
48    module = filename.split('-')[0]
49    target_dir = ''
50    if module == 'media': return 'prebuilts/module_sdk/Media'
51    if module == 'tethering': return 'prebuilts/module_sdk/Connectivity'
52    for dir in os.listdir('prebuilts/module_sdk/'):
53        if module.lower() in dir.lower():
54            if target_dir:
55                fail('Multiple target dirs matched "%s": %s' % (module, (target_dir, dir)))
56            target_dir = dir
57    if not target_dir:
58        fail('Could not find a target dir for %s' % filename)
59
60    return 'prebuilts/module_sdk/%s' % target_dir
61
62def dir_for_sdk(filename, version):
63    base = str(version)
64    if 'test-exports' in filename:
65        return os.path.join(base, 'test-exports')
66    if 'host-exports' in filename:
67        return os.path.join(base, 'host-exports')
68    return base
69
70if not os.path.isdir('build/soong'):
71    fail("This script must be run from the top of an Android source tree.")
72
73parser = argparse.ArgumentParser(description=('Finalize an extension SDK with prebuilts'))
74parser.add_argument('-f', '--finalize_sdk', type=int, required=True, help='The numbered SDK to finalize.')
75parser.add_argument('-b', '--bug', type=int, required=True, help='The bug number to add to the commit message.')
76parser.add_argument('-a', '--amend_last_commit', action="store_true", help='Amend current HEAD commits instead of making new commits.')
77parser.add_argument('bid', help='Build server build ID')
78args = parser.parse_args()
79
80branch_name = 'finalize-%d' % args.finalize_sdk
81cmdline = " ".join(filter(lambda x: x not in ['-a', '--amend_last_commit'], sys.argv))
82commit_message = COMMIT_TEMPLATE % (args.finalize_sdk, args.bid, cmdline, args.bug)
83
84tmpdir = fetch_artifacts(BUILD_TARGET, args.bid, ARTIFACT_PATTERN % args.finalize_sdk)
85
86created_dirs = defaultdict(list)
87
88for f in os.listdir(tmpdir):
89    repo = repo_for_sdk(f)
90    dir = dir_for_sdk(f, args.finalize_sdk)
91    target_dir = os.path.join(repo, dir)
92    if os.path.isfile(target_dir):
93        print('Removing existing dir %s' % target_dir)
94        shutil.rmtree(target_dir)
95    with zipfile.ZipFile(os.path.join(tmpdir, f)) as zipFile:
96        zipFile.extractall(target_dir)
97
98    print('Created %s' % target_dir)
99    created_dirs[repo].append(dir)
100
101subprocess.check_output(['repo', 'start', branch_name] + list(created_dirs.keys()))
102print('Running git commit')
103for repo in created_dirs:
104    git = ['git', '-C', repo]
105    subprocess.check_output(git + ['add'] + created_dirs[repo])
106    if args.amend_last_commit:
107        change_id = '\n' + re.search(r'Change-Id: [^\\n]+', str(subprocess.check_output(git + ['log', '-1']))).group(0)
108        subprocess.check_output(git + ['commit', '--amend', '-m', commit_message + change_id])
109    else:
110        subprocess.check_output(git + ['commit', '-m', commit_message])
111