15f9996aaSopenharmony_ci#!/usr/bin/env python 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 65f9996aaSopenharmony_ci# You may obtain a copy of the License at 75f9996aaSopenharmony_ci# 85f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 145f9996aaSopenharmony_ci# limitations under the License. 155f9996aaSopenharmony_ci 165f9996aaSopenharmony_ciimport os 175f9996aaSopenharmony_ciimport sys 185f9996aaSopenharmony_ciimport argparse 195f9996aaSopenharmony_cifrom containers.status import throw_exception 205f9996aaSopenharmony_cifrom exceptions.ohos_exception import OHOSException 215f9996aaSopenharmony_cifrom scripts.util.file_utils import read_json_file, write_json_file # noqa: E402 E501 225f9996aaSopenharmony_cifrom util.log_util import LogUtil 235f9996aaSopenharmony_ci 245f9996aaSopenharmony_ci_default_subsystem = {"build": "build"} 255f9996aaSopenharmony_ci 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_ci@throw_exception 285f9996aaSopenharmony_cidef _read_config(subsystem_config_file, example_subsystem_file): 295f9996aaSopenharmony_ci if not os.path.exists(subsystem_config_file): 305f9996aaSopenharmony_ci raise OHOSException( 315f9996aaSopenharmony_ci "config file '{}' doesn't exist.".format(subsystem_config_file), "2013") 325f9996aaSopenharmony_ci subsystem_config = read_json_file(subsystem_config_file) 335f9996aaSopenharmony_ci if subsystem_config is None: 345f9996aaSopenharmony_ci raise OHOSException("read file '{}' failed.".format( 355f9996aaSopenharmony_ci subsystem_config_file), "2013") 365f9996aaSopenharmony_ci 375f9996aaSopenharmony_ci # example subsystem 385f9996aaSopenharmony_ci if example_subsystem_file: 395f9996aaSopenharmony_ci example_subsystem_config = read_json_file(example_subsystem_file) 405f9996aaSopenharmony_ci if example_subsystem_config is not None: 415f9996aaSopenharmony_ci subsystem_config.update(example_subsystem_config) 425f9996aaSopenharmony_ci 435f9996aaSopenharmony_ci subsystem_info = {} 445f9996aaSopenharmony_ci for key, val in subsystem_config.items(): 455f9996aaSopenharmony_ci if 'path' not in val: 465f9996aaSopenharmony_ci raise OHOSException( 475f9996aaSopenharmony_ci "subsystem '{}' not config path.".format(key), "2013") 485f9996aaSopenharmony_ci subsystem_info[key] = val.get('path') 495f9996aaSopenharmony_ci return subsystem_info 505f9996aaSopenharmony_ci 515f9996aaSopenharmony_ci 525f9996aaSopenharmony_cidef _scan_build_file(subsystem_path): 535f9996aaSopenharmony_ci _files = [] 545f9996aaSopenharmony_ci _bundle_files = [] 555f9996aaSopenharmony_ci for root, dirs, files in os.walk(subsystem_path): 565f9996aaSopenharmony_ci for name in files: 575f9996aaSopenharmony_ci if name == 'ohos.build': 585f9996aaSopenharmony_ci _files.append(os.path.join(root, name)) 595f9996aaSopenharmony_ci elif name == 'bundle.json': 605f9996aaSopenharmony_ci _bundle_files.append(os.path.join(root, name)) 615f9996aaSopenharmony_ci if _bundle_files: 625f9996aaSopenharmony_ci _files.extend(_bundle_files) 635f9996aaSopenharmony_ci return _files 645f9996aaSopenharmony_ci 655f9996aaSopenharmony_ci 665f9996aaSopenharmony_cidef _check_path_prefix(paths): 675f9996aaSopenharmony_ci allow_path_prefix = ['vendor', 'device'] 685f9996aaSopenharmony_ci result = list( 695f9996aaSopenharmony_ci filter(lambda x: x is False, 705f9996aaSopenharmony_ci map(lambda p: p.split('/')[0] in allow_path_prefix, paths))) 715f9996aaSopenharmony_ci return len(result) <= 1 725f9996aaSopenharmony_ci 735f9996aaSopenharmony_ci 745f9996aaSopenharmony_ci@throw_exception 755f9996aaSopenharmony_cidef scan(subsystem_config_file, example_subsystem_file, source_root_dir): 765f9996aaSopenharmony_ci subsystem_infos = _read_config(subsystem_config_file, 775f9996aaSopenharmony_ci example_subsystem_file) 785f9996aaSopenharmony_ci # add common subsystem info 795f9996aaSopenharmony_ci subsystem_infos.update(_default_subsystem) 805f9996aaSopenharmony_ci 815f9996aaSopenharmony_ci no_src_subsystem = {} 825f9996aaSopenharmony_ci _build_configs = {} 835f9996aaSopenharmony_ci for key, val in subsystem_infos.items(): 845f9996aaSopenharmony_ci _all_build_config_files = [] 855f9996aaSopenharmony_ci if not isinstance(val, list): 865f9996aaSopenharmony_ci val = [val] 875f9996aaSopenharmony_ci else: 885f9996aaSopenharmony_ci if not _check_path_prefix(val): 895f9996aaSopenharmony_ci raise OHOSException( 905f9996aaSopenharmony_ci "subsystem '{}' path configuration is incorrect.".format( 915f9996aaSopenharmony_ci key), "2013") 925f9996aaSopenharmony_ci _info = {'path': val} 935f9996aaSopenharmony_ci for _path in val: 945f9996aaSopenharmony_ci _subsystem_path = os.path.join(source_root_dir, _path) 955f9996aaSopenharmony_ci _build_config_files = _scan_build_file(_subsystem_path) 965f9996aaSopenharmony_ci _all_build_config_files.extend(_build_config_files) 975f9996aaSopenharmony_ci if _all_build_config_files: 985f9996aaSopenharmony_ci _info['build_files'] = _all_build_config_files 995f9996aaSopenharmony_ci _build_configs[key] = _info 1005f9996aaSopenharmony_ci else: 1015f9996aaSopenharmony_ci no_src_subsystem[key] = val 1025f9996aaSopenharmony_ci 1035f9996aaSopenharmony_ci scan_result = { 1045f9996aaSopenharmony_ci 'source_path': source_root_dir, 1055f9996aaSopenharmony_ci 'subsystem': _build_configs, 1065f9996aaSopenharmony_ci 'no_src_subsystem': no_src_subsystem 1075f9996aaSopenharmony_ci } 1085f9996aaSopenharmony_ci LogUtil.hb_info('subsytem config scan completed') 1095f9996aaSopenharmony_ci return scan_result 1105f9996aaSopenharmony_ci 1115f9996aaSopenharmony_ci 1125f9996aaSopenharmony_cidef main(): 1135f9996aaSopenharmony_ci parser = argparse.ArgumentParser() 1145f9996aaSopenharmony_ci parser.add_argument('--subsystem-config-file', required=True) 1155f9996aaSopenharmony_ci parser.add_argument('--subsystem-config-overlay-file', required=True) 1165f9996aaSopenharmony_ci parser.add_argument('--example-subsystem-file', required=False) 1175f9996aaSopenharmony_ci parser.add_argument('--source-root-dir', required=True) 1185f9996aaSopenharmony_ci parser.add_argument('--output-dir', required=True) 1195f9996aaSopenharmony_ci args = parser.parse_args() 1205f9996aaSopenharmony_ci 1215f9996aaSopenharmony_ci build_configs = scan(args.subsystem_config_file, 1225f9996aaSopenharmony_ci args.example_subsystem_file, args.source_root_dir) 1235f9996aaSopenharmony_ci 1245f9996aaSopenharmony_ci build_configs_file = os.path.join(args.output_dir, 1255f9996aaSopenharmony_ci "subsystem_build_config.json") 1265f9996aaSopenharmony_ci write_json_file(build_configs_file, build_configs) 1275f9996aaSopenharmony_ci return 0 1285f9996aaSopenharmony_ci 1295f9996aaSopenharmony_ci 1305f9996aaSopenharmony_ciif __name__ == '__main__': 1315f9996aaSopenharmony_ci sys.exit(main()) 132