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