1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import json 19import os 20import sys 21import stat 22 23precise_repo_xts = sys.argv[1] 24DEEP = int(sys.argv[2]) if len(sys.argv) > 2 else -1 25home = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 26manifest_home = os.path.join(home, ".repo") 27preloader_path = os.path.join(home, "out", "preloader") 28PRECISE_GNI_NAME = "precise_run.gni" 29DEPENDS_TREE_NAME = "depends_tree.txt" 30F_DEPENDS_NAME = "f_depends.txt" 31MAX_PRECISE_PR_NUM = 20 32 33# 首层依赖关系dist 34dependency_dist = {} 35# 全量编译白名单 36whitelist = {"test/xts/acts", "build"} 37 38 39def get_f_dependes_dist(path): 40 count = 0 41 # 遍历目录下的所有文件和子目录 42 for root, dirs, files in os.walk(path): 43 for file in files: 44 if file == 'bundle.json': 45 count = count + 1 46 # 构建完整的文件路径 47 file_path = os.path.join(root, file) 48 # 读取 JSON 文件并转换为 Python 对象 49 with open(file_path, 'r', encoding='utf-8') as f: 50 json_data = json.load(f) 51 bundle_name = json_data['name'].split('/')[-1] 52 if "deps" not in json_data['component']: 53 continue 54 deps = json_data['component']['deps'] 55 # 依赖关系额写入dependency_dist 56 if bundle_name not in dependency_dist: 57 dependency_dist[bundle_name] = [] 58 if "components" in deps: 59 components_defs = deps['components'] 60 for c_def in components_defs: 61 if c_def in dependency_dist: 62 dependency_dist[c_def].append(bundle_name) 63 else: 64 dependency_dist[c_def] = [bundle_name] 65 if "third_party" in deps: 66 third_party_defs = deps['third_party'] 67 for t_def in third_party_defs: 68 if t_def in dependency_dist: 69 dependency_dist[t_def].append(bundle_name) 70 else: 71 dependency_dist[t_def] = [bundle_name] 72 print(count) 73 74 75def getbundname(path_list): 76 print(path_list) 77 bundle_list = [] 78 for path in path_list: 79 # 读取JSON文件并获取指定key的value 80 with open(os.path.join(home, path, "bundle.json"), 'r') as file: 81 data = json.load(file) 82 bundle_list.append(data['component']['name']) 83 return bundle_list 84 85 86def get_all_dependencies(nodes, dependencies): 87 visited = set() # 存储已访问的节点 88 string_buffer = [] 89 90 def dfs(node, num, string_buffer): 91 string_buffer.append(" " * num + node) # 追加内容到列表 92 if node in visited: 93 return 94 if DEEP != -1 and num > DEEP: 95 return 96 visited.add(node) 97 if node in dependencies: 98 for dependency in dependencies[node]: 99 dfs(dependency, num + 1, string_buffer) # 传递可变对象进行修改 100 101 for node in nodes: 102 dfs(node, 0, string_buffer) 103 104 return visited, string_buffer 105 106 107def write_precise_gni(depends_list, file_name): 108 # 将数组转换为字符串形式,例如使用逗号分隔 109 array_str = json.dumps(list(depends_list)) 110 111 # 打开文件并写入数组字符串 112 file_descriptor = os.open(file_name, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) 113 with os.fdopen(file_descriptor, 'w') as file: 114 file.write("precise_run=") 115 file.write(array_str) 116 117 118def write_file(depends_list, file_name): 119 file_descriptor = os.open(file_name, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) 120 with os.fdopen(file_descriptor, 'w') as f: 121 json.dump(depends_list, f, indent=4) 122 123 124def run(precise_repo_xts_list): 125 # pr数>MAX或在白名单中的 126 if len(precise_repo_xts_list) >= MAX_PRECISE_PR_NUM or any(item in precise_repo_xts_list for item in whitelist): 127 depends_tree = "all" 128 depends_list = {"all"} 129 else: 130 try: 131 # 获取bundle_name_list 132 bundlelist = getbundname(precise_repo_xts_list) 133 # 计算首层依赖map 134 get_f_dependes_dist(home) 135 print(bundlelist) 136 # 获取全部需要跑的bundlename 137 depends_list, depends_tree = get_all_dependencies(bundlelist, dependency_dist) 138 depends_list.add("acts") 139 print(depends_list) 140 except Exception as e: 141 print("发生异常:", str(e)) 142 depends_tree = "all" 143 depends_list = {"all"} 144 # 依赖树输出 145 write_file(depends_tree, os.path.join(preloader_path, DEPENDS_TREE_NAME)) 146 # 写入gni文件 147 write_precise_gni(depends_list, os.path.join(preloader_path, PRECISE_GNI_NAME)) 148 149 150if __name__ == '__main__': 151 print("counting dependencies start") 152 run(precise_repo_xts.split(',')) 153 print("counting dependencies finished")