xref: /aosp_15_r20/tools/asuite/aidegen/lib/project_file_gen.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
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