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