xref: /aosp_15_r20/tools/asuite/aidegen/aidegen_main.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"""AIDEgen
18*c2e18aaaSAndroid Build Coastguard Worker
19*c2e18aaaSAndroid Build Coastguard WorkerThis CLI generates project files for using in IntelliJ, such as:
20*c2e18aaaSAndroid Build Coastguard Worker    - iml
21*c2e18aaaSAndroid Build Coastguard Worker    - .idea/compiler.xml
22*c2e18aaaSAndroid Build Coastguard Worker    - .idea/misc.xml
23*c2e18aaaSAndroid Build Coastguard Worker    - .idea/modules.xml
24*c2e18aaaSAndroid Build Coastguard Worker    - .idea/vcs.xml
25*c2e18aaaSAndroid Build Coastguard Worker    - .idea/.name
26*c2e18aaaSAndroid Build Coastguard Worker    - .idea/copyright/Apache_2.xml
27*c2e18aaaSAndroid Build Coastguard Worker    - .idea/copyright/profiles_settings.xml
28*c2e18aaaSAndroid Build Coastguard Worker
29*c2e18aaaSAndroid Build Coastguard Worker- Sample usage:
30*c2e18aaaSAndroid Build Coastguard Worker    - Change directory to AOSP root first.
31*c2e18aaaSAndroid Build Coastguard Worker    $ cd /user/home/aosp/
32*c2e18aaaSAndroid Build Coastguard Worker    - Generating project files under packages/apps/Settings folder.
33*c2e18aaaSAndroid Build Coastguard Worker    $ aidegen packages/apps/Settings
34*c2e18aaaSAndroid Build Coastguard Worker    or
35*c2e18aaaSAndroid Build Coastguard Worker    $ aidegen Settings
36*c2e18aaaSAndroid Build Coastguard Worker    or
37*c2e18aaaSAndroid Build Coastguard Worker    $ cd packages/apps/Settings;aidegen
38*c2e18aaaSAndroid Build Coastguard Worker"""
39*c2e18aaaSAndroid Build Coastguard Worker
40*c2e18aaaSAndroid Build Coastguard Workerfrom __future__ import absolute_import
41*c2e18aaaSAndroid Build Coastguard Worker
42*c2e18aaaSAndroid Build Coastguard Workerimport argparse
43*c2e18aaaSAndroid Build Coastguard Workerimport os
44*c2e18aaaSAndroid Build Coastguard Workerimport sys
45*c2e18aaaSAndroid Build Coastguard Workerimport traceback
46*c2e18aaaSAndroid Build Coastguard Worker
47*c2e18aaaSAndroid Build Coastguard Workerfrom pathlib import Path
48*c2e18aaaSAndroid Build Coastguard Worker
49*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant
50*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import aidegen_metrics
51*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util
52*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import eclipse_project_file_gen
53*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import errors
54*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import ide_util
55*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import module_info
56*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import native_module_info
57*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import native_project_info
58*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import native_util
59*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import project_config
60*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import project_file_gen
61*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import project_info
62*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.vscode import vscode_native_project_file_gen
63*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.vscode import vscode_workspace_file_gen
64*c2e18aaaSAndroid Build Coastguard Worker
65*c2e18aaaSAndroid Build Coastguard WorkerAIDEGEN_REPORT_LINK = ('To report an AIDEGen tool problem, please use this '
66*c2e18aaaSAndroid Build Coastguard Worker                       'link: https://goto.google.com/aidegen-bug')
67*c2e18aaaSAndroid Build Coastguard Worker_CONGRATULATIONS = common_util.COLORED_PASS('CONGRATULATIONS:')
68*c2e18aaaSAndroid Build Coastguard Worker_LAUNCH_SUCCESS_MSG = (
69*c2e18aaaSAndroid Build Coastguard Worker    'IDE launched successfully. Please check your IDE window.')
70*c2e18aaaSAndroid Build Coastguard Worker_LAUNCH_ECLIPSE_SUCCESS_MSG = (
71*c2e18aaaSAndroid Build Coastguard Worker    'The project files .classpath and .project are generated under '
72*c2e18aaaSAndroid Build Coastguard Worker    '{PROJECT_PATH} and AIDEGen doesn\'t import the project automatically, '
73*c2e18aaaSAndroid Build Coastguard Worker    'please import the project manually by steps: File -> Import -> select \''
74*c2e18aaaSAndroid Build Coastguard Worker    'General\' -> \'Existing Projects into Workspace\' -> click \'Next\' -> '
75*c2e18aaaSAndroid Build Coastguard Worker    'Choose the root directory -> click \'Finish\'.')
76*c2e18aaaSAndroid Build Coastguard Worker_IDE_CACHE_REMINDER_MSG = (
77*c2e18aaaSAndroid Build Coastguard Worker    'To prevent the existed IDE cache from impacting your IDE dependency '
78*c2e18aaaSAndroid Build Coastguard Worker    'analysis, please consider to clear IDE caches if necessary. To do that, '
79*c2e18aaaSAndroid Build Coastguard Worker    'in IntelliJ IDEA, go to [File > Invalidate Caches -> '
80*c2e18aaaSAndroid Build Coastguard Worker    'Invalidate and Restart].')
81*c2e18aaaSAndroid Build Coastguard Worker
82*c2e18aaaSAndroid Build Coastguard Worker_MAX_TIME = 1
83*c2e18aaaSAndroid Build Coastguard Worker_SKIP_BUILD_INFO_FUTURE = ''.join([
84*c2e18aaaSAndroid Build Coastguard Worker    'AIDEGen build time exceeds {} minute(s).\n'.format(_MAX_TIME),
85*c2e18aaaSAndroid Build Coastguard Worker    project_config.SKIP_BUILD_INFO.rstrip('.'), ' in the future.'
86*c2e18aaaSAndroid Build Coastguard Worker])
87*c2e18aaaSAndroid Build Coastguard Worker_INFO = common_util.COLORED_INFO('INFO:')
88*c2e18aaaSAndroid Build Coastguard Worker_SKIP_MSG = _SKIP_BUILD_INFO_FUTURE.format(
89*c2e18aaaSAndroid Build Coastguard Worker    common_util.COLORED_INFO('aidegen [ module(s) ] -s'))
90*c2e18aaaSAndroid Build Coastguard Worker_TIME_EXCEED_MSG = '\n{} {}\n'.format(_INFO, _SKIP_MSG)
91*c2e18aaaSAndroid Build Coastguard Worker_LAUNCH_CLION_IDES = [
92*c2e18aaaSAndroid Build Coastguard Worker    constant.IDE_CLION, constant.IDE_INTELLIJ, constant.IDE_ECLIPSE]
93*c2e18aaaSAndroid Build Coastguard Worker_CHOOSE_LANGUAGE_MSG = ('The scope of your modules contains {} different '
94*c2e18aaaSAndroid Build Coastguard Worker                        'languages as follows:\n{}\nPlease select the one you '
95*c2e18aaaSAndroid Build Coastguard Worker                        'would like to implement.\t')
96*c2e18aaaSAndroid Build Coastguard Worker_LANGUAGE_OPTIONS = [constant.JAVA, constant.C_CPP]
97*c2e18aaaSAndroid Build Coastguard Worker_NO_ANY_PROJECT_EXIST = 'There is no Java, C/C++ or Rust target.'
98*c2e18aaaSAndroid Build Coastguard Worker_NO_LANGUAGE_PROJECT_EXIST = 'There is no {} target.'
99*c2e18aaaSAndroid Build Coastguard Worker_NO_IDE_LAUNCH_PATH = 'Can not find the IDE path : {}'
100*c2e18aaaSAndroid Build Coastguard Worker_AIDEGEN_TRANSITION_MSG = (
101*c2e18aaaSAndroid Build Coastguard Worker    'Please note that AIDEGen is no longer supported. '
102*c2e18aaaSAndroid Build Coastguard Worker    'We encourage you to use Android Studio for Platform (ASfP). '
103*c2e18aaaSAndroid Build Coastguard Worker    'Visit go/asfp or google Android Studio for Platform '
104*c2e18aaaSAndroid Build Coastguard Worker    'for more information.')
105*c2e18aaaSAndroid Build Coastguard Worker
106*c2e18aaaSAndroid Build Coastguard Worker
107*c2e18aaaSAndroid Build Coastguard Workerdef _parse_args(args):
108*c2e18aaaSAndroid Build Coastguard Worker    """Parse command line arguments.
109*c2e18aaaSAndroid Build Coastguard Worker
110*c2e18aaaSAndroid Build Coastguard Worker    Args:
111*c2e18aaaSAndroid Build Coastguard Worker        args: A list of arguments.
112*c2e18aaaSAndroid Build Coastguard Worker
113*c2e18aaaSAndroid Build Coastguard Worker    Returns:
114*c2e18aaaSAndroid Build Coastguard Worker        An argparse.Namespace class instance holding parsed args.
115*c2e18aaaSAndroid Build Coastguard Worker    """
116*c2e18aaaSAndroid Build Coastguard Worker    parser = argparse.ArgumentParser(
117*c2e18aaaSAndroid Build Coastguard Worker        description=__doc__,
118*c2e18aaaSAndroid Build Coastguard Worker        formatter_class=argparse.RawDescriptionHelpFormatter,
119*c2e18aaaSAndroid Build Coastguard Worker        usage=('aidegen [module_name1 module_name2... '
120*c2e18aaaSAndroid Build Coastguard Worker               'project_path1 project_path2...]'))
121*c2e18aaaSAndroid Build Coastguard Worker    parser.required = False
122*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
123*c2e18aaaSAndroid Build Coastguard Worker        'targets',
124*c2e18aaaSAndroid Build Coastguard Worker        type=str,
125*c2e18aaaSAndroid Build Coastguard Worker        nargs='*',
126*c2e18aaaSAndroid Build Coastguard Worker        default=[''],
127*c2e18aaaSAndroid Build Coastguard Worker        help=('Android module name or path.'
128*c2e18aaaSAndroid Build Coastguard Worker              'e.g. Settings or packages/apps/Settings'))
129*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
130*c2e18aaaSAndroid Build Coastguard Worker        '-d',
131*c2e18aaaSAndroid Build Coastguard Worker        '--depth',
132*c2e18aaaSAndroid Build Coastguard Worker        type=int,
133*c2e18aaaSAndroid Build Coastguard Worker        choices=range(10),
134*c2e18aaaSAndroid Build Coastguard Worker        default=0,
135*c2e18aaaSAndroid Build Coastguard Worker        help='The depth of module referenced by source.')
136*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
137*c2e18aaaSAndroid Build Coastguard Worker        '-v',
138*c2e18aaaSAndroid Build Coastguard Worker        '--verbose',
139*c2e18aaaSAndroid Build Coastguard Worker        action='store_true',
140*c2e18aaaSAndroid Build Coastguard Worker        help='Display DEBUG level logging.')
141*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
142*c2e18aaaSAndroid Build Coastguard Worker        '-i',
143*c2e18aaaSAndroid Build Coastguard Worker        '--ide',
144*c2e18aaaSAndroid Build Coastguard Worker        default=['u'],
145*c2e18aaaSAndroid Build Coastguard Worker        help=('Launch IDE type, j: IntelliJ, s: Android Studio, e: Eclipse, '
146*c2e18aaaSAndroid Build Coastguard Worker              'c: CLion, v: VS Code. The default value is \'u\': undefined.'))
147*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
148*c2e18aaaSAndroid Build Coastguard Worker        '-p',
149*c2e18aaaSAndroid Build Coastguard Worker        '--ide-path',
150*c2e18aaaSAndroid Build Coastguard Worker        dest='ide_installed_path',
151*c2e18aaaSAndroid Build Coastguard Worker        help='IDE installed path.')
152*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
153*c2e18aaaSAndroid Build Coastguard Worker        '-n', '--no_launch', action='store_true', help='Do not launch IDE.')
154*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
155*c2e18aaaSAndroid Build Coastguard Worker        '-r',
156*c2e18aaaSAndroid Build Coastguard Worker        '--config-reset',
157*c2e18aaaSAndroid Build Coastguard Worker        dest='config_reset',
158*c2e18aaaSAndroid Build Coastguard Worker        action='store_true',
159*c2e18aaaSAndroid Build Coastguard Worker        help='Reset all saved configurations, e.g., preferred IDE version.')
160*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
161*c2e18aaaSAndroid Build Coastguard Worker        '-s',
162*c2e18aaaSAndroid Build Coastguard Worker        '--skip-build',
163*c2e18aaaSAndroid Build Coastguard Worker        dest='skip_build',
164*c2e18aaaSAndroid Build Coastguard Worker        action='store_true',
165*c2e18aaaSAndroid Build Coastguard Worker        help=('Skip building jars or modules that create java files in build '
166*c2e18aaaSAndroid Build Coastguard Worker              'time, e.g. R/AIDL/Logtags.'))
167*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
168*c2e18aaaSAndroid Build Coastguard Worker        '-a',
169*c2e18aaaSAndroid Build Coastguard Worker        '--android-tree',
170*c2e18aaaSAndroid Build Coastguard Worker        dest='android_tree',
171*c2e18aaaSAndroid Build Coastguard Worker        action='store_true',
172*c2e18aaaSAndroid Build Coastguard Worker        help='Generate whole Android source tree project file for IDE.')
173*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
174*c2e18aaaSAndroid Build Coastguard Worker        '-e',
175*c2e18aaaSAndroid Build Coastguard Worker        '--exclude-paths',
176*c2e18aaaSAndroid Build Coastguard Worker        dest='exclude_paths',
177*c2e18aaaSAndroid Build Coastguard Worker        nargs='*',
178*c2e18aaaSAndroid Build Coastguard Worker        help='Exclude the directories in IDE.')
179*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
180*c2e18aaaSAndroid Build Coastguard Worker        '-V',
181*c2e18aaaSAndroid Build Coastguard Worker        '--version',
182*c2e18aaaSAndroid Build Coastguard Worker        action='store_true',
183*c2e18aaaSAndroid Build Coastguard Worker        help='Print aidegen version string.')
184*c2e18aaaSAndroid Build Coastguard Worker    parser.add_argument(
185*c2e18aaaSAndroid Build Coastguard Worker        '-l',
186*c2e18aaaSAndroid Build Coastguard Worker        '--language',
187*c2e18aaaSAndroid Build Coastguard Worker        default=['u'],
188*c2e18aaaSAndroid Build Coastguard Worker        help=('Launch IDE with a specific language, j: Java, c: C/C++, r: '
189*c2e18aaaSAndroid Build Coastguard Worker              'Rust. The default value is \'u\': undefined.'))
190*c2e18aaaSAndroid Build Coastguard Worker    return parser.parse_args(args)
191*c2e18aaaSAndroid Build Coastguard Worker
192*c2e18aaaSAndroid Build Coastguard Worker
193*c2e18aaaSAndroid Build Coastguard Workerdef _generate_project_files(projects):
194*c2e18aaaSAndroid Build Coastguard Worker    """Generate project files by IDE type.
195*c2e18aaaSAndroid Build Coastguard Worker
196*c2e18aaaSAndroid Build Coastguard Worker    Args:
197*c2e18aaaSAndroid Build Coastguard Worker        projects: A list of ProjectInfo instances.
198*c2e18aaaSAndroid Build Coastguard Worker    """
199*c2e18aaaSAndroid Build Coastguard Worker    config = project_config.ProjectConfig.get_instance()
200*c2e18aaaSAndroid Build Coastguard Worker    if config.ide_name == constant.IDE_ECLIPSE:
201*c2e18aaaSAndroid Build Coastguard Worker        eclipse_project_file_gen.EclipseConf.generate_ide_project_files(
202*c2e18aaaSAndroid Build Coastguard Worker            projects)
203*c2e18aaaSAndroid Build Coastguard Worker    else:
204*c2e18aaaSAndroid Build Coastguard Worker        project_file_gen.ProjectFileGenerator.generate_ide_project_files(
205*c2e18aaaSAndroid Build Coastguard Worker            projects)
206*c2e18aaaSAndroid Build Coastguard Worker
207*c2e18aaaSAndroid Build Coastguard Worker
208*c2e18aaaSAndroid Build Coastguard Workerdef _launch_ide(ide_util_obj, project_absolute_path):
209*c2e18aaaSAndroid Build Coastguard Worker    """Launch IDE through ide_util instance.
210*c2e18aaaSAndroid Build Coastguard Worker
211*c2e18aaaSAndroid Build Coastguard Worker    To launch IDE,
212*c2e18aaaSAndroid Build Coastguard Worker    1. Set IDE config.
213*c2e18aaaSAndroid Build Coastguard Worker    2. For IntelliJ, use .idea as open target is better than .iml file,
214*c2e18aaaSAndroid Build Coastguard Worker       because open the latter is like to open a kind of normal file.
215*c2e18aaaSAndroid Build Coastguard Worker    3. Show _LAUNCH_SUCCESS_MSG to remind users IDE being launched.
216*c2e18aaaSAndroid Build Coastguard Worker
217*c2e18aaaSAndroid Build Coastguard Worker    Args:
218*c2e18aaaSAndroid Build Coastguard Worker        ide_util_obj: An ide_util instance.
219*c2e18aaaSAndroid Build Coastguard Worker        project_absolute_path: A string of project absolute path.
220*c2e18aaaSAndroid Build Coastguard Worker    """
221*c2e18aaaSAndroid Build Coastguard Worker    ide_util_obj.config_ide(project_absolute_path)
222*c2e18aaaSAndroid Build Coastguard Worker    if ide_util_obj.ide_name() == constant.IDE_ECLIPSE:
223*c2e18aaaSAndroid Build Coastguard Worker        launch_msg = ' '.join([_LAUNCH_SUCCESS_MSG,
224*c2e18aaaSAndroid Build Coastguard Worker                               _LAUNCH_ECLIPSE_SUCCESS_MSG.format(
225*c2e18aaaSAndroid Build Coastguard Worker                                   PROJECT_PATH=project_absolute_path)])
226*c2e18aaaSAndroid Build Coastguard Worker    else:
227*c2e18aaaSAndroid Build Coastguard Worker        launch_msg = _LAUNCH_SUCCESS_MSG
228*c2e18aaaSAndroid Build Coastguard Worker    print('\n{} {}\n'.format(_CONGRATULATIONS, launch_msg))
229*c2e18aaaSAndroid Build Coastguard Worker    print('\n{} {}\n'.format(_INFO, _IDE_CACHE_REMINDER_MSG))
230*c2e18aaaSAndroid Build Coastguard Worker    # Send the end message to Clearcut server before launching IDE to make sure
231*c2e18aaaSAndroid Build Coastguard Worker    # the execution time is correct.
232*c2e18aaaSAndroid Build Coastguard Worker    aidegen_metrics.ends_asuite_metrics(constant.EXIT_CODE_EXCEPTION)
233*c2e18aaaSAndroid Build Coastguard Worker    ide_util_obj.launch_ide()
234*c2e18aaaSAndroid Build Coastguard Worker
235*c2e18aaaSAndroid Build Coastguard Worker
236*c2e18aaaSAndroid Build Coastguard Workerdef _launch_native_projects(ide_util_obj, args, cmakelists):
237*c2e18aaaSAndroid Build Coastguard Worker    """Launches C/C++ projects with IDE.
238*c2e18aaaSAndroid Build Coastguard Worker
239*c2e18aaaSAndroid Build Coastguard Worker    AIDEGen provides the IDE argument for CLion, but there's still an implicit
240*c2e18aaaSAndroid Build Coastguard Worker    way to launch it. The rules to launch it are:
241*c2e18aaaSAndroid Build Coastguard Worker    1. If no target IDE, we don't have to launch any IDE for C/C++ project.
242*c2e18aaaSAndroid Build Coastguard Worker    2. If the target IDE is IntelliJ or Eclipse, we should launch C/C++
243*c2e18aaaSAndroid Build Coastguard Worker       projects with CLion.
244*c2e18aaaSAndroid Build Coastguard Worker
245*c2e18aaaSAndroid Build Coastguard Worker    Args:
246*c2e18aaaSAndroid Build Coastguard Worker        ide_util_obj: An ide_util instance.
247*c2e18aaaSAndroid Build Coastguard Worker        args: An argparse.Namespace class instance holding parsed args.
248*c2e18aaaSAndroid Build Coastguard Worker        cmakelists: A list of CMakeLists.txt file paths.
249*c2e18aaaSAndroid Build Coastguard Worker    """
250*c2e18aaaSAndroid Build Coastguard Worker    if not ide_util_obj:
251*c2e18aaaSAndroid Build Coastguard Worker        return
252*c2e18aaaSAndroid Build Coastguard Worker    native_ide_util_obj = ide_util_obj
253*c2e18aaaSAndroid Build Coastguard Worker    ide_name = constant.IDE_NAME_DICT[args.ide[0]]
254*c2e18aaaSAndroid Build Coastguard Worker    if ide_name in _LAUNCH_CLION_IDES:
255*c2e18aaaSAndroid Build Coastguard Worker        native_ide_util_obj = ide_util.get_ide_util_instance('c')
256*c2e18aaaSAndroid Build Coastguard Worker    if native_ide_util_obj:
257*c2e18aaaSAndroid Build Coastguard Worker        _launch_ide(native_ide_util_obj, ' '.join(cmakelists))
258*c2e18aaaSAndroid Build Coastguard Worker
259*c2e18aaaSAndroid Build Coastguard Worker
260*c2e18aaaSAndroid Build Coastguard Workerdef _create_and_launch_java_projects(ide_util_obj, targets):
261*c2e18aaaSAndroid Build Coastguard Worker    """Launches Android of Java(Kotlin) projects with IDE.
262*c2e18aaaSAndroid Build Coastguard Worker
263*c2e18aaaSAndroid Build Coastguard Worker    Args:
264*c2e18aaaSAndroid Build Coastguard Worker        ide_util_obj: An ide_util instance.
265*c2e18aaaSAndroid Build Coastguard Worker        targets: A list of build targets.
266*c2e18aaaSAndroid Build Coastguard Worker    """
267*c2e18aaaSAndroid Build Coastguard Worker    projects = project_info.ProjectInfo.generate_projects(targets)
268*c2e18aaaSAndroid Build Coastguard Worker
269*c2e18aaaSAndroid Build Coastguard Worker    project_info.ProjectInfo.multi_projects_locate_source(projects)
270*c2e18aaaSAndroid Build Coastguard Worker    _generate_project_files(projects)
271*c2e18aaaSAndroid Build Coastguard Worker    if ide_util_obj:
272*c2e18aaaSAndroid Build Coastguard Worker        _launch_ide(ide_util_obj, projects[0].project_absolute_path)
273*c2e18aaaSAndroid Build Coastguard Worker
274*c2e18aaaSAndroid Build Coastguard Worker
275*c2e18aaaSAndroid Build Coastguard Workerdef _launch_ide_by_module_contents(args, ide_util_obj, language,
276*c2e18aaaSAndroid Build Coastguard Worker                                   lang_targets, all_langs=False):
277*c2e18aaaSAndroid Build Coastguard Worker    """Deals with the suitable IDE launch action.
278*c2e18aaaSAndroid Build Coastguard Worker
279*c2e18aaaSAndroid Build Coastguard Worker    The rules of AIDEGen launching IDE with languages are:
280*c2e18aaaSAndroid Build Coastguard Worker      1. If no IDE or language is specific, the priority of the language is:
281*c2e18aaaSAndroid Build Coastguard Worker         a) Java
282*c2e18aaaSAndroid Build Coastguard Worker            aidegen frameworks/base
283*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in IntelliJ.
284*c2e18aaaSAndroid Build Coastguard Worker         b) C/C++
285*c2e18aaaSAndroid Build Coastguard Worker            aidegen hardware/interfaces/vibrator/aidl/default
286*c2e18aaaSAndroid Build Coastguard Worker            launch C/C++ project of hardware/interfaces/vibrator/aidl/default
287*c2e18aaaSAndroid Build Coastguard Worker            in CLion.
288*c2e18aaaSAndroid Build Coastguard Worker         c) Rust
289*c2e18aaaSAndroid Build Coastguard Worker            aidegen external/rust/crates/protobuf
290*c2e18aaaSAndroid Build Coastguard Worker            launch Rust project of external/rust/crates/protobuf in VS Code.
291*c2e18aaaSAndroid Build Coastguard Worker      2. If the IDE is specific, launch related projects in the IDE.
292*c2e18aaaSAndroid Build Coastguard Worker         a) aidegen frameworks/base -i j
293*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in IntelliJ.
294*c2e18aaaSAndroid Build Coastguard Worker            aidegen frameworks/base -i s
295*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in Android Studio.
296*c2e18aaaSAndroid Build Coastguard Worker            aidegen frameworks/base -i e
297*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in Eclipse.
298*c2e18aaaSAndroid Build Coastguard Worker         b) aidegen frameworks/base -i c
299*c2e18aaaSAndroid Build Coastguard Worker            launch C/C++ projects of frameworks/base in CLion.
300*c2e18aaaSAndroid Build Coastguard Worker         c) aidegen external/rust/crates/protobuf -i v
301*c2e18aaaSAndroid Build Coastguard Worker            launch Rust project of external/rust/crates/protobuf in VS Code.
302*c2e18aaaSAndroid Build Coastguard Worker      3. If the language is specific, launch relative language projects in the
303*c2e18aaaSAndroid Build Coastguard Worker         relative IDE.
304*c2e18aaaSAndroid Build Coastguard Worker         a) aidegen frameworks/base -l j
305*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in IntelliJ.
306*c2e18aaaSAndroid Build Coastguard Worker         b) aidegen frameworks/base -l c
307*c2e18aaaSAndroid Build Coastguard Worker            launch C/C++ projects of frameworks/base in CLion.
308*c2e18aaaSAndroid Build Coastguard Worker         c) aidegen external/rust/crates/protobuf -l r
309*c2e18aaaSAndroid Build Coastguard Worker            launch Rust projects of external/rust/crates/protobuf in VS Code.
310*c2e18aaaSAndroid Build Coastguard Worker      4. Both of the IDE and language are specific, launch the IDE with the
311*c2e18aaaSAndroid Build Coastguard Worker         relative language projects. If the IDE conflicts with the language, the
312*c2e18aaaSAndroid Build Coastguard Worker         IDE is prior to the language.
313*c2e18aaaSAndroid Build Coastguard Worker         a) aidegen frameworks/base -i j -l j
314*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in IntelliJ.
315*c2e18aaaSAndroid Build Coastguard Worker         b) aidegen frameworks/base -i s -l c
316*c2e18aaaSAndroid Build Coastguard Worker            launch C/C++ projects of frameworks/base in Android Studio.
317*c2e18aaaSAndroid Build Coastguard Worker         c) aidegen frameworks/base -i c -l j
318*c2e18aaaSAndroid Build Coastguard Worker            launch Java projects of frameworks/base in CLion.
319*c2e18aaaSAndroid Build Coastguard Worker
320*c2e18aaaSAndroid Build Coastguard Worker    Args:
321*c2e18aaaSAndroid Build Coastguard Worker        args: A list of system arguments.
322*c2e18aaaSAndroid Build Coastguard Worker        ide_util_obj: An ide_util instance.
323*c2e18aaaSAndroid Build Coastguard Worker        language: A string of the language to be edited in the IDE.
324*c2e18aaaSAndroid Build Coastguard Worker        lang_targets: A dict contains None or list of targets of different
325*c2e18aaaSAndroid Build Coastguard Worker            languages. E.g.
326*c2e18aaaSAndroid Build Coastguard Worker            {
327*c2e18aaaSAndroid Build Coastguard Worker               'Java': ['modules1', 'modules2'],
328*c2e18aaaSAndroid Build Coastguard Worker               'C/C++': ['modules3'],
329*c2e18aaaSAndroid Build Coastguard Worker               'Rust': None,
330*c2e18aaaSAndroid Build Coastguard Worker               ...
331*c2e18aaaSAndroid Build Coastguard Worker            }
332*c2e18aaaSAndroid Build Coastguard Worker        all_langs: A boolean, True to launch all languages else False.
333*c2e18aaaSAndroid Build Coastguard Worker    """
334*c2e18aaaSAndroid Build Coastguard Worker    if lang_targets is None:
335*c2e18aaaSAndroid Build Coastguard Worker        print(constant.WARN_MSG.format(
336*c2e18aaaSAndroid Build Coastguard Worker            common_util.COLORED_INFO('Warning:'), _NO_ANY_PROJECT_EXIST))
337*c2e18aaaSAndroid Build Coastguard Worker        return
338*c2e18aaaSAndroid Build Coastguard Worker
339*c2e18aaaSAndroid Build Coastguard Worker    targets = lang_targets
340*c2e18aaaSAndroid Build Coastguard Worker    java_list = targets[constant.JAVA] if constant.JAVA in targets else None
341*c2e18aaaSAndroid Build Coastguard Worker    c_cpp_list = targets[constant.C_CPP] if constant.C_CPP in targets else None
342*c2e18aaaSAndroid Build Coastguard Worker    rust_list = targets[constant.RUST] if constant.RUST in targets else None
343*c2e18aaaSAndroid Build Coastguard Worker
344*c2e18aaaSAndroid Build Coastguard Worker    if all_langs:
345*c2e18aaaSAndroid Build Coastguard Worker        _launch_vscode(ide_util_obj, project_info.ProjectInfo.modules_info,
346*c2e18aaaSAndroid Build Coastguard Worker                       java_list, c_cpp_list, rust_list)
347*c2e18aaaSAndroid Build Coastguard Worker        return
348*c2e18aaaSAndroid Build Coastguard Worker    if not (java_list or c_cpp_list or rust_list):
349*c2e18aaaSAndroid Build Coastguard Worker        print(constant.WARN_MSG.format(
350*c2e18aaaSAndroid Build Coastguard Worker            common_util.COLORED_INFO('Warning:'), _NO_ANY_PROJECT_EXIST))
351*c2e18aaaSAndroid Build Coastguard Worker        return
352*c2e18aaaSAndroid Build Coastguard Worker    if language == constant.JAVA:
353*c2e18aaaSAndroid Build Coastguard Worker        if not java_list:
354*c2e18aaaSAndroid Build Coastguard Worker            print(constant.WARN_MSG.format(
355*c2e18aaaSAndroid Build Coastguard Worker                common_util.COLORED_INFO('Warning:'),
356*c2e18aaaSAndroid Build Coastguard Worker                _NO_LANGUAGE_PROJECT_EXIST.format(constant.JAVA)))
357*c2e18aaaSAndroid Build Coastguard Worker            return
358*c2e18aaaSAndroid Build Coastguard Worker        _create_and_launch_java_projects(ide_util_obj, java_list)
359*c2e18aaaSAndroid Build Coastguard Worker        return
360*c2e18aaaSAndroid Build Coastguard Worker    if language == constant.C_CPP:
361*c2e18aaaSAndroid Build Coastguard Worker        if not c_cpp_list:
362*c2e18aaaSAndroid Build Coastguard Worker            print(constant.WARN_MSG.format(
363*c2e18aaaSAndroid Build Coastguard Worker                common_util.COLORED_INFO('Warning:'),
364*c2e18aaaSAndroid Build Coastguard Worker                _NO_LANGUAGE_PROJECT_EXIST.format(constant.C_CPP)))
365*c2e18aaaSAndroid Build Coastguard Worker            return
366*c2e18aaaSAndroid Build Coastguard Worker        native_project_info.NativeProjectInfo.generate_projects(c_cpp_list)
367*c2e18aaaSAndroid Build Coastguard Worker        native_project_file = native_util.generate_clion_projects(c_cpp_list)
368*c2e18aaaSAndroid Build Coastguard Worker        if native_project_file:
369*c2e18aaaSAndroid Build Coastguard Worker            _launch_native_projects(ide_util_obj, args, [native_project_file])
370*c2e18aaaSAndroid Build Coastguard Worker
371*c2e18aaaSAndroid Build Coastguard Worker
372*c2e18aaaSAndroid Build Coastguard Workerdef _launch_vscode(ide_util_obj, atest_module_info, jtargets, ctargets,
373*c2e18aaaSAndroid Build Coastguard Worker                   rtargets):
374*c2e18aaaSAndroid Build Coastguard Worker    """Launches targets with VSCode IDE.
375*c2e18aaaSAndroid Build Coastguard Worker
376*c2e18aaaSAndroid Build Coastguard Worker    Args:
377*c2e18aaaSAndroid Build Coastguard Worker        ide_util_obj: An ide_util instance.
378*c2e18aaaSAndroid Build Coastguard Worker        atest_module_info: A ModuleInfo instance contains the data of
379*c2e18aaaSAndroid Build Coastguard Worker                module-info.json.
380*c2e18aaaSAndroid Build Coastguard Worker        jtargets: A list of Java project targets.
381*c2e18aaaSAndroid Build Coastguard Worker        ctargets: A list of C/C++ project targets.
382*c2e18aaaSAndroid Build Coastguard Worker        rtargets: A list of Rust project targets.
383*c2e18aaaSAndroid Build Coastguard Worker    """
384*c2e18aaaSAndroid Build Coastguard Worker    abs_paths = []
385*c2e18aaaSAndroid Build Coastguard Worker    if jtargets:
386*c2e18aaaSAndroid Build Coastguard Worker        abs_paths.extend(_get_java_project_paths(jtargets, atest_module_info))
387*c2e18aaaSAndroid Build Coastguard Worker    if ctargets:
388*c2e18aaaSAndroid Build Coastguard Worker        abs_paths.extend(_get_cc_project_paths(ctargets))
389*c2e18aaaSAndroid Build Coastguard Worker    if rtargets:
390*c2e18aaaSAndroid Build Coastguard Worker        root_dir = common_util.get_android_root_dir()
391*c2e18aaaSAndroid Build Coastguard Worker        abs_paths.extend(_get_rust_project_paths(rtargets, root_dir))
392*c2e18aaaSAndroid Build Coastguard Worker    if not (jtargets or ctargets or rtargets):
393*c2e18aaaSAndroid Build Coastguard Worker        print(constant.WARN_MSG.format(
394*c2e18aaaSAndroid Build Coastguard Worker            common_util.COLORED_INFO('Warning:'), _NO_ANY_PROJECT_EXIST))
395*c2e18aaaSAndroid Build Coastguard Worker        return
396*c2e18aaaSAndroid Build Coastguard Worker    vs_path = vscode_workspace_file_gen.generate_code_workspace_file(abs_paths)
397*c2e18aaaSAndroid Build Coastguard Worker    if not ide_util_obj:
398*c2e18aaaSAndroid Build Coastguard Worker        return
399*c2e18aaaSAndroid Build Coastguard Worker    _launch_ide(ide_util_obj, vs_path)
400*c2e18aaaSAndroid Build Coastguard Worker
401*c2e18aaaSAndroid Build Coastguard Worker
402*c2e18aaaSAndroid Build Coastguard Workerdef _get_java_project_paths(jtargets, atest_module_info):
403*c2e18aaaSAndroid Build Coastguard Worker    """Gets the Java absolute project paths from the input Java targets.
404*c2e18aaaSAndroid Build Coastguard Worker
405*c2e18aaaSAndroid Build Coastguard Worker    Args:
406*c2e18aaaSAndroid Build Coastguard Worker        jtargets: A list of strings of Java targets.
407*c2e18aaaSAndroid Build Coastguard Worker        atest_module_info: A ModuleInfo instance contains the data of
408*c2e18aaaSAndroid Build Coastguard Worker                module-info.json.
409*c2e18aaaSAndroid Build Coastguard Worker
410*c2e18aaaSAndroid Build Coastguard Worker    Returns:
411*c2e18aaaSAndroid Build Coastguard Worker        A list of the Java absolute project paths.
412*c2e18aaaSAndroid Build Coastguard Worker    """
413*c2e18aaaSAndroid Build Coastguard Worker    abs_paths = []
414*c2e18aaaSAndroid Build Coastguard Worker    for target in jtargets:
415*c2e18aaaSAndroid Build Coastguard Worker        _, abs_path = common_util.get_related_paths(atest_module_info, target)
416*c2e18aaaSAndroid Build Coastguard Worker        if abs_path:
417*c2e18aaaSAndroid Build Coastguard Worker            abs_paths.append(abs_path)
418*c2e18aaaSAndroid Build Coastguard Worker    return abs_paths
419*c2e18aaaSAndroid Build Coastguard Worker
420*c2e18aaaSAndroid Build Coastguard Worker
421*c2e18aaaSAndroid Build Coastguard Workerdef _get_cc_project_paths(ctargets):
422*c2e18aaaSAndroid Build Coastguard Worker    """Gets the C/C++ absolute project paths from the input C/C++ targets.
423*c2e18aaaSAndroid Build Coastguard Worker
424*c2e18aaaSAndroid Build Coastguard Worker    Args:
425*c2e18aaaSAndroid Build Coastguard Worker        ctargets: A list of strings of C/C++ targets.
426*c2e18aaaSAndroid Build Coastguard Worker
427*c2e18aaaSAndroid Build Coastguard Worker    Returns:
428*c2e18aaaSAndroid Build Coastguard Worker        A list of the C/C++ absolute project paths.
429*c2e18aaaSAndroid Build Coastguard Worker    """
430*c2e18aaaSAndroid Build Coastguard Worker    abs_paths = []
431*c2e18aaaSAndroid Build Coastguard Worker    cc_module_info = native_module_info.NativeModuleInfo()
432*c2e18aaaSAndroid Build Coastguard Worker    native_project_info.NativeProjectInfo.generate_projects(ctargets)
433*c2e18aaaSAndroid Build Coastguard Worker    vs_gen = vscode_native_project_file_gen.VSCodeNativeProjectFileGenerator
434*c2e18aaaSAndroid Build Coastguard Worker    for target in ctargets:
435*c2e18aaaSAndroid Build Coastguard Worker        _, abs_path = common_util.get_related_paths(cc_module_info, target)
436*c2e18aaaSAndroid Build Coastguard Worker        if not abs_path:
437*c2e18aaaSAndroid Build Coastguard Worker            continue
438*c2e18aaaSAndroid Build Coastguard Worker        vs_native = vs_gen(abs_path)
439*c2e18aaaSAndroid Build Coastguard Worker        vs_native.generate_c_cpp_properties_json_file()
440*c2e18aaaSAndroid Build Coastguard Worker        if abs_path not in abs_paths:
441*c2e18aaaSAndroid Build Coastguard Worker            abs_paths.append(abs_path)
442*c2e18aaaSAndroid Build Coastguard Worker    return abs_paths
443*c2e18aaaSAndroid Build Coastguard Worker
444*c2e18aaaSAndroid Build Coastguard Worker
445*c2e18aaaSAndroid Build Coastguard Workerdef _get_rust_project_paths(rtargets, root_dir):
446*c2e18aaaSAndroid Build Coastguard Worker    """Gets the Rust absolute project paths from the input Rust targets.
447*c2e18aaaSAndroid Build Coastguard Worker
448*c2e18aaaSAndroid Build Coastguard Worker    Args:
449*c2e18aaaSAndroid Build Coastguard Worker        rtargets: A list of strings of Rust targets.
450*c2e18aaaSAndroid Build Coastguard Worker        root_dir: A string of the Android root directory.
451*c2e18aaaSAndroid Build Coastguard Worker
452*c2e18aaaSAndroid Build Coastguard Worker    Returns:
453*c2e18aaaSAndroid Build Coastguard Worker        A list of the Rust absolute project paths.
454*c2e18aaaSAndroid Build Coastguard Worker    """
455*c2e18aaaSAndroid Build Coastguard Worker    abs_paths = []
456*c2e18aaaSAndroid Build Coastguard Worker    for rtarget in rtargets:
457*c2e18aaaSAndroid Build Coastguard Worker        path = rtarget
458*c2e18aaaSAndroid Build Coastguard Worker        # If rtarget is not an absolute path, make it an absolute one.
459*c2e18aaaSAndroid Build Coastguard Worker        if not common_util.is_source_under_relative_path(rtarget, root_dir):
460*c2e18aaaSAndroid Build Coastguard Worker            path = os.path.join(root_dir, rtarget)
461*c2e18aaaSAndroid Build Coastguard Worker        abs_paths.append(path)
462*c2e18aaaSAndroid Build Coastguard Worker    return abs_paths
463*c2e18aaaSAndroid Build Coastguard Worker
464*c2e18aaaSAndroid Build Coastguard Worker
465*c2e18aaaSAndroid Build Coastguard Workerdef _get_targets_from_args(targets, android_tree):
466*c2e18aaaSAndroid Build Coastguard Worker    """Gets targets for specific argument.
467*c2e18aaaSAndroid Build Coastguard Worker
468*c2e18aaaSAndroid Build Coastguard Worker    For example:
469*c2e18aaaSAndroid Build Coastguard Worker        $aidegen     : targets = ['.']
470*c2e18aaaSAndroid Build Coastguard Worker        $aidegen -a  : targets = []
471*c2e18aaaSAndroid Build Coastguard Worker        $aidegen .   : targets = ['.']
472*c2e18aaaSAndroid Build Coastguard Worker        $aidegen . -a: targets = []
473*c2e18aaaSAndroid Build Coastguard Worker
474*c2e18aaaSAndroid Build Coastguard Worker    Args:
475*c2e18aaaSAndroid Build Coastguard Worker        targets: A list of strings of targets.
476*c2e18aaaSAndroid Build Coastguard Worker        android_tree: A boolean, True with '-a' argument else False.
477*c2e18aaaSAndroid Build Coastguard Worker
478*c2e18aaaSAndroid Build Coastguard Worker    Returns:
479*c2e18aaaSAndroid Build Coastguard Worker        A list of the Rust absolute project paths.
480*c2e18aaaSAndroid Build Coastguard Worker    """
481*c2e18aaaSAndroid Build Coastguard Worker    if targets == [''] and not android_tree:
482*c2e18aaaSAndroid Build Coastguard Worker        return ['.']
483*c2e18aaaSAndroid Build Coastguard Worker    if android_tree:
484*c2e18aaaSAndroid Build Coastguard Worker        return []
485*c2e18aaaSAndroid Build Coastguard Worker    return targets
486*c2e18aaaSAndroid Build Coastguard Worker
487*c2e18aaaSAndroid Build Coastguard Worker
488*c2e18aaaSAndroid Build Coastguard Worker@common_util.time_logged(message=_TIME_EXCEED_MSG, maximum=_MAX_TIME)
489*c2e18aaaSAndroid Build Coastguard Workerdef main_with_message(args):
490*c2e18aaaSAndroid Build Coastguard Worker    """Main entry with skip build message.
491*c2e18aaaSAndroid Build Coastguard Worker
492*c2e18aaaSAndroid Build Coastguard Worker    Args:
493*c2e18aaaSAndroid Build Coastguard Worker        args: A list of system arguments.
494*c2e18aaaSAndroid Build Coastguard Worker    """
495*c2e18aaaSAndroid Build Coastguard Worker    aidegen_main(args)
496*c2e18aaaSAndroid Build Coastguard Worker
497*c2e18aaaSAndroid Build Coastguard Worker
498*c2e18aaaSAndroid Build Coastguard Worker@common_util.time_logged
499*c2e18aaaSAndroid Build Coastguard Workerdef main_without_message(args):
500*c2e18aaaSAndroid Build Coastguard Worker    """Main entry without skip build message.
501*c2e18aaaSAndroid Build Coastguard Worker
502*c2e18aaaSAndroid Build Coastguard Worker    Args:
503*c2e18aaaSAndroid Build Coastguard Worker        args: A list of system arguments.
504*c2e18aaaSAndroid Build Coastguard Worker    """
505*c2e18aaaSAndroid Build Coastguard Worker    aidegen_main(args)
506*c2e18aaaSAndroid Build Coastguard Worker
507*c2e18aaaSAndroid Build Coastguard Worker
508*c2e18aaaSAndroid Build Coastguard Worker# pylint: disable=broad-except
509*c2e18aaaSAndroid Build Coastguard Workerdef main(argv):
510*c2e18aaaSAndroid Build Coastguard Worker    """Main entry.
511*c2e18aaaSAndroid Build Coastguard Worker
512*c2e18aaaSAndroid Build Coastguard Worker    Show skip build message in aidegen main process if users command skip_build
513*c2e18aaaSAndroid Build Coastguard Worker    otherwise remind them to use it and include metrics supports.
514*c2e18aaaSAndroid Build Coastguard Worker
515*c2e18aaaSAndroid Build Coastguard Worker    Args:
516*c2e18aaaSAndroid Build Coastguard Worker        argv: A list of system arguments.
517*c2e18aaaSAndroid Build Coastguard Worker    """
518*c2e18aaaSAndroid Build Coastguard Worker    exit_code = constant.EXIT_CODE_NORMAL
519*c2e18aaaSAndroid Build Coastguard Worker    launch_ide = True
520*c2e18aaaSAndroid Build Coastguard Worker    ask_version = False
521*c2e18aaaSAndroid Build Coastguard Worker    try:
522*c2e18aaaSAndroid Build Coastguard Worker        args = _parse_args(argv)
523*c2e18aaaSAndroid Build Coastguard Worker        args.targets = _get_targets_from_args(args.targets, args.android_tree)
524*c2e18aaaSAndroid Build Coastguard Worker        if args.version:
525*c2e18aaaSAndroid Build Coastguard Worker            ask_version = True
526*c2e18aaaSAndroid Build Coastguard Worker            version_file = os.path.join(os.path.dirname(__file__),
527*c2e18aaaSAndroid Build Coastguard Worker                                        constant.VERSION_FILE)
528*c2e18aaaSAndroid Build Coastguard Worker            print(common_util.read_file_content(version_file))
529*c2e18aaaSAndroid Build Coastguard Worker            sys.exit(constant.EXIT_CODE_NORMAL)
530*c2e18aaaSAndroid Build Coastguard Worker        if args.ide_installed_path:
531*c2e18aaaSAndroid Build Coastguard Worker            if not Path(args.ide_installed_path).exists():
532*c2e18aaaSAndroid Build Coastguard Worker                print(_NO_IDE_LAUNCH_PATH.format(args.ide_installed_path))
533*c2e18aaaSAndroid Build Coastguard Worker                sys.exit(constant.EXIT_CODE_NORMAL)
534*c2e18aaaSAndroid Build Coastguard Worker
535*c2e18aaaSAndroid Build Coastguard Worker        launch_ide = not args.no_launch
536*c2e18aaaSAndroid Build Coastguard Worker        common_util.configure_logging(args.verbose)
537*c2e18aaaSAndroid Build Coastguard Worker        is_whole_android_tree = project_config.is_whole_android_tree(
538*c2e18aaaSAndroid Build Coastguard Worker            args.targets, args.android_tree)
539*c2e18aaaSAndroid Build Coastguard Worker        references = [constant.ANDROID_TREE] if is_whole_android_tree else []
540*c2e18aaaSAndroid Build Coastguard Worker        aidegen_metrics.starts_asuite_metrics(references)
541*c2e18aaaSAndroid Build Coastguard Worker        print(constant.WARN_MSG.format(
542*c2e18aaaSAndroid Build Coastguard Worker              common_util.COLORED_INFO('INFO:'), _AIDEGEN_TRANSITION_MSG))
543*c2e18aaaSAndroid Build Coastguard Worker        if args.skip_build:
544*c2e18aaaSAndroid Build Coastguard Worker            main_without_message(args)
545*c2e18aaaSAndroid Build Coastguard Worker        else:
546*c2e18aaaSAndroid Build Coastguard Worker            main_with_message(args)
547*c2e18aaaSAndroid Build Coastguard Worker    except BaseException as err:
548*c2e18aaaSAndroid Build Coastguard Worker        exit_code = constant.EXIT_CODE_EXCEPTION
549*c2e18aaaSAndroid Build Coastguard Worker        _, exc_value, exc_traceback = sys.exc_info()
550*c2e18aaaSAndroid Build Coastguard Worker        if isinstance(err, errors.AIDEgenError):
551*c2e18aaaSAndroid Build Coastguard Worker            exit_code = constant.EXIT_CODE_AIDEGEN_EXCEPTION
552*c2e18aaaSAndroid Build Coastguard Worker        # Filter out sys.Exit(0) case, which is not an exception case.
553*c2e18aaaSAndroid Build Coastguard Worker        if isinstance(err, SystemExit) and exc_value.code == 0:
554*c2e18aaaSAndroid Build Coastguard Worker            exit_code = constant.EXIT_CODE_NORMAL
555*c2e18aaaSAndroid Build Coastguard Worker        if exit_code is not constant.EXIT_CODE_NORMAL:
556*c2e18aaaSAndroid Build Coastguard Worker            error_message = str(exc_value)
557*c2e18aaaSAndroid Build Coastguard Worker            traceback_list = traceback.format_tb(exc_traceback)
558*c2e18aaaSAndroid Build Coastguard Worker            traceback_list.append(error_message)
559*c2e18aaaSAndroid Build Coastguard Worker            traceback_str = ''.join(traceback_list)
560*c2e18aaaSAndroid Build Coastguard Worker            aidegen_metrics.ends_asuite_metrics(exit_code, traceback_str,
561*c2e18aaaSAndroid Build Coastguard Worker                                                error_message)
562*c2e18aaaSAndroid Build Coastguard Worker            # print out the traceback message for developers to debug
563*c2e18aaaSAndroid Build Coastguard Worker            print(traceback_str)
564*c2e18aaaSAndroid Build Coastguard Worker            raise err
565*c2e18aaaSAndroid Build Coastguard Worker    finally:
566*c2e18aaaSAndroid Build Coastguard Worker        if not ask_version:
567*c2e18aaaSAndroid Build Coastguard Worker            print('\n{0} {1}\n'.format(_INFO, AIDEGEN_REPORT_LINK))
568*c2e18aaaSAndroid Build Coastguard Worker            # Send the end message here on ignoring launch IDE case.
569*c2e18aaaSAndroid Build Coastguard Worker            if not launch_ide and exit_code is constant.EXIT_CODE_NORMAL:
570*c2e18aaaSAndroid Build Coastguard Worker                aidegen_metrics.ends_asuite_metrics(exit_code)
571*c2e18aaaSAndroid Build Coastguard Worker
572*c2e18aaaSAndroid Build Coastguard Worker
573*c2e18aaaSAndroid Build Coastguard Workerdef aidegen_main(args):
574*c2e18aaaSAndroid Build Coastguard Worker    """AIDEGen main entry.
575*c2e18aaaSAndroid Build Coastguard Worker
576*c2e18aaaSAndroid Build Coastguard Worker    Try to generate project files for using in IDE. The process is:
577*c2e18aaaSAndroid Build Coastguard Worker      1. Instantiate a ProjectConfig singleton object and initialize its
578*c2e18aaaSAndroid Build Coastguard Worker         environment. After creating a singleton instance for ProjectConfig,
579*c2e18aaaSAndroid Build Coastguard Worker         other modules can use project configurations by
580*c2e18aaaSAndroid Build Coastguard Worker         ProjectConfig.get_instance().
581*c2e18aaaSAndroid Build Coastguard Worker      2. Get an IDE instance from ide_util, ide_util.get_ide_util_instance will
582*c2e18aaaSAndroid Build Coastguard Worker         use ProjectConfig.get_instance() inside the function.
583*c2e18aaaSAndroid Build Coastguard Worker      3. Setup project_info.ProjectInfo.modules_info by instantiate
584*c2e18aaaSAndroid Build Coastguard Worker         AidegenModuleInfo.
585*c2e18aaaSAndroid Build Coastguard Worker      4. Check if projects contain C/C++ projects and launch related IDE.
586*c2e18aaaSAndroid Build Coastguard Worker
587*c2e18aaaSAndroid Build Coastguard Worker    Args:
588*c2e18aaaSAndroid Build Coastguard Worker        args: A list of system arguments.
589*c2e18aaaSAndroid Build Coastguard Worker    """
590*c2e18aaaSAndroid Build Coastguard Worker    config = project_config.ProjectConfig(args)
591*c2e18aaaSAndroid Build Coastguard Worker    config.init_environment()
592*c2e18aaaSAndroid Build Coastguard Worker    targets = config.targets
593*c2e18aaaSAndroid Build Coastguard Worker    project_info.ProjectInfo.modules_info = module_info.AidegenModuleInfo()
594*c2e18aaaSAndroid Build Coastguard Worker    cc_module_info = native_module_info.NativeModuleInfo()
595*c2e18aaaSAndroid Build Coastguard Worker    jtargets, ctargets, rtargets = native_util.get_java_cc_and_rust_projects(
596*c2e18aaaSAndroid Build Coastguard Worker        project_info.ProjectInfo.modules_info, cc_module_info, targets)
597*c2e18aaaSAndroid Build Coastguard Worker    config.language, config.ide_name = common_util.determine_language_ide(
598*c2e18aaaSAndroid Build Coastguard Worker        args.language[0], args.ide[0], jtargets, ctargets, rtargets)
599*c2e18aaaSAndroid Build Coastguard Worker    # Called ide_util for pre-check the IDE existence state.
600*c2e18aaaSAndroid Build Coastguard Worker    ide_util_obj = ide_util.get_ide_util_instance(
601*c2e18aaaSAndroid Build Coastguard Worker        constant.IDE_DICT[config.ide_name])
602*c2e18aaaSAndroid Build Coastguard Worker    all_langs = config.ide_name == constant.IDE_VSCODE
603*c2e18aaaSAndroid Build Coastguard Worker    # Backward compatible strategy, when both java and C/C++ module exist,
604*c2e18aaaSAndroid Build Coastguard Worker    # check the preferred target from the user and launch single one.
605*c2e18aaaSAndroid Build Coastguard Worker    language_targets = {constant.JAVA: jtargets,
606*c2e18aaaSAndroid Build Coastguard Worker                        constant.C_CPP: ctargets,
607*c2e18aaaSAndroid Build Coastguard Worker                        constant.RUST: rtargets}
608*c2e18aaaSAndroid Build Coastguard Worker    _launch_ide_by_module_contents(args, ide_util_obj, config.language,
609*c2e18aaaSAndroid Build Coastguard Worker                                   language_targets, all_langs)
610*c2e18aaaSAndroid Build Coastguard Worker
611*c2e18aaaSAndroid Build Coastguard Worker
612*c2e18aaaSAndroid Build Coastguard Workerif __name__ == '__main__':
613*c2e18aaaSAndroid Build Coastguard Worker    main(sys.argv[1:])
614