xref: /aosp_15_r20/tools/asuite/aidegen/lib/config.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"""Config class.
18*c2e18aaaSAndroid Build Coastguard Worker
19*c2e18aaaSAndroid Build Coastguard WorkerHistory:
20*c2e18aaaSAndroid Build Coastguard Worker    version 2: Record the user's each preferred ide version by the key name
21*c2e18aaaSAndroid Build Coastguard Worker               [ide_base.ide_name]_preferred_version. E.g., the key name of the
22*c2e18aaaSAndroid Build Coastguard Worker               preferred IntelliJ is IntelliJ_preferred_version and the example
23*c2e18aaaSAndroid Build Coastguard Worker               is as follows.
24*c2e18aaaSAndroid Build Coastguard Worker               "Android Studio_preferred_version": "/opt/android-studio-3.0/bin/
25*c2e18aaaSAndroid Build Coastguard Worker               studio.sh"
26*c2e18aaaSAndroid Build Coastguard Worker               "IntelliJ_preferred_version": "/opt/intellij-ce-stable/bin/
27*c2e18aaaSAndroid Build Coastguard Worker               idea.sh"
28*c2e18aaaSAndroid Build Coastguard Worker
29*c2e18aaaSAndroid Build Coastguard Worker    version 1: Record the user's preferred IntelliJ version by the key name
30*c2e18aaaSAndroid Build Coastguard Worker               preferred_version and doesn't support any other IDEs. The example
31*c2e18aaaSAndroid Build Coastguard Worker               is "preferred_version": "/opt/intellij-ce-stable/bin/idea.sh".
32*c2e18aaaSAndroid Build Coastguard Worker"""
33*c2e18aaaSAndroid Build Coastguard Worker
34*c2e18aaaSAndroid Build Coastguard Workerimport copy
35*c2e18aaaSAndroid Build Coastguard Workerimport json
36*c2e18aaaSAndroid Build Coastguard Workerimport logging
37*c2e18aaaSAndroid Build Coastguard Workerimport os
38*c2e18aaaSAndroid Build Coastguard Workerimport re
39*c2e18aaaSAndroid Build Coastguard Worker
40*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import constant
41*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen import templates
42*c2e18aaaSAndroid Build Coastguard Workerfrom aidegen.lib import common_util
43*c2e18aaaSAndroid Build Coastguard Worker
44*c2e18aaaSAndroid Build Coastguard Worker_DIR_LIB = 'lib'
45*c2e18aaaSAndroid Build Coastguard Worker
46*c2e18aaaSAndroid Build Coastguard Worker
47*c2e18aaaSAndroid Build Coastguard Workerclass AidegenConfig:
48*c2e18aaaSAndroid Build Coastguard Worker    """Class manages AIDEGen's configurations.
49*c2e18aaaSAndroid Build Coastguard Worker
50*c2e18aaaSAndroid Build Coastguard Worker    Attributes:
51*c2e18aaaSAndroid Build Coastguard Worker        _config: A dict contains the aidegen config.
52*c2e18aaaSAndroid Build Coastguard Worker        _config_backup: A dict contains the aidegen config.
53*c2e18aaaSAndroid Build Coastguard Worker    """
54*c2e18aaaSAndroid Build Coastguard Worker
55*c2e18aaaSAndroid Build Coastguard Worker    # Constants of AIDEGen config
56*c2e18aaaSAndroid Build Coastguard Worker    _DEFAULT_CONFIG_FILE = 'aidegen.config'
57*c2e18aaaSAndroid Build Coastguard Worker    _CONFIG_DIR = os.path.join(
58*c2e18aaaSAndroid Build Coastguard Worker        os.path.expanduser('~'), '.config', 'asuite', 'aidegen')
59*c2e18aaaSAndroid Build Coastguard Worker    _CONFIG_FILE_PATH = os.path.join(_CONFIG_DIR, _DEFAULT_CONFIG_FILE)
60*c2e18aaaSAndroid Build Coastguard Worker    _KEY_APPEND = 'preferred_version'
61*c2e18aaaSAndroid Build Coastguard Worker    _KEY_PLUGIN_PREFERENCE = 'Asuite_plugin_preference'
62*c2e18aaaSAndroid Build Coastguard Worker
63*c2e18aaaSAndroid Build Coastguard Worker    # Constants of enable debugger
64*c2e18aaaSAndroid Build Coastguard Worker    _ENABLE_DEBUG_CONFIG_DIR = 'enable_debugger'
65*c2e18aaaSAndroid Build Coastguard Worker    _ENABLE_DEBUG_CONFIG_FILE = 'enable_debugger.iml'
66*c2e18aaaSAndroid Build Coastguard Worker    _ENABLE_DEBUG_DIR = os.path.join(_CONFIG_DIR, _ENABLE_DEBUG_CONFIG_DIR)
67*c2e18aaaSAndroid Build Coastguard Worker    _DIR_SRC = 'src'
68*c2e18aaaSAndroid Build Coastguard Worker    _DIR_GEN = 'gen'
69*c2e18aaaSAndroid Build Coastguard Worker    DEBUG_ENABLED_FILE_PATH = os.path.join(_ENABLE_DEBUG_DIR,
70*c2e18aaaSAndroid Build Coastguard Worker                                           _ENABLE_DEBUG_CONFIG_FILE)
71*c2e18aaaSAndroid Build Coastguard Worker
72*c2e18aaaSAndroid Build Coastguard Worker    # Constants of checking deprecated IntelliJ version.
73*c2e18aaaSAndroid Build Coastguard Worker    # The launch file idea.sh of IntelliJ is in ASCII encoding.
74*c2e18aaaSAndroid Build Coastguard Worker    ENCODE_TYPE = 'ISO-8859-1'
75*c2e18aaaSAndroid Build Coastguard Worker    ACTIVE_KEYWORD = '$JAVA_BIN'
76*c2e18aaaSAndroid Build Coastguard Worker
77*c2e18aaaSAndroid Build Coastguard Worker    def __init__(self):
78*c2e18aaaSAndroid Build Coastguard Worker        self._config = {}
79*c2e18aaaSAndroid Build Coastguard Worker        self._config_backup = {}
80*c2e18aaaSAndroid Build Coastguard Worker        self._create_config_folder()
81*c2e18aaaSAndroid Build Coastguard Worker
82*c2e18aaaSAndroid Build Coastguard Worker    def __enter__(self):
83*c2e18aaaSAndroid Build Coastguard Worker        self._load_aidegen_config()
84*c2e18aaaSAndroid Build Coastguard Worker        self._config_backup = copy.deepcopy(self._config)
85*c2e18aaaSAndroid Build Coastguard Worker        return self
86*c2e18aaaSAndroid Build Coastguard Worker
87*c2e18aaaSAndroid Build Coastguard Worker    def __exit__(self, exc_type, exc_val, exc_tb):
88*c2e18aaaSAndroid Build Coastguard Worker        self._save_aidegen_config()
89*c2e18aaaSAndroid Build Coastguard Worker
90*c2e18aaaSAndroid Build Coastguard Worker    def preferred_version(self, ide=None):
91*c2e18aaaSAndroid Build Coastguard Worker        """AIDEGen configuration getter.
92*c2e18aaaSAndroid Build Coastguard Worker
93*c2e18aaaSAndroid Build Coastguard Worker        Args:
94*c2e18aaaSAndroid Build Coastguard Worker            ide: The string of the relevant IDE name, same as the data of
95*c2e18aaaSAndroid Build Coastguard Worker                 IdeBase._ide_name or IdeUtil.ide_name(). None represents the
96*c2e18aaaSAndroid Build Coastguard Worker                 usage of the version 1.
97*c2e18aaaSAndroid Build Coastguard Worker
98*c2e18aaaSAndroid Build Coastguard Worker        Returns:
99*c2e18aaaSAndroid Build Coastguard Worker            The preferred version item of configuration data if exists and is
100*c2e18aaaSAndroid Build Coastguard Worker            not deprecated, otherwise None.
101*c2e18aaaSAndroid Build Coastguard Worker        """
102*c2e18aaaSAndroid Build Coastguard Worker        key = '_'.join([ide, self._KEY_APPEND]) if ide else self._KEY_APPEND
103*c2e18aaaSAndroid Build Coastguard Worker        preferred_version = self._config.get(key, '')
104*c2e18aaaSAndroid Build Coastguard Worker        # Backward compatible check.
105*c2e18aaaSAndroid Build Coastguard Worker        if not preferred_version:
106*c2e18aaaSAndroid Build Coastguard Worker            preferred_version = self._config.get(self._KEY_APPEND, '')
107*c2e18aaaSAndroid Build Coastguard Worker
108*c2e18aaaSAndroid Build Coastguard Worker        if preferred_version:
109*c2e18aaaSAndroid Build Coastguard Worker            real_version = os.path.realpath(preferred_version)
110*c2e18aaaSAndroid Build Coastguard Worker            if ide and not self.deprecated_version(ide, real_version):
111*c2e18aaaSAndroid Build Coastguard Worker                return preferred_version
112*c2e18aaaSAndroid Build Coastguard Worker            # Backward compatible handling.
113*c2e18aaaSAndroid Build Coastguard Worker            if not ide and not self.deprecated_intellij_version(real_version):
114*c2e18aaaSAndroid Build Coastguard Worker                return preferred_version
115*c2e18aaaSAndroid Build Coastguard Worker        return None
116*c2e18aaaSAndroid Build Coastguard Worker
117*c2e18aaaSAndroid Build Coastguard Worker    def set_preferred_version(self, preferred_version, ide=None):
118*c2e18aaaSAndroid Build Coastguard Worker        """AIDEGen configuration setter.
119*c2e18aaaSAndroid Build Coastguard Worker
120*c2e18aaaSAndroid Build Coastguard Worker        Args:
121*c2e18aaaSAndroid Build Coastguard Worker            preferred_version: A string, user's preferred version to be set.
122*c2e18aaaSAndroid Build Coastguard Worker            ide: The string of the relevant IDE name, same as the data of
123*c2e18aaaSAndroid Build Coastguard Worker                 IdeBase._ide_name or IdeUtil.ide_name(). None presents the
124*c2e18aaaSAndroid Build Coastguard Worker                 usage of the version 1.
125*c2e18aaaSAndroid Build Coastguard Worker        """
126*c2e18aaaSAndroid Build Coastguard Worker        key = '_'.join([ide, self._KEY_APPEND]) if ide else self._KEY_APPEND
127*c2e18aaaSAndroid Build Coastguard Worker        self._config[key] = preferred_version
128*c2e18aaaSAndroid Build Coastguard Worker
129*c2e18aaaSAndroid Build Coastguard Worker    @property
130*c2e18aaaSAndroid Build Coastguard Worker    def plugin_preference(self):
131*c2e18aaaSAndroid Build Coastguard Worker        """Gets Asuite plugin user's preference
132*c2e18aaaSAndroid Build Coastguard Worker
133*c2e18aaaSAndroid Build Coastguard Worker        Returns:
134*c2e18aaaSAndroid Build Coastguard Worker             A string of the user's preference: yes/no/auto.
135*c2e18aaaSAndroid Build Coastguard Worker        """
136*c2e18aaaSAndroid Build Coastguard Worker        return self._config.get(self._KEY_PLUGIN_PREFERENCE, '')
137*c2e18aaaSAndroid Build Coastguard Worker
138*c2e18aaaSAndroid Build Coastguard Worker    @plugin_preference.setter
139*c2e18aaaSAndroid Build Coastguard Worker    def plugin_preference(self, preference):
140*c2e18aaaSAndroid Build Coastguard Worker        """Sets Asuite plugin user's preference
141*c2e18aaaSAndroid Build Coastguard Worker
142*c2e18aaaSAndroid Build Coastguard Worker        Args:
143*c2e18aaaSAndroid Build Coastguard Worker            preference: A string of the user's preference: yes/no/auto.
144*c2e18aaaSAndroid Build Coastguard Worker        """
145*c2e18aaaSAndroid Build Coastguard Worker        self._config[self._KEY_PLUGIN_PREFERENCE] = preference
146*c2e18aaaSAndroid Build Coastguard Worker
147*c2e18aaaSAndroid Build Coastguard Worker    def _load_aidegen_config(self):
148*c2e18aaaSAndroid Build Coastguard Worker        """Load data from configuration file."""
149*c2e18aaaSAndroid Build Coastguard Worker        if os.path.exists(self._CONFIG_FILE_PATH):
150*c2e18aaaSAndroid Build Coastguard Worker            try:
151*c2e18aaaSAndroid Build Coastguard Worker                with open(self._CONFIG_FILE_PATH, 'r',
152*c2e18aaaSAndroid Build Coastguard Worker                          encoding='utf-8') as cfg_file:
153*c2e18aaaSAndroid Build Coastguard Worker                    self._config = json.load(cfg_file)
154*c2e18aaaSAndroid Build Coastguard Worker            except ValueError as err:
155*c2e18aaaSAndroid Build Coastguard Worker                info = '{} format is incorrect, error: {}'.format(
156*c2e18aaaSAndroid Build Coastguard Worker                    self._CONFIG_FILE_PATH, err)
157*c2e18aaaSAndroid Build Coastguard Worker                logging.info(info)
158*c2e18aaaSAndroid Build Coastguard Worker            except IOError as err:
159*c2e18aaaSAndroid Build Coastguard Worker                logging.error(err)
160*c2e18aaaSAndroid Build Coastguard Worker                raise
161*c2e18aaaSAndroid Build Coastguard Worker
162*c2e18aaaSAndroid Build Coastguard Worker    def _save_aidegen_config(self):
163*c2e18aaaSAndroid Build Coastguard Worker        """Save data to configuration file."""
164*c2e18aaaSAndroid Build Coastguard Worker        if self._is_config_modified():
165*c2e18aaaSAndroid Build Coastguard Worker            with open(self._CONFIG_FILE_PATH, 'w',
166*c2e18aaaSAndroid Build Coastguard Worker                      encoding='utf-8') as cfg_file:
167*c2e18aaaSAndroid Build Coastguard Worker                json.dump(self._config, cfg_file, indent=4)
168*c2e18aaaSAndroid Build Coastguard Worker
169*c2e18aaaSAndroid Build Coastguard Worker    def _is_config_modified(self):
170*c2e18aaaSAndroid Build Coastguard Worker        """Check if configuration data is modified."""
171*c2e18aaaSAndroid Build Coastguard Worker        return any(key for key in self._config if key not in self._config_backup
172*c2e18aaaSAndroid Build Coastguard Worker                   or self._config[key] != self._config_backup[key])
173*c2e18aaaSAndroid Build Coastguard Worker
174*c2e18aaaSAndroid Build Coastguard Worker    def _create_config_folder(self):
175*c2e18aaaSAndroid Build Coastguard Worker        """Create the config folder if it doesn't exist."""
176*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.exists(self._CONFIG_DIR):
177*c2e18aaaSAndroid Build Coastguard Worker            os.makedirs(self._CONFIG_DIR)
178*c2e18aaaSAndroid Build Coastguard Worker
179*c2e18aaaSAndroid Build Coastguard Worker    def _gen_enable_debug_sub_dir(self, dir_name):
180*c2e18aaaSAndroid Build Coastguard Worker        """Generate a dir under enable debug dir.
181*c2e18aaaSAndroid Build Coastguard Worker
182*c2e18aaaSAndroid Build Coastguard Worker        Args:
183*c2e18aaaSAndroid Build Coastguard Worker            dir_name: A string of the folder name.
184*c2e18aaaSAndroid Build Coastguard Worker        """
185*c2e18aaaSAndroid Build Coastguard Worker        _dir = os.path.join(self._ENABLE_DEBUG_DIR, dir_name)
186*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.exists(_dir):
187*c2e18aaaSAndroid Build Coastguard Worker            os.makedirs(_dir)
188*c2e18aaaSAndroid Build Coastguard Worker
189*c2e18aaaSAndroid Build Coastguard Worker    def _gen_androidmanifest(self):
190*c2e18aaaSAndroid Build Coastguard Worker        """Generate an AndroidManifest.xml under enable debug dir.
191*c2e18aaaSAndroid Build Coastguard Worker
192*c2e18aaaSAndroid Build Coastguard Worker        Once the AndroidManifest.xml does not exist or file size is zero,
193*c2e18aaaSAndroid Build Coastguard Worker        AIDEGen will generate it with default content to prevent the red
194*c2e18aaaSAndroid Build Coastguard Worker        underline error in IntelliJ.
195*c2e18aaaSAndroid Build Coastguard Worker        """
196*c2e18aaaSAndroid Build Coastguard Worker        _file = os.path.join(self._ENABLE_DEBUG_DIR, constant.ANDROID_MANIFEST)
197*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.exists(_file) or os.stat(_file).st_size == 0:
198*c2e18aaaSAndroid Build Coastguard Worker            common_util.file_generate(_file, templates.ANDROID_MANIFEST_CONTENT)
199*c2e18aaaSAndroid Build Coastguard Worker
200*c2e18aaaSAndroid Build Coastguard Worker    def _gen_enable_debugger_config(self, android_sdk_version):
201*c2e18aaaSAndroid Build Coastguard Worker        """Generate the enable_debugger.iml config file.
202*c2e18aaaSAndroid Build Coastguard Worker
203*c2e18aaaSAndroid Build Coastguard Worker        Re-generate the enable_debugger.iml everytime for correcting the Android
204*c2e18aaaSAndroid Build Coastguard Worker        SDK version.
205*c2e18aaaSAndroid Build Coastguard Worker
206*c2e18aaaSAndroid Build Coastguard Worker        Args:
207*c2e18aaaSAndroid Build Coastguard Worker            android_sdk_version: The version name of the Android Sdk in the
208*c2e18aaaSAndroid Build Coastguard Worker                                 jdk.table.xml.
209*c2e18aaaSAndroid Build Coastguard Worker        """
210*c2e18aaaSAndroid Build Coastguard Worker        content = templates.XML_ENABLE_DEBUGGER.format(
211*c2e18aaaSAndroid Build Coastguard Worker            ANDROID_SDK_VERSION=android_sdk_version)
212*c2e18aaaSAndroid Build Coastguard Worker        common_util.file_generate(self.DEBUG_ENABLED_FILE_PATH, content)
213*c2e18aaaSAndroid Build Coastguard Worker
214*c2e18aaaSAndroid Build Coastguard Worker    def create_enable_debugger_module(self, android_sdk_version):
215*c2e18aaaSAndroid Build Coastguard Worker        """Create the enable_debugger module.
216*c2e18aaaSAndroid Build Coastguard Worker
217*c2e18aaaSAndroid Build Coastguard Worker        1. Create two empty folders named src and gen.
218*c2e18aaaSAndroid Build Coastguard Worker        2. Create an empty file named AndroidManifest.xml
219*c2e18aaaSAndroid Build Coastguard Worker        3. Create the enable_debugger.iml.
220*c2e18aaaSAndroid Build Coastguard Worker
221*c2e18aaaSAndroid Build Coastguard Worker        Args:
222*c2e18aaaSAndroid Build Coastguard Worker            android_sdk_version: The version name of the Android Sdk in the
223*c2e18aaaSAndroid Build Coastguard Worker                                 jdk.table.xml.
224*c2e18aaaSAndroid Build Coastguard Worker
225*c2e18aaaSAndroid Build Coastguard Worker        Returns: True if successfully generate the enable debugger module,
226*c2e18aaaSAndroid Build Coastguard Worker                 otherwise False.
227*c2e18aaaSAndroid Build Coastguard Worker        """
228*c2e18aaaSAndroid Build Coastguard Worker        try:
229*c2e18aaaSAndroid Build Coastguard Worker            self._gen_enable_debug_sub_dir(self._DIR_SRC)
230*c2e18aaaSAndroid Build Coastguard Worker            self._gen_enable_debug_sub_dir(self._DIR_GEN)
231*c2e18aaaSAndroid Build Coastguard Worker            self._gen_androidmanifest()
232*c2e18aaaSAndroid Build Coastguard Worker            self._gen_enable_debugger_config(android_sdk_version)
233*c2e18aaaSAndroid Build Coastguard Worker            return True
234*c2e18aaaSAndroid Build Coastguard Worker        except (IOError, OSError) as err:
235*c2e18aaaSAndroid Build Coastguard Worker            logging.warning(('Can\'t create the enable_debugger module in %s.\n'
236*c2e18aaaSAndroid Build Coastguard Worker                             '%s'), self._CONFIG_DIR, err)
237*c2e18aaaSAndroid Build Coastguard Worker            return False
238*c2e18aaaSAndroid Build Coastguard Worker
239*c2e18aaaSAndroid Build Coastguard Worker    @staticmethod
240*c2e18aaaSAndroid Build Coastguard Worker    def deprecated_version(ide, script_path):
241*c2e18aaaSAndroid Build Coastguard Worker        """Check if the script_path belongs to a deprecated IDE version.
242*c2e18aaaSAndroid Build Coastguard Worker
243*c2e18aaaSAndroid Build Coastguard Worker        Args:
244*c2e18aaaSAndroid Build Coastguard Worker            ide: The string of the relevant IDE name, same as the data of
245*c2e18aaaSAndroid Build Coastguard Worker                 IdeBase._ide_name or IdeUtil.ide_name().
246*c2e18aaaSAndroid Build Coastguard Worker            script_path: The path string of the IDE script file.
247*c2e18aaaSAndroid Build Coastguard Worker
248*c2e18aaaSAndroid Build Coastguard Worker        Returns: True if the preferred version is deprecated, otherwise False.
249*c2e18aaaSAndroid Build Coastguard Worker        """
250*c2e18aaaSAndroid Build Coastguard Worker        if ide == constant.IDE_ANDROID_STUDIO:
251*c2e18aaaSAndroid Build Coastguard Worker            return AidegenConfig.deprecated_studio_version(script_path)
252*c2e18aaaSAndroid Build Coastguard Worker        if ide == constant.IDE_INTELLIJ:
253*c2e18aaaSAndroid Build Coastguard Worker            return AidegenConfig.deprecated_intellij_version(script_path)
254*c2e18aaaSAndroid Build Coastguard Worker        return False
255*c2e18aaaSAndroid Build Coastguard Worker
256*c2e18aaaSAndroid Build Coastguard Worker    @staticmethod
257*c2e18aaaSAndroid Build Coastguard Worker    def deprecated_intellij_version(idea_path):
258*c2e18aaaSAndroid Build Coastguard Worker        """Check if the preferred IntelliJ version is deprecated or not.
259*c2e18aaaSAndroid Build Coastguard Worker
260*c2e18aaaSAndroid Build Coastguard Worker        The IntelliJ version is deprecated once the string "$JAVA_BIN" doesn't
261*c2e18aaaSAndroid Build Coastguard Worker        exist in the idea.sh.
262*c2e18aaaSAndroid Build Coastguard Worker
263*c2e18aaaSAndroid Build Coastguard Worker        Args:
264*c2e18aaaSAndroid Build Coastguard Worker            idea_path: the absolute path to idea.sh.
265*c2e18aaaSAndroid Build Coastguard Worker
266*c2e18aaaSAndroid Build Coastguard Worker        Returns: True if the preferred version was deprecated, otherwise False.
267*c2e18aaaSAndroid Build Coastguard Worker        """
268*c2e18aaaSAndroid Build Coastguard Worker        if os.path.isfile(idea_path):
269*c2e18aaaSAndroid Build Coastguard Worker            file_content = common_util.read_file_content(
270*c2e18aaaSAndroid Build Coastguard Worker                idea_path, AidegenConfig.ENCODE_TYPE)
271*c2e18aaaSAndroid Build Coastguard Worker            return AidegenConfig.ACTIVE_KEYWORD not in file_content
272*c2e18aaaSAndroid Build Coastguard Worker        return False
273*c2e18aaaSAndroid Build Coastguard Worker
274*c2e18aaaSAndroid Build Coastguard Worker    @staticmethod
275*c2e18aaaSAndroid Build Coastguard Worker    def deprecated_studio_version(script_path):
276*c2e18aaaSAndroid Build Coastguard Worker        """Check if the preferred Studio version is deprecated or not.
277*c2e18aaaSAndroid Build Coastguard Worker
278*c2e18aaaSAndroid Build Coastguard Worker        The Studio version is deprecated once the /android-studio-*/lib folder
279*c2e18aaaSAndroid Build Coastguard Worker        doesn't exist.
280*c2e18aaaSAndroid Build Coastguard Worker
281*c2e18aaaSAndroid Build Coastguard Worker        Args:
282*c2e18aaaSAndroid Build Coastguard Worker            script_path: the absolute path to the ide script file.
283*c2e18aaaSAndroid Build Coastguard Worker
284*c2e18aaaSAndroid Build Coastguard Worker        Returns: True if the preferred version is deprecated, otherwise False.
285*c2e18aaaSAndroid Build Coastguard Worker        """
286*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.isfile(script_path):
287*c2e18aaaSAndroid Build Coastguard Worker            return True
288*c2e18aaaSAndroid Build Coastguard Worker        script_dir = os.path.dirname(script_path)
289*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.isdir(script_dir):
290*c2e18aaaSAndroid Build Coastguard Worker            return True
291*c2e18aaaSAndroid Build Coastguard Worker        lib_path = os.path.join(os.path.dirname(script_dir), _DIR_LIB)
292*c2e18aaaSAndroid Build Coastguard Worker        return not os.path.isdir(lib_path)
293*c2e18aaaSAndroid Build Coastguard Worker
294*c2e18aaaSAndroid Build Coastguard Worker
295*c2e18aaaSAndroid Build Coastguard Workerclass IdeaProperties:
296*c2e18aaaSAndroid Build Coastguard Worker    """Class manages IntelliJ's idea.properties attribute.
297*c2e18aaaSAndroid Build Coastguard Worker
298*c2e18aaaSAndroid Build Coastguard Worker    Class Attributes:
299*c2e18aaaSAndroid Build Coastguard Worker        _PROPERTIES_FILE: The property file name of IntelliJ.
300*c2e18aaaSAndroid Build Coastguard Worker        _KEY_FILESIZE: The key name of the maximum file size.
301*c2e18aaaSAndroid Build Coastguard Worker        _FILESIZE_LIMIT: The value to be set as the max file size.
302*c2e18aaaSAndroid Build Coastguard Worker        _RE_SEARCH_FILESIZE: A regular expression to find the current max file
303*c2e18aaaSAndroid Build Coastguard Worker                             size.
304*c2e18aaaSAndroid Build Coastguard Worker        _PROPERTIES_CONTENT: The default content of idea.properties to be
305*c2e18aaaSAndroid Build Coastguard Worker                             generated.
306*c2e18aaaSAndroid Build Coastguard Worker
307*c2e18aaaSAndroid Build Coastguard Worker    Attributes:
308*c2e18aaaSAndroid Build Coastguard Worker        idea_file: The absolute path of the idea.properties.
309*c2e18aaaSAndroid Build Coastguard Worker                   For example:
310*c2e18aaaSAndroid Build Coastguard Worker                   In Linux, it is ~/.IdeaIC2019.1/config/idea.properties.
311*c2e18aaaSAndroid Build Coastguard Worker                   In Mac, it is ~/Library/Preferences/IdeaIC2019.1/
312*c2e18aaaSAndroid Build Coastguard Worker                   idea.properties.
313*c2e18aaaSAndroid Build Coastguard Worker    """
314*c2e18aaaSAndroid Build Coastguard Worker
315*c2e18aaaSAndroid Build Coastguard Worker    # Constants of idea.properties
316*c2e18aaaSAndroid Build Coastguard Worker    _PROPERTIES_FILE = 'idea.properties'
317*c2e18aaaSAndroid Build Coastguard Worker    _KEY_FILESIZE = 'idea.max.intellisense.filesize'
318*c2e18aaaSAndroid Build Coastguard Worker    _FILESIZE_LIMIT = 100000
319*c2e18aaaSAndroid Build Coastguard Worker    _RE_SEARCH_FILESIZE = r'%s\s?=\s?(?P<value>\d+)' % _KEY_FILESIZE
320*c2e18aaaSAndroid Build Coastguard Worker    _PROPERTIES_CONTENT = """# custom IntelliJ IDEA properties
321*c2e18aaaSAndroid Build Coastguard Worker
322*c2e18aaaSAndroid Build Coastguard Worker#-------------------------------------------------------------------------------
323*c2e18aaaSAndroid Build Coastguard Worker# Maximum size of files (in kilobytes) for which IntelliJ IDEA provides coding
324*c2e18aaaSAndroid Build Coastguard Worker# assistance. Coding assistance for large files can affect editor performance
325*c2e18aaaSAndroid Build Coastguard Worker# and increase memory consumption.
326*c2e18aaaSAndroid Build Coastguard Worker# The default value is 2500.
327*c2e18aaaSAndroid Build Coastguard Worker#-------------------------------------------------------------------------------
328*c2e18aaaSAndroid Build Coastguard Workeridea.max.intellisense.filesize=100000
329*c2e18aaaSAndroid Build Coastguard Worker"""
330*c2e18aaaSAndroid Build Coastguard Worker
331*c2e18aaaSAndroid Build Coastguard Worker    def __init__(self, config_dir):
332*c2e18aaaSAndroid Build Coastguard Worker        """IdeaProperties initialize.
333*c2e18aaaSAndroid Build Coastguard Worker
334*c2e18aaaSAndroid Build Coastguard Worker        Args:
335*c2e18aaaSAndroid Build Coastguard Worker            config_dir: The absolute dir of the idea.properties.
336*c2e18aaaSAndroid Build Coastguard Worker        """
337*c2e18aaaSAndroid Build Coastguard Worker        self.idea_file = os.path.join(config_dir, self._PROPERTIES_FILE)
338*c2e18aaaSAndroid Build Coastguard Worker
339*c2e18aaaSAndroid Build Coastguard Worker    def _set_default_idea_properties(self):
340*c2e18aaaSAndroid Build Coastguard Worker        """Create the file idea.properties."""
341*c2e18aaaSAndroid Build Coastguard Worker        common_util.file_generate(self.idea_file, self._PROPERTIES_CONTENT)
342*c2e18aaaSAndroid Build Coastguard Worker
343*c2e18aaaSAndroid Build Coastguard Worker    def _reset_max_file_size(self):
344*c2e18aaaSAndroid Build Coastguard Worker        """Reset the max file size value in the idea.properties."""
345*c2e18aaaSAndroid Build Coastguard Worker        updated_flag = False
346*c2e18aaaSAndroid Build Coastguard Worker        properties = common_util.read_file_content(self.idea_file).splitlines()
347*c2e18aaaSAndroid Build Coastguard Worker        for index, line in enumerate(properties):
348*c2e18aaaSAndroid Build Coastguard Worker            res = re.search(self._RE_SEARCH_FILESIZE, line)
349*c2e18aaaSAndroid Build Coastguard Worker            if res and int(res.group('value')) < self._FILESIZE_LIMIT:
350*c2e18aaaSAndroid Build Coastguard Worker                updated_flag = True
351*c2e18aaaSAndroid Build Coastguard Worker                properties[index] = '%s=%s' % (self._KEY_FILESIZE,
352*c2e18aaaSAndroid Build Coastguard Worker                                               str(self._FILESIZE_LIMIT))
353*c2e18aaaSAndroid Build Coastguard Worker        if updated_flag:
354*c2e18aaaSAndroid Build Coastguard Worker            common_util.file_generate(self.idea_file, '\n'.join(properties))
355*c2e18aaaSAndroid Build Coastguard Worker
356*c2e18aaaSAndroid Build Coastguard Worker    def set_max_file_size(self):
357*c2e18aaaSAndroid Build Coastguard Worker        """Set the max file size parameter in the idea.properties."""
358*c2e18aaaSAndroid Build Coastguard Worker        if not os.path.exists(self.idea_file):
359*c2e18aaaSAndroid Build Coastguard Worker            self._set_default_idea_properties()
360*c2e18aaaSAndroid Build Coastguard Worker        else:
361*c2e18aaaSAndroid Build Coastguard Worker            self._reset_max_file_size()
362