1*c2e18aaaSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*c2e18aaaSAndroid Build Coastguard Worker# 3*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2020 - The Android Open Source Project 4*c2e18aaaSAndroid Build Coastguard Worker# 5*c2e18aaaSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*c2e18aaaSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*c2e18aaaSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*c2e18aaaSAndroid Build Coastguard Worker# 9*c2e18aaaSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*c2e18aaaSAndroid Build Coastguard Worker# 11*c2e18aaaSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*c2e18aaaSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*c2e18aaaSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*c2e18aaaSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*c2e18aaaSAndroid Build Coastguard Worker# limitations under the License. 16*c2e18aaaSAndroid Build Coastguard Worker 17*c2e18aaaSAndroid Build Coastguard Worker"""Creates the xml files. 18*c2e18aaaSAndroid Build Coastguard Worker 19*c2e18aaaSAndroid Build Coastguard WorkerUsage example: 20*c2e18aaaSAndroid Build Coastguard Worker vcs = XMLGenerator(module_path, 'vcs.xml') 21*c2e18aaaSAndroid Build Coastguard Worker if not vcs.xml_obj: 22*c2e18aaaSAndroid Build Coastguard Worker # Create the file directly. 23*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(vcs.xml_abspath, xml_content) 24*c2e18aaaSAndroid Build Coastguard Worker else: 25*c2e18aaaSAndroid Build Coastguard Worker # Add/remove elements to vcs.xml_obj by the methods of 26*c2e18aaaSAndroid Build Coastguard Worker # ElementTree.Element object. 27*c2e18aaaSAndroid Build Coastguard Worker vcs.xml_obj.append() 28*c2e18aaaSAndroid Build Coastguard Worker vcs.xml_obj.makeelement() 29*c2e18aaaSAndroid Build Coastguard Worker vcs.xml_obj.remove() 30*c2e18aaaSAndroid Build Coastguard Worker # Update the XML content. 31*c2e18aaaSAndroid Build Coastguard Worker vcs.create_xml() 32*c2e18aaaSAndroid Build Coastguard Worker""" 33*c2e18aaaSAndroid Build Coastguard Worker 34*c2e18aaaSAndroid Build Coastguard Workerfrom __future__ import absolute_import 35*c2e18aaaSAndroid Build Coastguard Worker 36*c2e18aaaSAndroid Build Coastguard Workerimport os 37*c2e18aaaSAndroid Build Coastguard Worker 38*c2e18aaaSAndroid Build Coastguard Workerfrom xml.etree import ElementTree 39*c2e18aaaSAndroid Build Coastguard Worker 40*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant 41*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import templates 42*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import aidegen_metrics 43*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util 44*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import xml_util 45*c2e18aaaSAndroid Build Coastguard Worker 46*c2e18aaaSAndroid Build Coastguard Worker_GIT_PATH = ' <mapping directory="{GIT_DIR}" vcs="Git" />' 47*c2e18aaaSAndroid Build Coastguard Worker_IGNORE_PATH = ' <path value="{GIT_DIR}" />' 48*c2e18aaaSAndroid Build Coastguard Worker 49*c2e18aaaSAndroid Build Coastguard Worker 50*c2e18aaaSAndroid Build Coastguard Workerclass XMLGenerator: 51*c2e18aaaSAndroid Build Coastguard Worker """Creates the xml file. 52*c2e18aaaSAndroid Build Coastguard Worker 53*c2e18aaaSAndroid Build Coastguard Worker Attributes: 54*c2e18aaaSAndroid Build Coastguard Worker _xml_abspath: A string of the XML's absolute path. 55*c2e18aaaSAndroid Build Coastguard Worker _xml_obj: An ElementTree object. 56*c2e18aaaSAndroid Build Coastguard Worker """ 57*c2e18aaaSAndroid Build Coastguard Worker 58*c2e18aaaSAndroid Build Coastguard Worker def __init__(self, module_abspath, xml_name): 59*c2e18aaaSAndroid Build Coastguard Worker """Initializes XMLGenerator. 60*c2e18aaaSAndroid Build Coastguard Worker 61*c2e18aaaSAndroid Build Coastguard Worker Args: 62*c2e18aaaSAndroid Build Coastguard Worker module_abspath: A string of the module's absolute path. 63*c2e18aaaSAndroid Build Coastguard Worker xml_name: A string of the xml file name. 64*c2e18aaaSAndroid Build Coastguard Worker """ 65*c2e18aaaSAndroid Build Coastguard Worker self._xml_abspath = os.path.join(module_abspath, constant.IDEA_FOLDER, 66*c2e18aaaSAndroid Build Coastguard Worker xml_name) 67*c2e18aaaSAndroid Build Coastguard Worker self._xml_obj = None 68*c2e18aaaSAndroid Build Coastguard Worker self.parse() 69*c2e18aaaSAndroid Build Coastguard Worker 70*c2e18aaaSAndroid Build Coastguard Worker def parse(self): 71*c2e18aaaSAndroid Build Coastguard Worker """Parses the XML file to an ElementTree object.""" 72*c2e18aaaSAndroid Build Coastguard Worker if os.path.exists(self._xml_abspath): 73*c2e18aaaSAndroid Build Coastguard Worker self._xml_obj = xml_util.parse_xml(self._xml_abspath) 74*c2e18aaaSAndroid Build Coastguard Worker 75*c2e18aaaSAndroid Build Coastguard Worker @property 76*c2e18aaaSAndroid Build Coastguard Worker def xml_path(self): 77*c2e18aaaSAndroid Build Coastguard Worker """Gets the xml absolute path.""" 78*c2e18aaaSAndroid Build Coastguard Worker return self._xml_abspath 79*c2e18aaaSAndroid Build Coastguard Worker 80*c2e18aaaSAndroid Build Coastguard Worker @property 81*c2e18aaaSAndroid Build Coastguard Worker def xml_obj(self): 82*c2e18aaaSAndroid Build Coastguard Worker """Gets the xml object.""" 83*c2e18aaaSAndroid Build Coastguard Worker return self._xml_obj 84*c2e18aaaSAndroid Build Coastguard Worker 85*c2e18aaaSAndroid Build Coastguard Worker def find_elements_by_name(self, element_type, name): 86*c2e18aaaSAndroid Build Coastguard Worker """Finds the target elements by name attribute. 87*c2e18aaaSAndroid Build Coastguard Worker 88*c2e18aaaSAndroid Build Coastguard Worker Args: 89*c2e18aaaSAndroid Build Coastguard Worker element_type: A string of element's type. 90*c2e18aaaSAndroid Build Coastguard Worker name: A string of element's name. 91*c2e18aaaSAndroid Build Coastguard Worker 92*c2e18aaaSAndroid Build Coastguard Worker Return: 93*c2e18aaaSAndroid Build Coastguard Worker List: ElementTree's element objects. 94*c2e18aaaSAndroid Build Coastguard Worker """ 95*c2e18aaaSAndroid Build Coastguard Worker return [e for e in self._xml_obj.findall(element_type) 96*c2e18aaaSAndroid Build Coastguard Worker if e.get('name') == name] 97*c2e18aaaSAndroid Build Coastguard Worker 98*c2e18aaaSAndroid Build Coastguard Worker @staticmethod 99*c2e18aaaSAndroid Build Coastguard Worker def append_node(parent, node_str): 100*c2e18aaaSAndroid Build Coastguard Worker """Appends a node string under the parent element. 101*c2e18aaaSAndroid Build Coastguard Worker 102*c2e18aaaSAndroid Build Coastguard Worker Args: 103*c2e18aaaSAndroid Build Coastguard Worker parent: An element object, the new node's parent. 104*c2e18aaaSAndroid Build Coastguard Worker node_str: A string, the new node's content. 105*c2e18aaaSAndroid Build Coastguard Worker """ 106*c2e18aaaSAndroid Build Coastguard Worker try: 107*c2e18aaaSAndroid Build Coastguard Worker parent.append(ElementTree.fromstring(node_str)) 108*c2e18aaaSAndroid Build Coastguard Worker except ElementTree.ParseError as xml_err: 109*c2e18aaaSAndroid Build Coastguard Worker aidegen_metrics.send_exception_metrics( 110*c2e18aaaSAndroid Build Coastguard Worker exit_code=constant.XML_PARSING_FAILURE, stack_trace=xml_err, 111*c2e18aaaSAndroid Build Coastguard Worker log=node_str, err_msg='') 112*c2e18aaaSAndroid Build Coastguard Worker 113*c2e18aaaSAndroid Build Coastguard Worker def create_xml(self): 114*c2e18aaaSAndroid Build Coastguard Worker """Creates the xml file.""" 115*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(self._xml_abspath, common_util.to_pretty_xml( 116*c2e18aaaSAndroid Build Coastguard Worker self._xml_obj.getroot())) 117*c2e18aaaSAndroid Build Coastguard Worker 118*c2e18aaaSAndroid Build Coastguard Worker 119*c2e18aaaSAndroid Build Coastguard Workerdef gen_vcs_xml(module_path, git_paths): 120*c2e18aaaSAndroid Build Coastguard Worker """Writes the git path into the .idea/vcs.xml. 121*c2e18aaaSAndroid Build Coastguard Worker 122*c2e18aaaSAndroid Build Coastguard Worker For main module, the vcs.xml should include all modules' git path. 123*c2e18aaaSAndroid Build Coastguard Worker For the whole AOSP case, ignore creating the vcs.xml. Instead, add the 124*c2e18aaaSAndroid Build Coastguard Worker ignored Git paths in the workspace.xml. 125*c2e18aaaSAndroid Build Coastguard Worker 126*c2e18aaaSAndroid Build Coastguard Worker Args: 127*c2e18aaaSAndroid Build Coastguard Worker module_path: A string, the absolute path of the module. 128*c2e18aaaSAndroid Build Coastguard Worker git_paths: A list of git paths. 129*c2e18aaaSAndroid Build Coastguard Worker """ 130*c2e18aaaSAndroid Build Coastguard Worker git_mappings = [_GIT_PATH.format(GIT_DIR=p) for p in git_paths if p] 131*c2e18aaaSAndroid Build Coastguard Worker vcs = XMLGenerator(module_path, 'vcs.xml') 132*c2e18aaaSAndroid Build Coastguard Worker if module_path != common_util.get_android_root_dir() or not vcs.xml_obj: 133*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(vcs.xml_path, templates.XML_VCS.format( 134*c2e18aaaSAndroid Build Coastguard Worker GIT_MAPPINGS='\n'.join(git_mappings))) 135*c2e18aaaSAndroid Build Coastguard Worker 136*c2e18aaaSAndroid Build Coastguard Worker 137*c2e18aaaSAndroid Build Coastguard Workerdef write_ignore_git_dirs_file(module_path, ignore_paths): 138*c2e18aaaSAndroid Build Coastguard Worker """Write the ignored git paths in the .idea/workspace.xml. 139*c2e18aaaSAndroid Build Coastguard Worker 140*c2e18aaaSAndroid Build Coastguard Worker Args: 141*c2e18aaaSAndroid Build Coastguard Worker module_path: A string, the absolute path of the module. 142*c2e18aaaSAndroid Build Coastguard Worker ignore_paths: A list of git paths. 143*c2e18aaaSAndroid Build Coastguard Worker """ 144*c2e18aaaSAndroid Build Coastguard Worker ignores = [_IGNORE_PATH.format(GIT_DIR=p) for p in ignore_paths] 145*c2e18aaaSAndroid Build Coastguard Worker workspace = XMLGenerator(module_path, 'workspace.xml') 146*c2e18aaaSAndroid Build Coastguard Worker if not workspace.xml_obj: 147*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(workspace.xml_path, 148*c2e18aaaSAndroid Build Coastguard Worker templates.XML_WORKSPACE.format( 149*c2e18aaaSAndroid Build Coastguard Worker GITS=''.join(ignores))) 150*c2e18aaaSAndroid Build Coastguard Worker return 151*c2e18aaaSAndroid Build Coastguard Worker for conf in workspace.find_elements_by_name('component', 152*c2e18aaaSAndroid Build Coastguard Worker 'VcsManagerConfiguration'): 153*c2e18aaaSAndroid Build Coastguard Worker workspace.xml_obj.getroot().remove(conf) 154*c2e18aaaSAndroid Build Coastguard Worker workspace.append_node(workspace.xml_obj.getroot(), 155*c2e18aaaSAndroid Build Coastguard Worker templates.IGNORED_GITS.format(GITS=''.join(ignores))) 156*c2e18aaaSAndroid Build Coastguard Worker workspace.create_xml() 157