15f9996aaSopenharmony_ci#!/usr/bin/env python 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci# Copyright (c) 2021 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_ci 205f9996aaSopenharmony_ci 215f9996aaSopenharmony_cisys.path.append( 225f9996aaSopenharmony_ci os.path.dirname(os.path.dirname(os.path.dirname( 235f9996aaSopenharmony_ci os.path.abspath(__file__))))) 245f9996aaSopenharmony_cifrom scripts.util.file_utils import read_json_file # noqa: E402 255f9996aaSopenharmony_ci 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_cidef check_third_party_deps(args, dep_part: str, parts_deps_info: dict, _tips_info: dict, third_deps_allow_list: list): 285f9996aaSopenharmony_ci """check whether the three-party dependency is in the part declaration""" 295f9996aaSopenharmony_ci if args.part_name == dep_part: 305f9996aaSopenharmony_ci return 315f9996aaSopenharmony_ci part_deps_info = parts_deps_info.get(args.part_name) 325f9996aaSopenharmony_ci if not part_deps_info: 335f9996aaSopenharmony_ci _warning_info = f"{_tips_info} {args.part_name}." 345f9996aaSopenharmony_ci elif not part_deps_info.get('third_party') or \ 355f9996aaSopenharmony_ci not dep_part in part_deps_info.get('third_party'): 365f9996aaSopenharmony_ci _warning_info = f"{_tips_info} {part_deps_info.get('build_config_file')}." 375f9996aaSopenharmony_ci else: 385f9996aaSopenharmony_ci _warning_info = "" 395f9996aaSopenharmony_ci 405f9996aaSopenharmony_ci if _warning_info != "": 415f9996aaSopenharmony_ci if args.target_path in third_deps_allow_list: 425f9996aaSopenharmony_ci print(f"[0/0] WARNING: {_warning_info}") 435f9996aaSopenharmony_ci else: 445f9996aaSopenharmony_ci raise Exception(_warning_info) 455f9996aaSopenharmony_ci 465f9996aaSopenharmony_ci return 475f9996aaSopenharmony_ci 485f9996aaSopenharmony_ci 495f9996aaSopenharmony_cidef load_part_info(depfiles: list): 505f9996aaSopenharmony_ci """load part path info from parts_info""" 515f9996aaSopenharmony_ci # load parts path info file 525f9996aaSopenharmony_ci parts_path_file = 'build_configs/parts_info/parts_path_info.json' 535f9996aaSopenharmony_ci parts_path_info = read_json_file(parts_path_file) 545f9996aaSopenharmony_ci if parts_path_info is None: 555f9996aaSopenharmony_ci raise Exception("read pre_build parts_path_info failed.") 565f9996aaSopenharmony_ci depfiles.append(parts_path_file) 575f9996aaSopenharmony_ci 585f9996aaSopenharmony_ci # load path to parts info file 595f9996aaSopenharmony_ci path_parts_file = 'build_configs/parts_info/path_to_parts.json' 605f9996aaSopenharmony_ci path_parts_info = read_json_file(path_parts_file) 615f9996aaSopenharmony_ci if path_parts_info is None: 625f9996aaSopenharmony_ci raise Exception("read pre_build path to parts failed.") 635f9996aaSopenharmony_ci depfiles.append(path_parts_file) 645f9996aaSopenharmony_ci 655f9996aaSopenharmony_ci return parts_path_info, path_parts_info 665f9996aaSopenharmony_ci 675f9996aaSopenharmony_ci 685f9996aaSopenharmony_cidef get_path_from_label(label: str): 695f9996aaSopenharmony_ci """get part path from target label, the format is //path:module""" 705f9996aaSopenharmony_ci return label.lstrip('//').split(':')[0] 715f9996aaSopenharmony_ci 725f9996aaSopenharmony_ci 735f9996aaSopenharmony_cidef get_path_from_module_list(cur_part_name: str, depfiles:list) -> str: 745f9996aaSopenharmony_ci parts_module_lists = [] 755f9996aaSopenharmony_ci parts_modules_file = "build_configs/parts_info/parts_modules_info.json" 765f9996aaSopenharmony_ci parts_modules_info = read_json_file(parts_modules_file) 775f9996aaSopenharmony_ci if parts_modules_info is None: 785f9996aaSopenharmony_ci raise Exception("read pre_build parts module info failed.") 795f9996aaSopenharmony_ci depfiles.append(parts_modules_file) 805f9996aaSopenharmony_ci 815f9996aaSopenharmony_ci for parts_module in parts_modules_info.get("parts"): 825f9996aaSopenharmony_ci if parts_module.get("part_name") == cur_part_name: 835f9996aaSopenharmony_ci parts_module_lists = parts_module["module_list"] 845f9996aaSopenharmony_ci break 855f9996aaSopenharmony_ci parts_path = [get_path_from_label(x) for x in parts_module_lists] 865f9996aaSopenharmony_ci 875f9996aaSopenharmony_ci return parts_path 885f9996aaSopenharmony_ci 895f9996aaSopenharmony_ci 905f9996aaSopenharmony_cidef get_part_pattern(cur_part_name: str, parts_path_info: dict, path_parts_info: dict, depfiles: list) -> list: 915f9996aaSopenharmony_ci """get all part path from part info""" 925f9996aaSopenharmony_ci part_pattern = [] 935f9996aaSopenharmony_ci part_path = parts_path_info.get(cur_part_name) 945f9996aaSopenharmony_ci if part_path is None: 955f9996aaSopenharmony_ci return part_pattern 965f9996aaSopenharmony_ci 975f9996aaSopenharmony_ci path_to_part = path_parts_info.get(part_path) 985f9996aaSopenharmony_ci if len(path_to_part) == 1: 995f9996aaSopenharmony_ci part_pattern.append(part_path) 1005f9996aaSopenharmony_ci else: 1015f9996aaSopenharmony_ci part_pattern.extend(get_path_from_module_list(cur_part_name, depfiles)) 1025f9996aaSopenharmony_ci 1035f9996aaSopenharmony_ci return part_pattern 1045f9996aaSopenharmony_ci 1055f9996aaSopenharmony_ci 1065f9996aaSopenharmony_cidef get_dep_part(dep_path: str, third_part_info: dict) -> str: 1075f9996aaSopenharmony_ci """gets the part by the longest path match""" 1085f9996aaSopenharmony_ci for part_info in third_part_info: 1095f9996aaSopenharmony_ci path = part_info[0] 1105f9996aaSopenharmony_ci part = part_info[1][0] 1115f9996aaSopenharmony_ci if dep_path.find(path) != -1: 1125f9996aaSopenharmony_ci return part 1135f9996aaSopenharmony_ci return "" 1145f9996aaSopenharmony_ci 1155f9996aaSopenharmony_ci 1165f9996aaSopenharmony_cidef check_part_deps(args, part_pattern: str, path_parts_info: dict, compile_standard_allow_info: dict, depfiles: list): 1175f9996aaSopenharmony_ci deps_allow_list = compile_standard_allow_info.get("deps_added_external_part_module", []) 1185f9996aaSopenharmony_ci third_deps_allow_list = compile_standard_allow_info.get("third_deps_bundle_not_add", []) 1195f9996aaSopenharmony_ci parts_deps_file = 'build_configs/parts_info/parts_deps.json' 1205f9996aaSopenharmony_ci parts_deps_info = read_json_file(parts_deps_file) 1215f9996aaSopenharmony_ci if parts_deps_info is None: 1225f9996aaSopenharmony_ci raise Exception("read pre_build parts_deps failed.") 1235f9996aaSopenharmony_ci depfiles.append(parts_deps_file) 1245f9996aaSopenharmony_ci 1255f9996aaSopenharmony_ci parts_src_flag_file = "build_configs/parts_src_flag.json" 1265f9996aaSopenharmony_ci parts_src_info = read_json_file(parts_src_flag_file) 1275f9996aaSopenharmony_ci third_party_allow_list = os.path.join(args.source_root_dir, "out/products_ext/third_party_allow_list.json") 1285f9996aaSopenharmony_ci if not os.path.exists(third_party_allow_list): 1295f9996aaSopenharmony_ci third_party_allow_list = os.path.join(args.source_root_dir, "build/third_party_allow_list.json") 1305f9996aaSopenharmony_ci third_party_allow_info = read_json_file(third_party_allow_list) 1315f9996aaSopenharmony_ci 1325f9996aaSopenharmony_ci # filter third_party part info, sort by longest path match 1335f9996aaSopenharmony_ci third_party_info = [x for x in path_parts_info.items() if x[0].find('third_party') != -1] 1345f9996aaSopenharmony_ci third_party_info.reverse() 1355f9996aaSopenharmony_ci for dep in args.deps: 1365f9996aaSopenharmony_ci dep_path = get_path_from_label(dep) 1375f9996aaSopenharmony_ci if dep_path.find('third_party/rust/crates') != -1: 1385f9996aaSopenharmony_ci continue 1395f9996aaSopenharmony_ci if dep_path.find('third_party') != -1: 1405f9996aaSopenharmony_ci dep_part = get_dep_part(dep_path, third_party_info) 1415f9996aaSopenharmony_ci 1425f9996aaSopenharmony_ci if dep_part not in parts_src_info and dep_part in third_party_allow_info: 1435f9996aaSopenharmony_ci print(f"[0/0] WARNING: deps third_party '{dep_part}' not configured in part config json, " 1445f9996aaSopenharmony_ci f"target: '{args.target_path}', deps: '{dep}'") 1455f9996aaSopenharmony_ci elif dep_part not in parts_src_info and dep_part not in third_party_allow_info: 1465f9996aaSopenharmony_ci raise Exception( 1475f9996aaSopenharmony_ci f"deps third_party '{dep_part}' not configured in part config json, " 1485f9996aaSopenharmony_ci f"target: '{args.target_path}', deps: '{dep}'") 1495f9996aaSopenharmony_ci 1505f9996aaSopenharmony_ci tips_info = "{} depend part {}, need set part deps {} info to".format( 1515f9996aaSopenharmony_ci args.target_path, dep, dep_part) 1525f9996aaSopenharmony_ci check_third_party_deps(args, dep_part, parts_deps_info, tips_info, third_deps_allow_list) 1535f9996aaSopenharmony_ci continue 1545f9996aaSopenharmony_ci 1555f9996aaSopenharmony_ci match_flag = False 1565f9996aaSopenharmony_ci for pattern in part_pattern: 1575f9996aaSopenharmony_ci if dep_path.startswith(pattern): 1585f9996aaSopenharmony_ci match_flag = True 1595f9996aaSopenharmony_ci break 1605f9996aaSopenharmony_ci if match_flag is False: 1615f9996aaSopenharmony_ci message = "deps validation part_name: '{}', target: '{}', dep: '{}' failed!!!".format( 1625f9996aaSopenharmony_ci args.part_name, args.target_path, dep) 1635f9996aaSopenharmony_ci if args.target_path in deps_allow_list: 1645f9996aaSopenharmony_ci print(f"[0/0] WARNING:{message}") 1655f9996aaSopenharmony_ci else: 1665f9996aaSopenharmony_ci raise Exception(message) 1675f9996aaSopenharmony_ci 1685f9996aaSopenharmony_ci 1695f9996aaSopenharmony_cidef check(args) -> list: 1705f9996aaSopenharmony_ci depfiles = [] 1715f9996aaSopenharmony_ci # ignore test related parts 1725f9996aaSopenharmony_ci part_allow_set = {'libc-test', 'libc-test-lib', 'libc-gtest-lib'} 1735f9996aaSopenharmony_ci if args.part_name in part_allow_set: 1745f9996aaSopenharmony_ci return depfiles 1755f9996aaSopenharmony_ci 1765f9996aaSopenharmony_ci compile_standard_allow_file = args.compile_standard_allow_file 1775f9996aaSopenharmony_ci compile_standard_allow_info = read_json_file(compile_standard_allow_file) 1785f9996aaSopenharmony_ci parts_path_info, path_parts_info = load_part_info(depfiles) 1795f9996aaSopenharmony_ci 1805f9996aaSopenharmony_ci part_pattern = get_part_pattern(args.part_name, parts_path_info, path_parts_info, depfiles) 1815f9996aaSopenharmony_ci if not part_pattern: 1825f9996aaSopenharmony_ci gn_allow_list = compile_standard_allow_info.get("gn_part_or_subsystem_error", []) 1835f9996aaSopenharmony_ci message = "part_name: '{}' path is not exist, please check target: '{}'".format( 1845f9996aaSopenharmony_ci args.part_name, args.target_path) 1855f9996aaSopenharmony_ci if args.target_path in gn_allow_list: 1865f9996aaSopenharmony_ci print(f"[0/0] {message}") 1875f9996aaSopenharmony_ci return depfiles 1885f9996aaSopenharmony_ci else: 1895f9996aaSopenharmony_ci raise Exception(message) 1905f9996aaSopenharmony_ci 1915f9996aaSopenharmony_ci check_part_deps(args, part_pattern, path_parts_info, compile_standard_allow_info, depfiles) 1925f9996aaSopenharmony_ci 1935f9996aaSopenharmony_ci return depfiles 1945f9996aaSopenharmony_ci 1955f9996aaSopenharmony_ci 1965f9996aaSopenharmony_cidef main(): 1975f9996aaSopenharmony_ci parser = argparse.ArgumentParser() 1985f9996aaSopenharmony_ci parser.add_argument('--deps', nargs='*', required=True) 1995f9996aaSopenharmony_ci parser.add_argument('--part-name', required=True) 2005f9996aaSopenharmony_ci parser.add_argument('--target-path', required=True) 2015f9996aaSopenharmony_ci parser.add_argument('--source-root-dir', required=True) 2025f9996aaSopenharmony_ci args = parser.parse_args() 2035f9996aaSopenharmony_ci 2045f9996aaSopenharmony_ci check(args) 2055f9996aaSopenharmony_ci 2065f9996aaSopenharmony_ci return 0 2075f9996aaSopenharmony_ci 2085f9996aaSopenharmony_ci 2095f9996aaSopenharmony_ciif __name__ == '__main__': 2105f9996aaSopenharmony_ci sys.exit(main()) 211