• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:]))