xref: /aosp_15_r20/tools/asuite/aidegen/lib/project_config.py (revision c2e18aaa1096c836b086f94603d04f4eb9cf37f5)
1*c2e18aaaSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*c2e18aaaSAndroid Build Coastguard Worker#
3*c2e18aaaSAndroid Build Coastguard Worker# Copyright 2019 - 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"""Project config class."""
18*c2e18aaaSAndroid Build Coastguard Worker
19*c2e18aaaSAndroid Build Coastguard Workerimport os
20*c2e18aaaSAndroid Build Coastguard Worker
21*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant
22*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util
23*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import errors
24*c2e18aaaSAndroid Build Coastguard Worker
25*c2e18aaaSAndroid Build Coastguard WorkerSKIP_BUILD_INFO = ('If you are sure the related modules and dependencies have '
26*c2e18aaaSAndroid Build Coastguard Worker                   'been already built, please try to use command {} to skip '
27*c2e18aaaSAndroid Build Coastguard Worker                   'the building process.')
28*c2e18aaaSAndroid Build Coastguard Worker_SKIP_BUILD_CMD = 'aidegen {} -s'
29*c2e18aaaSAndroid Build Coastguard Worker_SKIP_BUILD_WARN = (
30*c2e18aaaSAndroid Build Coastguard Worker    'You chose "--skip-build". Skip building jar and module might increase '
31*c2e18aaaSAndroid Build Coastguard Worker    'the risk of the absence of some jar or R/AIDL/logtags java files and '
32*c2e18aaaSAndroid Build Coastguard Worker    'cause the red lines to appear in IDE tool.')
33*c2e18aaaSAndroid Build Coastguard Worker_INSTANCE_NOT_EXIST_ERROR = ('The instance of {} does not exist. Please '
34*c2e18aaaSAndroid Build Coastguard Worker                             'initialize it before using.')
35*c2e18aaaSAndroid Build Coastguard Worker
36*c2e18aaaSAndroid Build Coastguard Worker
37*c2e18aaaSAndroid Build Coastguard Workerclass ProjectConfig:
38*c2e18aaaSAndroid Build Coastguard Worker    """A singleton class manages AIDEGen's configurations.
39*c2e18aaaSAndroid Build Coastguard Worker
40*c2e18aaaSAndroid Build Coastguard Worker    ProjectConfig is a singleton class that can be accessed in other modules.
41*c2e18aaaSAndroid Build Coastguard Worker
42*c2e18aaaSAndroid Build Coastguard Worker    Usage:
43*c2e18aaaSAndroid Build Coastguard Worker        1. Main module should do it once by instantiating a ProjectConfig with
44*c2e18aaaSAndroid Build Coastguard Worker           users' input arguments and calling init_environment().
45*c2e18aaaSAndroid Build Coastguard Worker           args = aidegen_main.main(sys.argv[1:])
46*c2e18aaaSAndroid Build Coastguard Worker           project_config.ProjectConfig(args).init_environment()
47*c2e18aaaSAndroid Build Coastguard Worker        2. All others can get the ProjectConfig instance by calling
48*c2e18aaaSAndroid Build Coastguard Worker           get_instance().
49*c2e18aaaSAndroid Build Coastguard Worker           project_config.ProjectConfig.get_instance()
50*c2e18aaaSAndroid Build Coastguard Worker
51*c2e18aaaSAndroid Build Coastguard Worker    Class attributes:
52*c2e18aaaSAndroid Build Coastguard Worker        _instance: A singleton instance of ProjectConfig.
53*c2e18aaaSAndroid Build Coastguard Worker
54*c2e18aaaSAndroid Build Coastguard Worker    Attributes:
55*c2e18aaaSAndroid Build Coastguard Worker        ide_name: The IDE name which users prefer to launch.
56*c2e18aaaSAndroid Build Coastguard Worker        is_launch_ide: A boolean for launching IDE in the end of AIDEGen.
57*c2e18aaaSAndroid Build Coastguard Worker        depth: The depth of module referenced by source.
58*c2e18aaaSAndroid Build Coastguard Worker        full_repo: A boolean decides import whole Android source repo.
59*c2e18aaaSAndroid Build Coastguard Worker        is_skip_build: A boolean decides skipping building jars or modules.
60*c2e18aaaSAndroid Build Coastguard Worker        targets: A string list with Android module names or paths.
61*c2e18aaaSAndroid Build Coastguard Worker        verbose: A boolean. If true, display DEBUG level logs.
62*c2e18aaaSAndroid Build Coastguard Worker        ide_installed_path: A string of IDE installed path.
63*c2e18aaaSAndroid Build Coastguard Worker        config_reset: A boolean if true to reset all saved configurations.
64*c2e18aaaSAndroid Build Coastguard Worker        atest_module_info: A ModuleInfo instance.
65*c2e18aaaSAndroid Build Coastguard Worker        language: The programming language users prefer to deal with.
66*c2e18aaaSAndroid Build Coastguard Worker    """
67*c2e18aaaSAndroid Build Coastguard Worker
68*c2e18aaaSAndroid Build Coastguard Worker    _instance = None
69*c2e18aaaSAndroid Build Coastguard Worker
70*c2e18aaaSAndroid Build Coastguard Worker    def __init__(self, args):
71*c2e18aaaSAndroid Build Coastguard Worker        """ProjectConfig initialize.
72*c2e18aaaSAndroid Build Coastguard Worker
73*c2e18aaaSAndroid Build Coastguard Worker        Args:
74*c2e18aaaSAndroid Build Coastguard Worker            An argparse.Namespace object holds parsed args.
75*c2e18aaaSAndroid Build Coastguard Worker        """
76*c2e18aaaSAndroid Build Coastguard Worker        self.language = constant.LANGUAGE_NAME_DICT[args.language[0]]
77*c2e18aaaSAndroid Build Coastguard Worker        self.ide_name = constant.IDE_NAME_DICT[args.ide[0]]
78*c2e18aaaSAndroid Build Coastguard Worker        self.is_launch_ide = not args.no_launch
79*c2e18aaaSAndroid Build Coastguard Worker        self.depth = args.depth
80*c2e18aaaSAndroid Build Coastguard Worker        self.full_repo = args.android_tree
81*c2e18aaaSAndroid Build Coastguard Worker        self.is_skip_build = args.skip_build
82*c2e18aaaSAndroid Build Coastguard Worker        self.targets = args.targets.copy()
83*c2e18aaaSAndroid Build Coastguard Worker        self.verbose = args.verbose
84*c2e18aaaSAndroid Build Coastguard Worker        self.ide_installed_path = args.ide_installed_path
85*c2e18aaaSAndroid Build Coastguard Worker        self.config_reset = args.config_reset
86*c2e18aaaSAndroid Build Coastguard Worker        self.exclude_paths = args.exclude_paths
87*c2e18aaaSAndroid Build Coastguard Worker        self.atest_module_info = None
88*c2e18aaaSAndroid Build Coastguard Worker        ProjectConfig._instance = self
89*c2e18aaaSAndroid Build Coastguard Worker
90*c2e18aaaSAndroid Build Coastguard Worker    def init_environment(self):
91*c2e18aaaSAndroid Build Coastguard Worker        """Initialize the environment settings for the whole project."""
92*c2e18aaaSAndroid Build Coastguard Worker        self._show_skip_build_msg()
93*c2e18aaaSAndroid Build Coastguard Worker        # TODO(b/159078170): Avoid CLion IDE case for now, we should avoid
94*c2e18aaaSAndroid Build Coastguard Worker        # Android Studio's native project's case in the future.
95*c2e18aaaSAndroid Build Coastguard Worker        targets = self.targets if self.language == constant.JAVA else None
96*c2e18aaaSAndroid Build Coastguard Worker        self.atest_module_info = common_util.get_atest_module_info(targets)
97*c2e18aaaSAndroid Build Coastguard Worker        self.exclude_paths = _transform_exclusive_paths(
98*c2e18aaaSAndroid Build Coastguard Worker            self.atest_module_info, self.exclude_paths)
99*c2e18aaaSAndroid Build Coastguard Worker        self.targets = _check_whole_android_tree(self.targets, self.full_repo)
100*c2e18aaaSAndroid Build Coastguard Worker        self.full_repo = (self.targets[0] == constant.WHOLE_ANDROID_TREE_TARGET)
101*c2e18aaaSAndroid Build Coastguard Worker
102*c2e18aaaSAndroid Build Coastguard Worker    def _show_skip_build_msg(self):
103*c2e18aaaSAndroid Build Coastguard Worker        """Display different messages if users skip building targets or not."""
104*c2e18aaaSAndroid Build Coastguard Worker        if self.is_skip_build:
105*c2e18aaaSAndroid Build Coastguard Worker            print('\n{} {}\n'.format(
106*c2e18aaaSAndroid Build Coastguard Worker                common_util.COLORED_INFO('Warning:'), _SKIP_BUILD_WARN))
107*c2e18aaaSAndroid Build Coastguard Worker        else:
108*c2e18aaaSAndroid Build Coastguard Worker            msg = SKIP_BUILD_INFO.format(
109*c2e18aaaSAndroid Build Coastguard Worker                common_util.COLORED_INFO(
110*c2e18aaaSAndroid Build Coastguard Worker                    _SKIP_BUILD_CMD.format(' '.join(self.targets))))
111*c2e18aaaSAndroid Build Coastguard Worker            print('\n{} {}\n'.format(common_util.COLORED_INFO('INFO:'), msg))
112*c2e18aaaSAndroid Build Coastguard Worker
113*c2e18aaaSAndroid Build Coastguard Worker    @classmethod
114*c2e18aaaSAndroid Build Coastguard Worker    def get_instance(cls):
115*c2e18aaaSAndroid Build Coastguard Worker        """Get a singleton's instance.
116*c2e18aaaSAndroid Build Coastguard Worker
117*c2e18aaaSAndroid Build Coastguard Worker        Returns:
118*c2e18aaaSAndroid Build Coastguard Worker           A singleton instance of ProjectConfig.
119*c2e18aaaSAndroid Build Coastguard Worker
120*c2e18aaaSAndroid Build Coastguard Worker        Raises:
121*c2e18aaaSAndroid Build Coastguard Worker           An exception of errors.InstanceNotExistError if users didn't
122*c2e18aaaSAndroid Build Coastguard Worker           instantiate a ProjectConfig object before calling this method.
123*c2e18aaaSAndroid Build Coastguard Worker        """
124*c2e18aaaSAndroid Build Coastguard Worker        if not cls._instance:
125*c2e18aaaSAndroid Build Coastguard Worker            raise errors.InstanceNotExistError(
126*c2e18aaaSAndroid Build Coastguard Worker                _INSTANCE_NOT_EXIST_ERROR.format(str(cls)))
127*c2e18aaaSAndroid Build Coastguard Worker        return cls._instance
128*c2e18aaaSAndroid Build Coastguard Worker
129*c2e18aaaSAndroid Build Coastguard Worker
130*c2e18aaaSAndroid Build Coastguard Workerdef _check_whole_android_tree(targets, android_tree):
131*c2e18aaaSAndroid Build Coastguard Worker    """Check if it's a building project file for the whole Android tree.
132*c2e18aaaSAndroid Build Coastguard Worker
133*c2e18aaaSAndroid Build Coastguard Worker    The rules:
134*c2e18aaaSAndroid Build Coastguard Worker    1. If users command aidegen under Android root, e.g.,
135*c2e18aaaSAndroid Build Coastguard Worker       root$ aidegen
136*c2e18aaaSAndroid Build Coastguard Worker       that implies users would like to launch the whole Android tree, AIDEGen
137*c2e18aaaSAndroid Build Coastguard Worker       should set the flag android_tree True.
138*c2e18aaaSAndroid Build Coastguard Worker    2. If android_tree is True, add whole Android tree to the project.
139*c2e18aaaSAndroid Build Coastguard Worker
140*c2e18aaaSAndroid Build Coastguard Worker    Args:
141*c2e18aaaSAndroid Build Coastguard Worker        targets: A list of targets to be imported.
142*c2e18aaaSAndroid Build Coastguard Worker        android_tree: A boolean, True if it's a whole Android tree case,
143*c2e18aaaSAndroid Build Coastguard Worker                      otherwise False.
144*c2e18aaaSAndroid Build Coastguard Worker
145*c2e18aaaSAndroid Build Coastguard Worker    Returns:
146*c2e18aaaSAndroid Build Coastguard Worker        A list of targets to be built.
147*c2e18aaaSAndroid Build Coastguard Worker    """
148*c2e18aaaSAndroid Build Coastguard Worker    if common_util.is_android_root(os.getcwd()) and targets == ['']:
149*c2e18aaaSAndroid Build Coastguard Worker        return [constant.WHOLE_ANDROID_TREE_TARGET]
150*c2e18aaaSAndroid Build Coastguard Worker    new_targets = targets.copy()
151*c2e18aaaSAndroid Build Coastguard Worker    if android_tree:
152*c2e18aaaSAndroid Build Coastguard Worker        new_targets.insert(0, constant.WHOLE_ANDROID_TREE_TARGET)
153*c2e18aaaSAndroid Build Coastguard Worker    return new_targets
154*c2e18aaaSAndroid Build Coastguard Worker
155*c2e18aaaSAndroid Build Coastguard Worker
156*c2e18aaaSAndroid Build Coastguard Workerdef is_whole_android_tree(targets, android_tree):
157*c2e18aaaSAndroid Build Coastguard Worker    """Checks is AIDEGen going to process whole android tree.
158*c2e18aaaSAndroid Build Coastguard Worker
159*c2e18aaaSAndroid Build Coastguard Worker    Args:
160*c2e18aaaSAndroid Build Coastguard Worker        targets: A list of targets to be imported.
161*c2e18aaaSAndroid Build Coastguard Worker        android_tree: A boolean, True if it's a whole Android tree case,
162*c2e18aaaSAndroid Build Coastguard Worker                      otherwise False.
163*c2e18aaaSAndroid Build Coastguard Worker    Returns:
164*c2e18aaaSAndroid Build Coastguard Worker        A boolean, True when user is going to import whole Android tree.
165*c2e18aaaSAndroid Build Coastguard Worker    """
166*c2e18aaaSAndroid Build Coastguard Worker    return (android_tree or
167*c2e18aaaSAndroid Build Coastguard Worker            (common_util.is_android_root(os.getcwd()) and targets == ['']))
168*c2e18aaaSAndroid Build Coastguard Worker
169*c2e18aaaSAndroid Build Coastguard Worker
170*c2e18aaaSAndroid Build Coastguard Workerdef _transform_exclusive_paths(atest_module_info, exclude_paths):
171*c2e18aaaSAndroid Build Coastguard Worker    """Transforms exclusive paths to relative paths.
172*c2e18aaaSAndroid Build Coastguard Worker
173*c2e18aaaSAndroid Build Coastguard Worker    Args:
174*c2e18aaaSAndroid Build Coastguard Worker        exclude_paths: A list of strings of exclusive paths.
175*c2e18aaaSAndroid Build Coastguard Worker
176*c2e18aaaSAndroid Build Coastguard Worker    Returns:
177*c2e18aaaSAndroid Build Coastguard Worker        A list of relative paths.
178*c2e18aaaSAndroid Build Coastguard Worker    """
179*c2e18aaaSAndroid Build Coastguard Worker    if not exclude_paths:
180*c2e18aaaSAndroid Build Coastguard Worker        return None
181*c2e18aaaSAndroid Build Coastguard Worker    excludes = []
182*c2e18aaaSAndroid Build Coastguard Worker    for path in exclude_paths:
183*c2e18aaaSAndroid Build Coastguard Worker        exclude_path, _ = common_util.get_related_paths(atest_module_info, path)
184*c2e18aaaSAndroid Build Coastguard Worker        excludes.append(exclude_path)
185*c2e18aaaSAndroid Build Coastguard Worker    return excludes
186