#!/usr/bin/env python3 # # Copyright 2019, The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Module Info class used to hold cached merged_module_info.json.""" import json import logging import os from pathlib import Path from atest import constants from atest import module_info from aidegen import constant from aidegen.lib import common_util from aidegen.lib import module_info_util from aidegen.lib.singleton import Singleton class AidegenModuleInfo(module_info.ModuleInfo, metaclass=Singleton): """Class that offers fast/easy lookup for Module related details.""" def _load_module_info_file(self, module_file): """Loads the module file. Args: module_file: String of path to file to load up. Used for testing. Returns: Tuple of module_info_target and a json object. """ # If module_file is specified, we're testing so we don't care if # module_info_target stays None. module_info_target = None file_path = module_file if not file_path: module_info_target, file_path = self._discover_mod_file_and_target( self.force_build) self.mod_info_file_path = Path(file_path) logging.debug('Loading %s as module-info.', file_path) with open(file_path, encoding='utf8') as json_file: mod_info = json.load(json_file) return module_info_target, mod_info @staticmethod def _discover_mod_file_and_target(force_build): """Find the module file. If force_build is True, we'll remove module_bp_java_deps.json first and let module_info_util.generate_merged_module_info regenerate it again. Args: force_build: Boolean to indicate if we should rebuild the module_info file regardless if it's created or not. Returns: Tuple of the relative and absolute paths of the merged module info file. """ module_file_path = common_util.get_blueprint_json_path( constant.BLUEPRINT_JAVA_JSONFILE_NAME) if force_build and os.path.isfile(module_file_path): os.remove(module_file_path) merged_file_path = os.path.join(common_util.get_soong_out_path(), constant.MERGED_MODULE_INFO) if not os.path.isfile(merged_file_path): logging.debug( 'Generating %s - this is required for the initial runs.', merged_file_path) data = module_info_util.generate_merged_module_info() common_util.dump_json_dict(merged_file_path, data) merged_file_rel_path = os.path.relpath( merged_file_path, common_util.get_android_root_dir()) return merged_file_rel_path, merged_file_path @staticmethod def is_target_module(mod_info): """Determine if the module is a target module. Determine if a module's class is in TARGET_CLASSES. Args: mod_info: A module's module-info dictionary to be checked. Returns: A boolean, true if it is a target module, otherwise false. """ if mod_info: return any( x in mod_info.get(constants.MODULE_CLASS, []) for x in constant.TARGET_CLASSES) return False @staticmethod def is_project_path_relative_module(mod_info, rel_path): """Determine if the given project path is relative to the module. The rules: 1. If constant.KEY_PATH not in mod_info, we can't tell if it's a module return False. 2. If rel_path is empty, it's under Android root, return True. 3. If module's path equals or starts with rel_path return True, otherwise return False. Args: mod_info: the module-info dictionary of the checked module. rel_path: project's relative path Returns: True if it's the given project path is relative to the module, otherwise False. """ if (constant.KEY_PATH not in mod_info or not mod_info[constant.KEY_PATH]): return False path = mod_info[constant.KEY_PATH][0] if rel_path == '': return True if (constant.KEY_CLASS in mod_info and common_util.is_source_under_relative_path(path, rel_path)): return True return False