1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2024 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import argparse 17import json 18import os 19import time 20import stat 21import utils 22 23 24def _get_args(): 25 parser = argparse.ArgumentParser(add_help=True) 26 parser.add_argument( 27 "-p", "--input_path", 28 default=r"./", type=str, 29 help="Path of source code", 30 ) 31 parser.add_argument( 32 "-rp", "--root_path", 33 default=r"./", type=str, 34 help="Path of root", 35 ) 36 parser.add_argument( 37 "-t", "--test", 38 default=1, type=int, 39 help="whether the target contains test type. default 0 , choices: 0 or 1 2", 40 ) 41 args = parser.parse_args() 42 return args 43 44 45def _judge_type(element, deps_list: list): 46 if isinstance(element, dict): 47 for k, v in element.items(): 48 _judge_type(v, deps_list) 49 elif isinstance(element, list): 50 for v in element: 51 _judge_type(v, deps_list) 52 elif isinstance(element, str): 53 deps_list.append(element) 54 55 56def _inner_kits_name(inner_kits_list, deps_list): 57 if inner_kits_list: 58 for k in inner_kits_list: 59 deps_list.append(k['name']) 60 61 62def _output_build_gn(deps_list, output_path, _test_check): 63 file_name = os.path.join(output_path, 'BUILD.gn') 64 if os.path.exists(file_name): 65 os.remove(file_name) 66 flags = os.O_WRONLY | os.O_CREAT 67 modes = stat.S_IWUSR | stat.S_IRUSR 68 with os.fdopen(os.open(file_name, flags, modes), 'w') as f: 69 f.write('import("//build/ohos_var.gni")\n') 70 f.write('\n') 71 f.write('group("default") {\n') 72 if _test_check: 73 f.write(' testonly = true\n') 74 f.write(' deps = [\n') 75 for i in deps_list: 76 f.write(f" \"{i}\",\n") 77 f.write(' ]\n') 78 f.write('}\n') 79 80 81def _get_bundle_path(source_code_path): 82 bundle_paths = dict() 83 for root, dirs, files in os.walk(source_code_path): 84 for file in files: 85 if file == "bundle.json": 86 bundle_paths.update({os.path.join(root, file): root}) 87 return bundle_paths 88 89 90def _get_src_part_name(src_bundle_paths): 91 _name = '' 92 _path = '' 93 _bundle_path = '' 94 for src_bundle_path, v_path in src_bundle_paths.items(): 95 src_bundle_json = utils.get_json(src_bundle_path) 96 part_name = '' 97 try: 98 part_name = src_bundle_json['component']['name'] 99 except KeyError: 100 print(f'--get bundle json component name error--') 101 if part_name.endswith('_lite'): 102 pass 103 else: 104 _name = part_name 105 _bundle_path = src_bundle_path 106 _path = v_path 107 return _bundle_path, _path 108 109 110def _target_handle(ele, build_data, deps_list, _test_check): 111 if ele not in ['inner_kits', 'test', 'inner_api']: 112 _judge_type(build_data[ele], deps_list) 113 elif ele in ['inner_kits', 'inner_api']: 114 inner_kits_list = build_data[ele] 115 _inner_kits_name(inner_kits_list, deps_list) 116 117 if _test_check == 1 and ele == 'test': 118 inner_kits_list = build_data[ele] 119 for k in inner_kits_list: 120 deps_list.append(k) 121 122 123def process_build_data(build_data, _test_check, deps_list): 124 for ele in build_data: 125 _target_handle(ele, build_data, deps_list, _test_check) 126 127 128def handle_test_check(build_data, _test_check, deps_list): 129 if _test_check == 2: 130 inner_kits_list = build_data.get('test', []) 131 if inner_kits_list: 132 for k in inner_kits_list: 133 deps_list.append(k) 134 135 136def process_bundle_path(_bundle_path, _test_check, deps_list): 137 bundle_json = utils.get_json(_bundle_path) 138 build_data = bundle_json.get("component", {}).get("build", {}) 139 if _test_check == 0: 140 process_build_data(build_data, _test_check, deps_list) 141 elif _test_check == 1: 142 process_build_data(build_data, _test_check, deps_list) 143 handle_test_check(build_data, _test_check, deps_list) 144 elif _test_check == 2: 145 handle_test_check(build_data, _test_check, deps_list) 146 else: 147 print("Error: Please pass the correct test parameters") 148 149 150def process_inner_fields(module_to_path, all_target_list): 151 # 检查并处理可能的字段名称 152 for item in all_target_list: 153 fullpath = item 154 module = fullpath.split(":")[-1] 155 module_to_path[module] = fullpath 156 157 158def target_args_handle(_bundle_path, build_target_list, deps_list): 159 bundle_json = utils.get_json(_bundle_path) 160 build_data = bundle_json.get("component", {}).get("build", {}) 161 162 all_target_list = [] 163 module_to_path = {} 164 165 # 获取所有目标列表和module到全路径的映射 166 process_target_data(build_data, all_target_list, module_to_path) 167 168 # 处理构建目标列表,返回依赖列表 169 return process_build_target_list(build_target_list, module_to_path, deps_list) 170 171 172def process_target_data(build_data, all_target_list, module_to_path): 173 # 获取所有目标列表 174 process_build_data(build_data, 1, all_target_list) 175 # 获取module到全路径的映射 176 process_inner_fields(module_to_path, all_target_list) 177 178 179def process_build_target_list(build_target_list, module_to_path, deps_list): 180 for item in build_target_list: 181 if item.startswith("//"): 182 # 如果是全路径,直接添加 183 add_to_deps_list(deps_list, item) 184 else: 185 # 如果不是全路径,查找对应的module 186 fullpath = module_to_path.get(item) 187 if fullpath: 188 add_to_deps_list(deps_list, fullpath) 189 return deps_list 190 191 192def add_to_deps_list(deps_list, item): 193 if item not in deps_list: 194 deps_list.append(item) 195 196 197def main(): 198 args = _get_args() 199 source_code_paths = args.input_path.split(',') 200 _test_check = args.test 201 output_path = os.path.join(args.root_path, 'out') 202 deps_list = [] 203 build_target_list = utils.get_build_target() 204 205 for source_code_path in source_code_paths: 206 bundle_paths = _get_bundle_path(source_code_path) 207 for _bundle_path in bundle_paths: 208 if build_target_list: 209 deps_list = target_args_handle(_bundle_path, build_target_list, deps_list) 210 else: 211 process_bundle_path(_bundle_path, _test_check, deps_list) 212 _output_build_gn(deps_list, output_path, _test_check) 213 214 215if __name__ == '__main__': 216 main() 217