1#!/usr/bin/env python 2# Copyright (c) 2013 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Generate local manifest in an Android repository. 7 8This is used to generate a local manifest in an Android repository. The purpose 9of the generated manifest is to remove the set of projects that exist under a 10certain path. 11""" 12 13from optparse import OptionParser 14import os 15import xml.etree.ElementTree as ET 16 17def createLocalManifest(manifest_path, local_manifest_path, path_to_exclude, 18 pinned_projects=None): 19 manifest_tree = ET.parse(manifest_path) 20 local_manifest_root = ET.Element('manifest') 21 22 def remove_project(project): 23 remove_project = ET.SubElement(local_manifest_root, 'remove-project') 24 remove_project.set('name', project.get('name')) 25 26 def pin_project(project, revision): 27 pin_project = ET.SubElement(local_manifest_root, 'project') 28 pin_project.set('name', project.get('name')) 29 if project.get('path') != None: 30 pin_project.set('path', project.get('path')) 31 pin_project.set('revision', revision) 32 33 for project in manifest_tree.getroot().findall('project'): 34 project_path = project.get('path') 35 project_name = project.get('name') 36 exclude_project = ((project_path != None and 37 project_path.startswith(path_to_exclude)) or 38 (project_path == None and 39 project_name.startswith(path_to_exclude))) 40 if exclude_project: 41 print 'Excluding project name="%s" path="%s"' % (project_name, 42 project_path) 43 remove_project(project) 44 continue 45 46 pinned_projects = pinned_projects or [] 47 for pinned in pinned_projects: 48 if pinned['path'] == project_path and pinned['name'] == project_name: 49 remove_project(project) 50 pin_project(project, pinned['revision']) 51 break 52 53 local_manifest_tree = ET.ElementTree(local_manifest_root) 54 local_manifest_dir = os.path.dirname(local_manifest_path) 55 if not os.path.exists(local_manifest_dir): 56 os.makedirs(local_manifest_dir) 57 local_manifest_tree.write(local_manifest_path, 58 xml_declaration=True, 59 encoding='UTF-8', 60 method='xml') 61 62def main(): 63 usage = 'usage: %prog [options] <android_build_top> <path_to_exclude>' 64 parser = OptionParser(usage=usage) 65 parser.add_option('--ndk-revision', dest='ndk_revision', 66 help='pin the ndk project at a particular REVISION', 67 metavar='REVISION', default=None) 68 parser.add_option('--manifest_filename', dest='manifest_filename', 69 help='name of the manifest file', default='default.xml') 70 (options, args) = parser.parse_args() 71 72 if len(args) != 2: 73 parser.error('Wrong number of arguments.') 74 75 android_build_top = args[0] 76 path_to_exclude = args[1] 77 78 manifest_filename = options.manifest_filename 79 80 manifest_path = os.path.join(android_build_top, '.repo/manifests', 81 manifest_filename) 82 local_manifest_path = os.path.join(android_build_top, 83 '.repo/local_manifest.xml') 84 85 pinned_projects = [] 86 if options.ndk_revision: 87 pinned_projects = [{ 88 'path': 'ndk', 89 'name': 'platform/ndk', 90 'revision' : options.ndk_revision, 91 },] 92 93 print 'Path to exclude: %s' % path_to_exclude 94 print 'Path to manifest file: %s' % manifest_path 95 createLocalManifest(manifest_path, local_manifest_path, path_to_exclude, 96 pinned_projects) 97 print 'Local manifest created in: %s' % local_manifest_path 98 99if __name__ == '__main__': 100 main() 101