1*c2e18aaaSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*c2e18aaaSAndroid Build Coastguard Worker# 3*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2018 - 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"""It is an AIDEGen sub task : generate the project files. 18*c2e18aaaSAndroid Build Coastguard Worker 19*c2e18aaaSAndroid Build Coastguard Worker Usage example: 20*c2e18aaaSAndroid Build Coastguard Worker projects: A list of ProjectInfo instances. 21*c2e18aaaSAndroid Build Coastguard Worker ProjectFileGenerator.generate_ide_project_file(projects) 22*c2e18aaaSAndroid Build Coastguard Worker""" 23*c2e18aaaSAndroid Build Coastguard Worker 24*c2e18aaaSAndroid Build Coastguard Workerimport logging 25*c2e18aaaSAndroid Build Coastguard Workerimport os 26*c2e18aaaSAndroid Build Coastguard Workerimport shutil 27*c2e18aaaSAndroid Build Coastguard Worker 28*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant 29*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import templates 30*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.idea import iml 31*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.idea import xml_gen 32*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util 33*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import config 34*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import project_config 35*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.project import project_splitter 36*c2e18aaaSAndroid Build Coastguard Worker 37*c2e18aaaSAndroid Build Coastguard Worker# FACET_SECTION is a part of iml, which defines the framework of the project. 38*c2e18aaaSAndroid Build Coastguard Worker_MODULE_SECTION = (' <module fileurl="file:///$PROJECT_DIR$/%s.iml"' 39*c2e18aaaSAndroid Build Coastguard Worker ' filepath="$PROJECT_DIR$/%s.iml" />') 40*c2e18aaaSAndroid Build Coastguard Worker_SUB_MODULES_SECTION = (' <module fileurl="file:///{IML}" ' 41*c2e18aaaSAndroid Build Coastguard Worker 'filepath="{IML}" />') 42*c2e18aaaSAndroid Build Coastguard Worker_MODULE_TOKEN = '@MODULES@' 43*c2e18aaaSAndroid Build Coastguard Worker_ENABLE_DEBUGGER_MODULE_TOKEN = '@ENABLE_DEBUGGER_MODULE@' 44*c2e18aaaSAndroid Build Coastguard Worker_IDEA_FOLDER = '.idea' 45*c2e18aaaSAndroid Build Coastguard Worker_MODULES_XML = 'modules.xml' 46*c2e18aaaSAndroid Build Coastguard Worker_COPYRIGHT_FOLDER = 'copyright' 47*c2e18aaaSAndroid Build Coastguard Worker_INSPECTION_FOLDER = 'inspectionProfiles' 48*c2e18aaaSAndroid Build Coastguard Worker_CODE_STYLE_FOLDER = 'codeStyles' 49*c2e18aaaSAndroid Build Coastguard Worker_APACHE_2_XML = 'Apache_2.xml' 50*c2e18aaaSAndroid Build Coastguard Worker_PROFILES_SETTINGS_XML = 'profiles_settings.xml' 51*c2e18aaaSAndroid Build Coastguard Worker_CODE_STYLE_CONFIG_XML = 'codeStyleConfig.xml' 52*c2e18aaaSAndroid Build Coastguard Worker_INSPECTION_CONFIG_XML = 'Aidegen_Inspections.xml' 53*c2e18aaaSAndroid Build Coastguard Worker_JSON_SCHEMAS_CONFIG_XML = 'jsonSchemas.xml' 54*c2e18aaaSAndroid Build Coastguard Worker_PROJECT_XML = 'Project.xml' 55*c2e18aaaSAndroid Build Coastguard Worker_COMPILE_XML = 'compiler.xml' 56*c2e18aaaSAndroid Build Coastguard Worker_MISC_XML = 'misc.xml' 57*c2e18aaaSAndroid Build Coastguard Worker_CONFIG_JSON = 'config.json' 58*c2e18aaaSAndroid Build Coastguard Worker_GIT_FOLDER_NAME = '.git' 59*c2e18aaaSAndroid Build Coastguard Worker# Support gitignore by symbolic link to aidegen/data/gitignore_template. 60*c2e18aaaSAndroid Build Coastguard Worker_GITIGNORE_FILE_NAME = '.gitignore' 61*c2e18aaaSAndroid Build Coastguard Worker_GITIGNORE_REL_PATH = 'tools/asuite/aidegen/data/gitignore_template' 62*c2e18aaaSAndroid Build Coastguard Worker_GITIGNORE_ABS_PATH = os.path.join(common_util.get_android_root_dir(), 63*c2e18aaaSAndroid Build Coastguard Worker _GITIGNORE_REL_PATH) 64*c2e18aaaSAndroid Build Coastguard Worker# Support code style by symbolic link to aidegen/data/AndroidStyle_aidegen.xml. 65*c2e18aaaSAndroid Build Coastguard Worker_CODE_STYLE_REL_PATH = 'tools/asuite/aidegen/data/AndroidStyle_aidegen.xml' 66*c2e18aaaSAndroid Build Coastguard Worker_CODE_STYLE_SRC_PATH = os.path.join(common_util.get_android_root_dir(), 67*c2e18aaaSAndroid Build Coastguard Worker _CODE_STYLE_REL_PATH) 68*c2e18aaaSAndroid Build Coastguard Worker_TEST_MAPPING_CONFIG_PATH = ('tools/tradefederation/core/src/com/android/' 69*c2e18aaaSAndroid Build Coastguard Worker 'tradefed/util/testmapping/TEST_MAPPING.config' 70*c2e18aaaSAndroid Build Coastguard Worker '.json') 71*c2e18aaaSAndroid Build Coastguard Worker 72*c2e18aaaSAndroid Build Coastguard Worker 73*c2e18aaaSAndroid Build Coastguard Workerclass ProjectFileGenerator: 74*c2e18aaaSAndroid Build Coastguard Worker """Project file generator. 75*c2e18aaaSAndroid Build Coastguard Worker 76*c2e18aaaSAndroid Build Coastguard Worker Attributes: 77*c2e18aaaSAndroid Build Coastguard Worker project_info: A instance of ProjectInfo. 78*c2e18aaaSAndroid Build Coastguard Worker """ 79*c2e18aaaSAndroid Build Coastguard Worker 80*c2e18aaaSAndroid Build Coastguard Worker def __init__(self, project_info): 81*c2e18aaaSAndroid Build Coastguard Worker """ProjectFileGenerator initialize. 82*c2e18aaaSAndroid Build Coastguard Worker 83*c2e18aaaSAndroid Build Coastguard Worker Args: 84*c2e18aaaSAndroid Build Coastguard Worker project_info: A instance of ProjectInfo. 85*c2e18aaaSAndroid Build Coastguard Worker """ 86*c2e18aaaSAndroid Build Coastguard Worker self.project_info = project_info 87*c2e18aaaSAndroid Build Coastguard Worker 88*c2e18aaaSAndroid Build Coastguard Worker def generate_intellij_project_file(self, iml_path_list=None): 89*c2e18aaaSAndroid Build Coastguard Worker """Generates IntelliJ project file. 90*c2e18aaaSAndroid Build Coastguard Worker 91*c2e18aaaSAndroid Build Coastguard Worker # TODO(b/155346505): Move this method to idea folder. 92*c2e18aaaSAndroid Build Coastguard Worker 93*c2e18aaaSAndroid Build Coastguard Worker Args: 94*c2e18aaaSAndroid Build Coastguard Worker iml_path_list: An optional list of submodule's iml paths, the 95*c2e18aaaSAndroid Build Coastguard Worker default value is None. 96*c2e18aaaSAndroid Build Coastguard Worker """ 97*c2e18aaaSAndroid Build Coastguard Worker if self.project_info.is_main_project: 98*c2e18aaaSAndroid Build Coastguard Worker self._generate_modules_xml(iml_path_list) 99*c2e18aaaSAndroid Build Coastguard Worker self._copy_constant_project_files() 100*c2e18aaaSAndroid Build Coastguard Worker 101*c2e18aaaSAndroid Build Coastguard Worker @classmethod 102*c2e18aaaSAndroid Build Coastguard Worker def generate_ide_project_files(cls, projects): 103*c2e18aaaSAndroid Build Coastguard Worker """Generate IDE project files by a list of ProjectInfo instances. 104*c2e18aaaSAndroid Build Coastguard Worker 105*c2e18aaaSAndroid Build Coastguard Worker It deals with the sources by ProjectSplitter to create iml files for 106*c2e18aaaSAndroid Build Coastguard Worker each project and generate_intellij_project_file only creates 107*c2e18aaaSAndroid Build Coastguard Worker the other project files under .idea/. 108*c2e18aaaSAndroid Build Coastguard Worker 109*c2e18aaaSAndroid Build Coastguard Worker Args: 110*c2e18aaaSAndroid Build Coastguard Worker projects: A list of ProjectInfo instances. 111*c2e18aaaSAndroid Build Coastguard Worker """ 112*c2e18aaaSAndroid Build Coastguard Worker # Initialization 113*c2e18aaaSAndroid Build Coastguard Worker iml.IMLGenerator.USED_NAME_CACHE.clear() 114*c2e18aaaSAndroid Build Coastguard Worker proj_splitter = project_splitter.ProjectSplitter(projects) 115*c2e18aaaSAndroid Build Coastguard Worker proj_splitter.get_dependencies() 116*c2e18aaaSAndroid Build Coastguard Worker proj_splitter.revise_source_folders() 117*c2e18aaaSAndroid Build Coastguard Worker iml_paths = [proj_splitter.gen_framework_srcjars_iml()] 118*c2e18aaaSAndroid Build Coastguard Worker proj_splitter.gen_projects_iml() 119*c2e18aaaSAndroid Build Coastguard Worker iml_paths += [project.iml_path for project in projects] 120*c2e18aaaSAndroid Build Coastguard Worker ProjectFileGenerator( 121*c2e18aaaSAndroid Build Coastguard Worker projects[0]).generate_intellij_project_file(iml_paths) 122*c2e18aaaSAndroid Build Coastguard Worker _merge_project_vcs_xmls(projects) 123*c2e18aaaSAndroid Build Coastguard Worker 124*c2e18aaaSAndroid Build Coastguard Worker def _copy_constant_project_files(self): 125*c2e18aaaSAndroid Build Coastguard Worker """Copy project files to target path with error handling. 126*c2e18aaaSAndroid Build Coastguard Worker 127*c2e18aaaSAndroid Build Coastguard Worker This function would copy compiler.xml, misc.xml, codeStyles folder and 128*c2e18aaaSAndroid Build Coastguard Worker copyright folder to target folder. Since these files aren't mandatory in 129*c2e18aaaSAndroid Build Coastguard Worker IntelliJ, it only logs when an IOError occurred. 130*c2e18aaaSAndroid Build Coastguard Worker """ 131*c2e18aaaSAndroid Build Coastguard Worker target_path = self.project_info.project_absolute_path 132*c2e18aaaSAndroid Build Coastguard Worker idea_dir = os.path.join(target_path, _IDEA_FOLDER) 133*c2e18aaaSAndroid Build Coastguard Worker copyright_dir = os.path.join(idea_dir, _COPYRIGHT_FOLDER) 134*c2e18aaaSAndroid Build Coastguard Worker inspection_dir = os.path.join(idea_dir, _INSPECTION_FOLDER) 135*c2e18aaaSAndroid Build Coastguard Worker code_style_dir = os.path.join(idea_dir, _CODE_STYLE_FOLDER) 136*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 137*c2e18aaaSAndroid Build Coastguard Worker os.path.join(idea_dir, _COMPILE_XML), templates.XML_COMPILER) 138*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 139*c2e18aaaSAndroid Build Coastguard Worker os.path.join(idea_dir, _MISC_XML), templates.XML_MISC) 140*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 141*c2e18aaaSAndroid Build Coastguard Worker os.path.join(copyright_dir, _APACHE_2_XML), templates.XML_APACHE_2) 142*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 143*c2e18aaaSAndroid Build Coastguard Worker os.path.join(copyright_dir, _PROFILES_SETTINGS_XML), 144*c2e18aaaSAndroid Build Coastguard Worker templates.XML_COPYRIGHT_PROFILES_SETTINGS) 145*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 146*c2e18aaaSAndroid Build Coastguard Worker os.path.join(inspection_dir, _PROFILES_SETTINGS_XML), 147*c2e18aaaSAndroid Build Coastguard Worker templates.XML_INSPECTION_PROFILES_SETTINGS) 148*c2e18aaaSAndroid Build Coastguard Worker inspection_config_xml = os.path.join(inspection_dir, 149*c2e18aaaSAndroid Build Coastguard Worker _INSPECTION_CONFIG_XML) 150*c2e18aaaSAndroid Build Coastguard Worker if not os.path.exists(inspection_config_xml): 151*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(inspection_config_xml, 152*c2e18aaaSAndroid Build Coastguard Worker templates.XML_INSPECTIONS) 153*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 154*c2e18aaaSAndroid Build Coastguard Worker os.path.join(code_style_dir, _CODE_STYLE_CONFIG_XML), 155*c2e18aaaSAndroid Build Coastguard Worker templates.XML_CODE_STYLE_CONFIG) 156*c2e18aaaSAndroid Build Coastguard Worker code_style_target_path = os.path.join(code_style_dir, _PROJECT_XML) 157*c2e18aaaSAndroid Build Coastguard Worker if not os.path.exists(code_style_target_path): 158*c2e18aaaSAndroid Build Coastguard Worker try: 159*c2e18aaaSAndroid Build Coastguard Worker shutil.copy2(_CODE_STYLE_SRC_PATH, code_style_target_path) 160*c2e18aaaSAndroid Build Coastguard Worker except (OSError, SystemError) as err: 161*c2e18aaaSAndroid Build Coastguard Worker logging.warning('%s can\'t copy the project files\n %s', 162*c2e18aaaSAndroid Build Coastguard Worker code_style_target_path, err) 163*c2e18aaaSAndroid Build Coastguard Worker # Create .gitignore if it doesn't exist. 164*c2e18aaaSAndroid Build Coastguard Worker _generate_git_ignore(target_path) 165*c2e18aaaSAndroid Build Coastguard Worker # Create jsonSchemas.xml for TEST_MAPPING. 166*c2e18aaaSAndroid Build Coastguard Worker _generate_test_mapping_schema(idea_dir) 167*c2e18aaaSAndroid Build Coastguard Worker # Create config.json for Asuite plugin 168*c2e18aaaSAndroid Build Coastguard Worker lunch_target = common_util.get_lunch_target() 169*c2e18aaaSAndroid Build Coastguard Worker if lunch_target: 170*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 171*c2e18aaaSAndroid Build Coastguard Worker os.path.join(idea_dir, _CONFIG_JSON), lunch_target) 172*c2e18aaaSAndroid Build Coastguard Worker 173*c2e18aaaSAndroid Build Coastguard Worker def _generate_modules_xml(self, iml_path_list=None): 174*c2e18aaaSAndroid Build Coastguard Worker """Generate modules.xml file. 175*c2e18aaaSAndroid Build Coastguard Worker 176*c2e18aaaSAndroid Build Coastguard Worker IntelliJ uses modules.xml to import which modules should be loaded to 177*c2e18aaaSAndroid Build Coastguard Worker project. In multiple modules case, we will pass iml_path_list of 178*c2e18aaaSAndroid Build Coastguard Worker submodules' dependencies and their iml file paths to add them into main 179*c2e18aaaSAndroid Build Coastguard Worker module's module.xml file. The dependencies.iml file contains all shared 180*c2e18aaaSAndroid Build Coastguard Worker dependencies source folders and jar files. 181*c2e18aaaSAndroid Build Coastguard Worker 182*c2e18aaaSAndroid Build Coastguard Worker Args: 183*c2e18aaaSAndroid Build Coastguard Worker iml_path_list: A list of submodule iml paths. 184*c2e18aaaSAndroid Build Coastguard Worker """ 185*c2e18aaaSAndroid Build Coastguard Worker module_path = self.project_info.project_absolute_path 186*c2e18aaaSAndroid Build Coastguard Worker 187*c2e18aaaSAndroid Build Coastguard Worker # b/121256503: Prevent duplicated iml names from breaking IDEA. 188*c2e18aaaSAndroid Build Coastguard Worker module_name = iml.IMLGenerator.get_unique_iml_name(module_path) 189*c2e18aaaSAndroid Build Coastguard Worker 190*c2e18aaaSAndroid Build Coastguard Worker if iml_path_list is not None: 191*c2e18aaaSAndroid Build Coastguard Worker module_list = [ 192*c2e18aaaSAndroid Build Coastguard Worker _MODULE_SECTION % (module_name, module_name), 193*c2e18aaaSAndroid Build Coastguard Worker _MODULE_SECTION % (constant.KEY_DEPENDENCIES, 194*c2e18aaaSAndroid Build Coastguard Worker constant.KEY_DEPENDENCIES) 195*c2e18aaaSAndroid Build Coastguard Worker ] 196*c2e18aaaSAndroid Build Coastguard Worker for iml_path in iml_path_list: 197*c2e18aaaSAndroid Build Coastguard Worker module_list.append(_SUB_MODULES_SECTION.format(IML=iml_path)) 198*c2e18aaaSAndroid Build Coastguard Worker else: 199*c2e18aaaSAndroid Build Coastguard Worker module_list = [ 200*c2e18aaaSAndroid Build Coastguard Worker _MODULE_SECTION % (module_name, module_name) 201*c2e18aaaSAndroid Build Coastguard Worker ] 202*c2e18aaaSAndroid Build Coastguard Worker module = '\n'.join(module_list) 203*c2e18aaaSAndroid Build Coastguard Worker content = self._remove_debugger_token(templates.XML_MODULES) 204*c2e18aaaSAndroid Build Coastguard Worker content = content.replace(_MODULE_TOKEN, module) 205*c2e18aaaSAndroid Build Coastguard Worker target_path = os.path.join(module_path, _IDEA_FOLDER, _MODULES_XML) 206*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(target_path, content) 207*c2e18aaaSAndroid Build Coastguard Worker 208*c2e18aaaSAndroid Build Coastguard Worker def _remove_debugger_token(self, content): 209*c2e18aaaSAndroid Build Coastguard Worker """Remove the token _ENABLE_DEBUGGER_MODULE_TOKEN. 210*c2e18aaaSAndroid Build Coastguard Worker 211*c2e18aaaSAndroid Build Coastguard Worker Remove the token _ENABLE_DEBUGGER_MODULE_TOKEN in 2 cases: 212*c2e18aaaSAndroid Build Coastguard Worker 1. Sub-projects don't need to be filled in the enable debugger module 213*c2e18aaaSAndroid Build Coastguard Worker so we remove the token here. For the main project, the enable 214*c2e18aaaSAndroid Build Coastguard Worker debugger module will be appended if it exists at the time launching 215*c2e18aaaSAndroid Build Coastguard Worker IDE. 216*c2e18aaaSAndroid Build Coastguard Worker 2. When there is no need to launch IDE. 217*c2e18aaaSAndroid Build Coastguard Worker 218*c2e18aaaSAndroid Build Coastguard Worker Args: 219*c2e18aaaSAndroid Build Coastguard Worker content: The content of module.xml. 220*c2e18aaaSAndroid Build Coastguard Worker 221*c2e18aaaSAndroid Build Coastguard Worker Returns: 222*c2e18aaaSAndroid Build Coastguard Worker String: The content of module.xml. 223*c2e18aaaSAndroid Build Coastguard Worker """ 224*c2e18aaaSAndroid Build Coastguard Worker if (not project_config.ProjectConfig.get_instance().is_launch_ide or 225*c2e18aaaSAndroid Build Coastguard Worker not self.project_info.is_main_project): 226*c2e18aaaSAndroid Build Coastguard Worker content = content.replace(_ENABLE_DEBUGGER_MODULE_TOKEN, '') 227*c2e18aaaSAndroid Build Coastguard Worker return content 228*c2e18aaaSAndroid Build Coastguard Worker 229*c2e18aaaSAndroid Build Coastguard Worker 230*c2e18aaaSAndroid Build Coastguard Workerdef _merge_project_vcs_xmls(projects): 231*c2e18aaaSAndroid Build Coastguard Worker """Merge sub-projects' git paths into main project's vcs.xml. 232*c2e18aaaSAndroid Build Coastguard Worker 233*c2e18aaaSAndroid Build Coastguard Worker After all projects' vcs.xml are generated, collect the git path of each 234*c2e18aaaSAndroid Build Coastguard Worker project and write them into main project's vcs.xml. 235*c2e18aaaSAndroid Build Coastguard Worker 236*c2e18aaaSAndroid Build Coastguard Worker Args: 237*c2e18aaaSAndroid Build Coastguard Worker projects: A list of ProjectInfo instances. 238*c2e18aaaSAndroid Build Coastguard Worker """ 239*c2e18aaaSAndroid Build Coastguard Worker main_project_absolute_path = projects[0].project_absolute_path 240*c2e18aaaSAndroid Build Coastguard Worker if main_project_absolute_path != common_util.get_android_root_dir(): 241*c2e18aaaSAndroid Build Coastguard Worker git_paths = [common_util.find_git_root(project.project_relative_path) 242*c2e18aaaSAndroid Build Coastguard Worker for project in projects if project.project_relative_path] 243*c2e18aaaSAndroid Build Coastguard Worker xml_gen.gen_vcs_xml(main_project_absolute_path, git_paths) 244*c2e18aaaSAndroid Build Coastguard Worker else: 245*c2e18aaaSAndroid Build Coastguard Worker ignore_gits = sorted(_get_all_git_path(main_project_absolute_path)) 246*c2e18aaaSAndroid Build Coastguard Worker xml_gen.write_ignore_git_dirs_file(main_project_absolute_path, 247*c2e18aaaSAndroid Build Coastguard Worker ignore_gits) 248*c2e18aaaSAndroid Build Coastguard Worker 249*c2e18aaaSAndroid Build Coastguard Worker 250*c2e18aaaSAndroid Build Coastguard Workerdef _get_all_git_path(root_path): 251*c2e18aaaSAndroid Build Coastguard Worker """Traverse all subdirectories to get all git folder's path. 252*c2e18aaaSAndroid Build Coastguard Worker 253*c2e18aaaSAndroid Build Coastguard Worker Args: 254*c2e18aaaSAndroid Build Coastguard Worker root_path: A string of path to traverse. 255*c2e18aaaSAndroid Build Coastguard Worker 256*c2e18aaaSAndroid Build Coastguard Worker Yields: 257*c2e18aaaSAndroid Build Coastguard Worker A git folder's path. 258*c2e18aaaSAndroid Build Coastguard Worker """ 259*c2e18aaaSAndroid Build Coastguard Worker for dir_path, dir_names, _ in os.walk(root_path): 260*c2e18aaaSAndroid Build Coastguard Worker if _GIT_FOLDER_NAME in dir_names: 261*c2e18aaaSAndroid Build Coastguard Worker yield dir_path 262*c2e18aaaSAndroid Build Coastguard Worker 263*c2e18aaaSAndroid Build Coastguard Worker 264*c2e18aaaSAndroid Build Coastguard Workerdef _generate_git_ignore(target_folder): 265*c2e18aaaSAndroid Build Coastguard Worker """Generate .gitignore file. 266*c2e18aaaSAndroid Build Coastguard Worker 267*c2e18aaaSAndroid Build Coastguard Worker In target_folder, if there's no .gitignore file, generate one to hide 268*c2e18aaaSAndroid Build Coastguard Worker project content files from git. 269*c2e18aaaSAndroid Build Coastguard Worker 270*c2e18aaaSAndroid Build Coastguard Worker Args: 271*c2e18aaaSAndroid Build Coastguard Worker target_folder: An absolute path string of target folder. 272*c2e18aaaSAndroid Build Coastguard Worker """ 273*c2e18aaaSAndroid Build Coastguard Worker # TODO(b/133641803): Move out aidegen artifacts from Android repo. 274*c2e18aaaSAndroid Build Coastguard Worker try: 275*c2e18aaaSAndroid Build Coastguard Worker gitignore_abs_path = os.path.join(target_folder, _GITIGNORE_FILE_NAME) 276*c2e18aaaSAndroid Build Coastguard Worker if not os.path.exists(gitignore_abs_path): 277*c2e18aaaSAndroid Build Coastguard Worker shutil.copy(_GITIGNORE_ABS_PATH, gitignore_abs_path) 278*c2e18aaaSAndroid Build Coastguard Worker except OSError as err: 279*c2e18aaaSAndroid Build Coastguard Worker logging.error('Not support to run aidegen on Windows.\n %s', err) 280*c2e18aaaSAndroid Build Coastguard Worker 281*c2e18aaaSAndroid Build Coastguard Worker 282*c2e18aaaSAndroid Build Coastguard Workerdef _generate_test_mapping_schema(idea_dir): 283*c2e18aaaSAndroid Build Coastguard Worker """Create jsonSchemas.xml for TEST_MAPPING. 284*c2e18aaaSAndroid Build Coastguard Worker 285*c2e18aaaSAndroid Build Coastguard Worker Args: 286*c2e18aaaSAndroid Build Coastguard Worker idea_dir: An absolute path string of target .idea folder. 287*c2e18aaaSAndroid Build Coastguard Worker """ 288*c2e18aaaSAndroid Build Coastguard Worker config_path = os.path.join( 289*c2e18aaaSAndroid Build Coastguard Worker common_util.get_android_root_dir(), _TEST_MAPPING_CONFIG_PATH) 290*c2e18aaaSAndroid Build Coastguard Worker if os.path.isfile(config_path): 291*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate( 292*c2e18aaaSAndroid Build Coastguard Worker os.path.join(idea_dir, _JSON_SCHEMAS_CONFIG_XML), 293*c2e18aaaSAndroid Build Coastguard Worker templates.TEST_MAPPING_SCHEMAS_XML.format(SCHEMA_PATH=config_path)) 294*c2e18aaaSAndroid Build Coastguard Worker else: 295*c2e18aaaSAndroid Build Coastguard Worker logging.warning('Can\'t find TEST_MAPPING.config.json') 296*c2e18aaaSAndroid Build Coastguard Worker 297*c2e18aaaSAndroid Build Coastguard Worker 298*c2e18aaaSAndroid Build Coastguard Workerdef _filter_out_source_paths(source_paths, module_relpaths): 299*c2e18aaaSAndroid Build Coastguard Worker """Filter out the source paths which belong to the target module. 300*c2e18aaaSAndroid Build Coastguard Worker 301*c2e18aaaSAndroid Build Coastguard Worker The source_paths is a union set of all source paths of all target modules. 302*c2e18aaaSAndroid Build Coastguard Worker For generating the dependencies.iml, we only need the source paths outside 303*c2e18aaaSAndroid Build Coastguard Worker the target modules. 304*c2e18aaaSAndroid Build Coastguard Worker 305*c2e18aaaSAndroid Build Coastguard Worker Args: 306*c2e18aaaSAndroid Build Coastguard Worker source_paths: A set contains the source folder paths. 307*c2e18aaaSAndroid Build Coastguard Worker module_relpaths: A list, contains the relative paths of target modules 308*c2e18aaaSAndroid Build Coastguard Worker except the main module. 309*c2e18aaaSAndroid Build Coastguard Worker 310*c2e18aaaSAndroid Build Coastguard Worker Returns: A set of source paths. 311*c2e18aaaSAndroid Build Coastguard Worker """ 312*c2e18aaaSAndroid Build Coastguard Worker return {x for x in source_paths if not any( 313*c2e18aaaSAndroid Build Coastguard Worker {common_util.is_source_under_relative_path(x, y) 314*c2e18aaaSAndroid Build Coastguard Worker for y in module_relpaths})} 315*c2e18aaaSAndroid Build Coastguard Worker 316*c2e18aaaSAndroid Build Coastguard Worker 317*c2e18aaaSAndroid Build Coastguard Workerdef update_enable_debugger(module_path, enable_debugger_module_abspath=None): 318*c2e18aaaSAndroid Build Coastguard Worker """Append the enable_debugger module's info in modules.xml file. 319*c2e18aaaSAndroid Build Coastguard Worker 320*c2e18aaaSAndroid Build Coastguard Worker Args: 321*c2e18aaaSAndroid Build Coastguard Worker module_path: A string of the folder path contains IDE project content, 322*c2e18aaaSAndroid Build Coastguard Worker e.g., the folder contains the .idea folder. 323*c2e18aaaSAndroid Build Coastguard Worker enable_debugger_module_abspath: A string of the im file path of enable 324*c2e18aaaSAndroid Build Coastguard Worker debugger module. 325*c2e18aaaSAndroid Build Coastguard Worker """ 326*c2e18aaaSAndroid Build Coastguard Worker replace_string = '' 327*c2e18aaaSAndroid Build Coastguard Worker if enable_debugger_module_abspath: 328*c2e18aaaSAndroid Build Coastguard Worker replace_string = _SUB_MODULES_SECTION.format( 329*c2e18aaaSAndroid Build Coastguard Worker IML=enable_debugger_module_abspath) 330*c2e18aaaSAndroid Build Coastguard Worker target_path = os.path.join(module_path, _IDEA_FOLDER, _MODULES_XML) 331*c2e18aaaSAndroid Build Coastguard Worker content = common_util.read_file_content(target_path) 332*c2e18aaaSAndroid Build Coastguard Worker content = content.replace(_ENABLE_DEBUGGER_MODULE_TOKEN, replace_string) 333*c2e18aaaSAndroid Build Coastguard Worker common_util.file_generate(target_path, content) 334*c2e18aaaSAndroid Build Coastguard Worker 335*c2e18aaaSAndroid Build Coastguard Worker 336*c2e18aaaSAndroid Build Coastguard Workerdef gen_enable_debugger_module(module_abspath, android_sdk_version): 337*c2e18aaaSAndroid Build Coastguard Worker """Generate the enable_debugger module under AIDEGen config folder. 338*c2e18aaaSAndroid Build Coastguard Worker 339*c2e18aaaSAndroid Build Coastguard Worker Skip generating the enable_debugger module in IntelliJ once the attempt 340*c2e18aaaSAndroid Build Coastguard Worker of getting the Android SDK version is failed. 341*c2e18aaaSAndroid Build Coastguard Worker 342*c2e18aaaSAndroid Build Coastguard Worker Args: 343*c2e18aaaSAndroid Build Coastguard Worker module_abspath: the absolute path of the main project. 344*c2e18aaaSAndroid Build Coastguard Worker android_sdk_version: A string, the Android SDK version in jdk.table.xml. 345*c2e18aaaSAndroid Build Coastguard Worker """ 346*c2e18aaaSAndroid Build Coastguard Worker if not android_sdk_version: 347*c2e18aaaSAndroid Build Coastguard Worker return 348*c2e18aaaSAndroid Build Coastguard Worker with config.AidegenConfig() as aconf: 349*c2e18aaaSAndroid Build Coastguard Worker if aconf.create_enable_debugger_module(android_sdk_version): 350*c2e18aaaSAndroid Build Coastguard Worker update_enable_debugger(module_abspath, 351*c2e18aaaSAndroid Build Coastguard Worker config.AidegenConfig.DEBUG_ENABLED_FILE_PATH) 352