• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2021 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 os
17import json
18import sys
19import argparse
20from pyecharts import options as opts
21from pyecharts.charts import Tree
22from pyecharts.globals import CurrentConfig
23
24
25def read_json_file(input_file):
26    if not os.path.exists(input_file):
27        print("file '{}' doesn't exist.".format(input_file))
28        return None
29
30    data = None
31    try:
32        with open(input_file, 'r') as input_f:
33            data = json.load(input_f)
34    except json.decoder.JSONDecodeError:
35        print("The file '{}' format is incorrect.".format(input_file))
36        raise
37    return data
38
39
40class ModuleTree:
41    def __init__(self, data, inner_kits_adapter):
42        self.data = data
43        self.inner_kits_adapter = inner_kits_adapter
44        self.isroot = True
45        self.module_count = {}
46
47    def parse_part_module_name(self, node_name):
48        split_result = node_name.split(':')
49        part_name = split_result[0]
50        module_name = split_result[1]
51        return part_name, module_name
52
53    def get_label_color(self, node_name):
54        if self.module_count.get(node_name, 'no_module') == 'no_module':
55            self.module_count[node_name] = 1
56            label_opt = opts.LabelOpts(color='#000000',
57                                       font_style='normal',
58                                       font_family='Times New Roman',
59                                       font_size=16)
60        else:
61            self.module_count[node_name] += 1
62            label_opt = opts.LabelOpts(color='#ff0000',
63                                       font_style='normal',
64                                       font_family='Times New Roman',
65                                       font_size=16)
66        return label_opt
67
68    def node_tree(self, node_name):
69        if node_name not in self.data:
70            part_name, module_name = self.parse_part_module_name(node_name)
71            new_part_name = self.inner_kits_adapter.get(
72                part_name, "no_adapter")
73            old_node_name = node_name
74            if new_part_name != "no_adapter":
75                node_name = "{}:{}".format(new_part_name, module_name)
76            if node_name not in self.data:
77                if self.isroot:
78                    raise Exception(
79                        "module '{}' doesn't exist.".format(old_node_name))
80                else:
81                    print("Warning! module '{}' doesn't exist.".format(
82                        old_node_name))
83                    tree_data = {"name": node_name}
84                    return tree_data
85
86        self.isroot = False
87        module_deps = self.data.get(node_name)
88        if len(module_deps) > 0:
89            children = []
90            for module_dep in module_deps:
91                children.append(self.node_tree(module_dep))
92            tree_data = {"name": node_name, "children": children}
93        else:
94            tree_data = {"name": node_name}
95        return tree_data
96
97    def color_tree(self, tree_data):
98        color_tree_data = {}
99        queue = [tree_data]
100        while len(queue) > 0:
101            node = queue.pop(0)
102            label_opt = self.get_label_color(node["name"])
103            node["label_opt"] = label_opt
104            children = node.get("children", "no_children")
105            if children != "no_children":
106                queue.extend(children)
107        return tree_data
108
109    def graph_tree(self, tree_data):
110        children = tree_data.get("children", "no_children")
111        if children != "no_children":
112            for index, value in enumerate(children):
113                children[index] = self.graph_tree(children[index])
114            return opts.TreeItem(name=tree_data["name"],
115                                 label_opts=tree_data["label_opt"],
116                                 children=children)
117        else:
118            return opts.TreeItem(name=tree_data["name"],
119                                 label_opts=tree_data["label_opt"])
120
121    def get_node_tree(self, node_name):
122        self.isroot = True
123        tree_data = self.node_tree(node_name)
124        self.module_count = {}
125        tree_data = self.color_tree(tree_data)
126        tree = self.graph_tree(tree_data)
127        return tree
128
129
130def main(argv):
131    parser = argparse.ArgumentParser()
132    parser.add_argument('--module-name', required=True)
133    parser.add_argument('--module-deps-file', required=True)
134    args = parser.parse_args(argv)
135
136    node_name = args.module_name
137    inner_kits_adapter_file = os.path.join(
138        os.path.dirname(
139            os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
140        "ohos", "inner_kits_adapter.json")
141    output_file = os.path.join(os.path.dirname(args.module_deps_file),
142                               "{}.html".format(node_name.replace(":", "__")))
143    tree_title = "{} module dependency tree".format(node_name)
144    CurrentConfig.ONLINE_HOST = ("https://cdn.jsdelivr.net/npm/"
145                                 "echarts@latest/dist/")
146
147    print("------Generate module dependency tree------")
148    module_deps = read_json_file(args.module_deps_file)
149    inner_kits_adapter = read_json_file(inner_kits_adapter_file)
150
151    module_tree_ = ModuleTree(module_deps, inner_kits_adapter)
152    tree_data = module_tree_.get_node_tree(node_name)
153
154    tree = (Tree(opts.InitOpts(width="1920px", height="1080px")).add(
155        "", [tree_data],
156        orient="LR",
157        initial_tree_depth=1,
158        is_roam=True,
159        symbol_size=10).set_global_opts(title_opts=opts.TitleOpts(
160            title=tree_title)).render(output_file))
161    print('module deps tree output to {}'.format(output_file))
162    return 0
163
164
165if __name__ == '__main__':
166    sys.exit(main(sys.argv[1:]))
167