1#!/usr/bin/python3 2# -*- coding: utf-8 -*- 3""" 4Copyright (c) 2021 Huawei Device Co., Ltd. 5Licensed under the Apache License, Version 2.0 (the "License"); 6you may not use this file except in compliance with the License. 7You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11Unless required by applicable law or agreed to in writing, software 12distributed under the License is distributed on an "AS IS" BASIS, 13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14See the License for the specific language governing permissions and 15limitations under the License. 16 17""" 18 19import sys 20import os 21import argparse 22import re 23 24from graphviz import Digraph 25from component_node import Node 26from component_node import Module 27 28file_paths = [] 29module_dict = {} 30component_nodes = {} 31 32 33def draw_deps_pictrue_by_gn(output_path): 34 graph = Digraph('deps_graph') 35 for node_name in component_nodes: 36 graph.node(name=node_name, color='red') 37 for node_name in component_nodes: 38 deps = component_nodes[node_name].deps 39 external_deps = component_nodes[node_name].deps 40 all_deps = deps | external_deps 41 for dep_name in all_deps: 42 part_name = dep_name.split(':')[0] 43 module_name = dep_name.split(':')[-1] 44 if part_name in component_nodes: 45 graph.edge(node_name, part_name) 46 elif module_name in component_nodes: 47 graph.edge(node_name, module_name) 48 graph.render(filename=output_path+'/dep_graph') 49 50 51def merge_module(): 52 # create component nodes 53 for module_name in module_dict: 54 part_name = module_dict[module_name].part_name 55 if part_name in component_nodes: 56 component_nodes[part_name].add_module(module_dict[module_name]) 57 else: 58 if part_name != '': 59 component_nodes[part_name] = Node(part_name) 60 component_nodes[part_name].add_module(module_dict[module_name]) 61 elif module_name != '': 62 component_nodes[module_name] = Node(module_name) 63 component_nodes[module_name].add_module(module_dict[module_name]) 64 else: 65 pass 66 67 68def read_build_gn_file(file_path): 69 with open(file_path, 'r') as file: 70 file_data = file.read() 71 pattern = re.compile(r'ohos_shared_library.*?\}', re.DOTALL) 72 results = pattern.findall(file_data) 73 for ohos_module_string in results: 74 module = Module.create_module_by_string(ohos_module_string, True) 75 module_dict[module.module_name] = module 76 77 pattern = re.compile(r'ohos_executable.*?\}', re.DOTALL) 78 results = pattern.findall(file_data) 79 for ohos_module_string in results: 80 module = Module.create_module_by_string(ohos_module_string, False) 81 module_dict[module.module_name] = module 82 83 84 85def _colletct_build_gn_path(root_path): 86 for file in os.listdir(root_path): 87 file_path = os.path.join(root_path, file) 88 if file == 'BUILD.gn': 89 file_paths.append(file_path) 90 if os.path.isdir(file_path): 91 _colletct_build_gn_path(file_path) 92 93 94def collect_build_gn_path(root_path): 95 for file in os.listdir(root_path): 96 file_path = os.path.join(root_path, file) 97 if file != 'out' and os.path.isdir(file_path): 98 _colletct_build_gn_path(file_path) 99 100 101def main(argv): 102 parser = argparse.ArgumentParser() 103 parser.add_argument('--root-path', required=True) 104 parser.add_argument('--output', required=True) 105 args = parser.parse_args(argv) 106 107 collect_build_gn_path(args.root_path) 108 for gn_file in file_paths: 109 read_build_gn_file(gn_file) 110 111 merge_module() 112 draw_deps_pictrue_by_gn(args.output) 113 114 115if __name__ == '__main__': 116 sys.exit(main(sys.argv[1:]))