#!/usr/bin/env python3 # # Copyright 2020 - The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Creates the xml files. Usage example: vcs = XMLGenerator(module_path, 'vcs.xml') if not vcs.xml_obj: # Create the file directly. common_util.file_generate(vcs.xml_abspath, xml_content) else: # Add/remove elements to vcs.xml_obj by the methods of # ElementTree.Element object. vcs.xml_obj.append() vcs.xml_obj.makeelement() vcs.xml_obj.remove() # Update the XML content. vcs.create_xml() """ from __future__ import absolute_import import os from xml.etree import ElementTree from aidegen import constant from aidegen import templates from aidegen.lib import aidegen_metrics from aidegen.lib import common_util from aidegen.lib import xml_util _GIT_PATH = ' ' _IGNORE_PATH = ' ' class XMLGenerator: """Creates the xml file. Attributes: _xml_abspath: A string of the XML's absolute path. _xml_obj: An ElementTree object. """ def __init__(self, module_abspath, xml_name): """Initializes XMLGenerator. Args: module_abspath: A string of the module's absolute path. xml_name: A string of the xml file name. """ self._xml_abspath = os.path.join(module_abspath, constant.IDEA_FOLDER, xml_name) self._xml_obj = None self.parse() def parse(self): """Parses the XML file to an ElementTree object.""" if os.path.exists(self._xml_abspath): self._xml_obj = xml_util.parse_xml(self._xml_abspath) @property def xml_path(self): """Gets the xml absolute path.""" return self._xml_abspath @property def xml_obj(self): """Gets the xml object.""" return self._xml_obj def find_elements_by_name(self, element_type, name): """Finds the target elements by name attribute. Args: element_type: A string of element's type. name: A string of element's name. Return: List: ElementTree's element objects. """ return [e for e in self._xml_obj.findall(element_type) if e.get('name') == name] @staticmethod def append_node(parent, node_str): """Appends a node string under the parent element. Args: parent: An element object, the new node's parent. node_str: A string, the new node's content. """ try: parent.append(ElementTree.fromstring(node_str)) except ElementTree.ParseError as xml_err: aidegen_metrics.send_exception_metrics( exit_code=constant.XML_PARSING_FAILURE, stack_trace=xml_err, log=node_str, err_msg='') def create_xml(self): """Creates the xml file.""" common_util.file_generate(self._xml_abspath, common_util.to_pretty_xml( self._xml_obj.getroot())) def gen_vcs_xml(module_path, git_paths): """Writes the git path into the .idea/vcs.xml. For main module, the vcs.xml should include all modules' git path. For the whole AOSP case, ignore creating the vcs.xml. Instead, add the ignored Git paths in the workspace.xml. Args: module_path: A string, the absolute path of the module. git_paths: A list of git paths. """ git_mappings = [_GIT_PATH.format(GIT_DIR=p) for p in git_paths if p] vcs = XMLGenerator(module_path, 'vcs.xml') if module_path != common_util.get_android_root_dir() or not vcs.xml_obj: common_util.file_generate(vcs.xml_path, templates.XML_VCS.format( GIT_MAPPINGS='\n'.join(git_mappings))) def write_ignore_git_dirs_file(module_path, ignore_paths): """Write the ignored git paths in the .idea/workspace.xml. Args: module_path: A string, the absolute path of the module. ignore_paths: A list of git paths. """ ignores = [_IGNORE_PATH.format(GIT_DIR=p) for p in ignore_paths] workspace = XMLGenerator(module_path, 'workspace.xml') if not workspace.xml_obj: common_util.file_generate(workspace.xml_path, templates.XML_WORKSPACE.format( GITS=''.join(ignores))) return for conf in workspace.find_elements_by_name('component', 'VcsManagerConfiguration'): workspace.xml_obj.getroot().remove(conf) workspace.append_node(workspace.xml_obj.getroot(), templates.IGNORED_GITS.format(GITS=''.join(ignores))) workspace.create_xml()