• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2022 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
16# This file is for get the mapping relationship of subsystem_name/component_name
17# and their directory. The code is from Yude Chen.
18
19__all__ = ["SC"]
20
21import argparse
22import os
23import json
24import logging
25
26g_subsystem_path_error = list()  # subsystem path exist in subsystem_config.json
27# bundle.json path which cant get component path.
28g_component_path_empty = list()
29g_component_abs_path = list()  # destPath can't be absolute path.
30
31
32def get_subsystem_components(ohos_path: str):
33    subsystem_json_path = os.path.join(
34        ohos_path, r"build/subsystem_config.json")
35    subsystem_item = {}
36
37    with open(subsystem_json_path, 'rb') as f:
38        subsystem_json = json.load(f)
39    # get sunsystems
40    for i in subsystem_json:
41        subsystem_name = subsystem_json[i]["name"]
42        subsystem_path = os.path.join(ohos_path, subsystem_json[i]["path"])
43        if not os.path.exists(subsystem_path):
44            g_subsystem_path_error.append(subsystem_path)
45            continue
46        cmd = 'find {} -name bundle.json'.format(subsystem_path)
47        bundle_json_list = os.popen(cmd).readlines()
48        # get components
49        component_list = []
50        for j in bundle_json_list:
51            bundle_path = j.strip()
52            with open(bundle_path, 'rb') as bundle_file:
53                bundle_json = json.load(bundle_file)
54            component_item = {}
55            if 'segment' in bundle_json and 'destPath' in bundle_json["segment"]:
56                destpath = bundle_json["segment"]["destPath"]
57                component_item[bundle_json["component"]["name"]] = destpath
58                if os.path.isabs(destpath):
59                    g_component_abs_path.append(destpath)
60            else:
61                component_item[bundle_json["component"]["name"]
62                               ] = "Unknow. Please check {}".format(bundle_path)
63                g_component_path_empty.append(bundle_path)
64            component_list.append(component_item)
65        subsystem_item[subsystem_name] = component_list
66    return subsystem_item
67
68
69def get_subsystem_components_modified(ohos_root) -> dict:
70    ret = dict()
71    subsystem_info = get_subsystem_components(ohos_root)
72    if subsystem_info is None:
73        return None
74    for subsystem_k, subsystem_v in subsystem_info.items():
75        for component in subsystem_v:
76            for k, v in component.items():
77                ret.update({v: {'subsystem': subsystem_k, 'component': k}})
78    return ret
79
80
81def export_to_json(subsystem_item: dict, output_filename: str):
82    subsystem_item_json = json.dumps(
83        subsystem_item, indent=4, separators=(', ', ': '))
84    with os.fdopen(os.open(output_filename, os.O_WRONLY | os.O_CREAT, mode=0o640), 'w') as f:
85        f.write(subsystem_item_json)
86    logging.info("output path: {}".format(output_filename))
87
88
89def parse_args():
90    parser = argparse.ArgumentParser()
91    parser.add_argument("project", help="project root path.", type=str)
92    parser.add_argument("-o", "--outpath",
93                        help="specify an output path.", type=str)
94    args = parser.parse_args()
95
96    ohos_path = os.path.abspath(args.project)
97    if not is_project(ohos_path):
98        logging.error("'{}' is not a valid project path.".format(ohos_path))
99        exit(1)
100
101    output_path = r'.'
102    if args.outpath:
103        output_path = args.outpath
104
105    return ohos_path, output_path
106
107
108def is_project(path: str) -> bool:
109    '''
110    @func: 判断是否源码工程。
111    @note: 通过是否含有 .repo/manifests 目录粗略判断。
112    '''
113    p = os.path.normpath(path)
114    return os.path.exists('{}/.repo/manifests'.format(p))
115
116
117def print_warning_info():
118    '''@func: 打印一些异常信息。
119    '''
120    if g_component_path_empty or g_component_abs_path:
121        logging.warning("------------ warning info ------------------")
122
123    if g_component_path_empty:
124        logging.warning("can't find destPath in:")
125        logging.warning(g_component_path_empty)
126
127    if g_component_abs_path:
128        logging.warning("destPath can't be absolute path:")
129        logging.warning(g_component_abs_path)
130
131
132class SC:
133    @classmethod
134    def run(cls, project_path: str, output_path: str = None, save_result: bool = True):
135        info = get_subsystem_components_modified(
136            os.path.abspath(os.path.expanduser(project_path)))
137        if save_result and output_path:
138            export_to_json(info, output_path)
139        print_warning_info()
140        return info