1ba991379Sopenharmony_ci#!/usr/bin/env python3 2ba991379Sopenharmony_ci# -*- coding: utf-8 -*- 3ba991379Sopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd. 4ba991379Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 5ba991379Sopenharmony_ci# you may not use this file except in compliance with the License. 6ba991379Sopenharmony_ci# You may obtain a copy of the License at 7ba991379Sopenharmony_ci# 8ba991379Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 9ba991379Sopenharmony_ci# 10ba991379Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 11ba991379Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 12ba991379Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba991379Sopenharmony_ci# See the License for the specific language governing permissions and 14ba991379Sopenharmony_ci# limitations under the License. 15ba991379Sopenharmony_ci 16ba991379Sopenharmony_ci# This file contains a RomAnalyzer for rom analyzation of standard device. 17ba991379Sopenharmony_ci 18ba991379Sopenharmony_ciimport argparse 19ba991379Sopenharmony_ciimport json 20ba991379Sopenharmony_ciimport os 21ba991379Sopenharmony_ciimport sys 22ba991379Sopenharmony_ciimport typing 23ba991379Sopenharmony_cifrom copy import deepcopy 24ba991379Sopenharmony_cifrom typing import Dict, Any, Iterator, List, Text 25ba991379Sopenharmony_ciimport re 26ba991379Sopenharmony_ciimport subprocess 27ba991379Sopenharmony_cifrom pkgs.rom_ram_baseline_collector import RomRamBaselineCollector 28ba991379Sopenharmony_cifrom pkgs.basic_tool import BasicTool, unit_adaptive 29ba991379Sopenharmony_cifrom pkgs.gn_common_tool import GnCommonTool, GnVariableParser 30ba991379Sopenharmony_cifrom pkgs.simple_excel_writer import SimpleExcelWriter 31ba991379Sopenharmony_ci 32ba991379Sopenharmony_cidebug = bool(sys.gettrace()) 33ba991379Sopenharmony_ci 34ba991379Sopenharmony_ciNOTFOUND = "NOTFOUND" 35ba991379Sopenharmony_ci 36ba991379Sopenharmony_ci 37ba991379Sopenharmony_ciclass PreCollector: 38ba991379Sopenharmony_ci """ 39ba991379Sopenharmony_ci collect some info that system_module_info.json dosn't contains 40ba991379Sopenharmony_ci """ 41ba991379Sopenharmony_ci 42ba991379Sopenharmony_ci def __init__(self, project_path: str) -> None: 43ba991379Sopenharmony_ci self.info_dict: Dict[str, Any] = dict() 44ba991379Sopenharmony_ci self.project_path = BasicTool.get_abs_path(project_path) 45ba991379Sopenharmony_ci self.result_dict = dict() 46ba991379Sopenharmony_ci 47ba991379Sopenharmony_ci def collect_sa_profile(self): 48ba991379Sopenharmony_ci grep_kw = r"ohos_sa_profile" 49ba991379Sopenharmony_ci grep_cmd = f"grep -rn '{grep_kw}' --include=BUILD.gn {self.project_path}" 50ba991379Sopenharmony_ci content = BasicTool.execute( 51ba991379Sopenharmony_ci grep_cmd, post_processor=lambda x: x.split('\n')) 52ba991379Sopenharmony_ci for item in content: 53ba991379Sopenharmony_ci if not item: 54ba991379Sopenharmony_ci continue 55ba991379Sopenharmony_ci self._process_single_sa(item, start_pattern=grep_kw) 56ba991379Sopenharmony_ci 57ba991379Sopenharmony_ci def _process_single_sa(self, item: str, start_pattern: str): 58ba991379Sopenharmony_ci gn, _, _ = item.split(':') 59ba991379Sopenharmony_ci with open(gn, 'r', encoding='utf-8') as f: 60ba991379Sopenharmony_ci content = f.read() 61ba991379Sopenharmony_ci p_itr: Iterator[re.Match] = BasicTool.match_paragraph( 62ba991379Sopenharmony_ci content=content, start_pattern=start_pattern) 63ba991379Sopenharmony_ci for p in p_itr: 64ba991379Sopenharmony_ci p_content = p.group() 65ba991379Sopenharmony_ci files: List[str] = GnVariableParser.list_parser( 66ba991379Sopenharmony_ci "sources", p_content) 67ba991379Sopenharmony_ci component_name, subsystem_name = GnCommonTool.find_part_subsystem( 68ba991379Sopenharmony_ci gn, self.project_path) 69ba991379Sopenharmony_ci for f in files: 70ba991379Sopenharmony_ci f = f.split('/')[-1] 71ba991379Sopenharmony_ci self.result_dict[f] = { 72ba991379Sopenharmony_ci "subsystem_name": subsystem_name, 73ba991379Sopenharmony_ci "component_name": component_name, 74ba991379Sopenharmony_ci "gn_path": gn 75ba991379Sopenharmony_ci } 76ba991379Sopenharmony_ci 77ba991379Sopenharmony_ci 78ba991379Sopenharmony_ciclass RomAnalyzer: 79ba991379Sopenharmony_ci @classmethod 80ba991379Sopenharmony_ci def analysis(cls, system_module_info_json: Text, product_dirs: List[str], 81ba991379Sopenharmony_ci project_path: Text, product_name: Text, output_file: Text, output_execel: bool, add_baseline: bool, 82ba991379Sopenharmony_ci unit_adapt: bool): 83ba991379Sopenharmony_ci """ 84ba991379Sopenharmony_ci system_module_info_json: json文件 85ba991379Sopenharmony_ci product_dirs:要处理的产物的路径列表如["vendor", "system/"] 86ba991379Sopenharmony_ci project_path: 项目根路径 87ba991379Sopenharmony_ci product_name: eg,rk3568 88ba991379Sopenharmony_ci output_file: basename of output file 89ba991379Sopenharmony_ci """ 90ba991379Sopenharmony_ci project_path = BasicTool.get_abs_path(project_path) 91ba991379Sopenharmony_ci rom_baseline_dict: Dict[str, Any] = RomRamBaselineCollector.collect( 92ba991379Sopenharmony_ci project_path) 93ba991379Sopenharmony_ci with os.fdopen(os.open("rom_ram_baseline.json", os.O_WRONLY | os.O_CREAT, mode=0o640), 'w', encoding='utf-8') as f: 94ba991379Sopenharmony_ci json.dump(rom_baseline_dict, f, indent=4) 95ba991379Sopenharmony_ci phone_dir = os.path.join( 96ba991379Sopenharmony_ci project_path, "out", product_name, "packages", "phone") 97ba991379Sopenharmony_ci product_dirs = [os.path.join(phone_dir, d) for d in product_dirs] 98ba991379Sopenharmony_ci pre_collector = PreCollector(project_path) 99ba991379Sopenharmony_ci pre_collector.collect_sa_profile() 100ba991379Sopenharmony_ci extra_product_info_dict: Dict[str, Dict] = pre_collector.result_dict 101ba991379Sopenharmony_ci product_info_dict = cls.__collect_product_info( 102ba991379Sopenharmony_ci system_module_info_json, project_path, 103ba991379Sopenharmony_ci extra_info=extra_product_info_dict) # collect product info from json file 104ba991379Sopenharmony_ci result_dict: Dict[Text:Dict] = dict() 105ba991379Sopenharmony_ci for d in product_dirs: 106ba991379Sopenharmony_ci file_list: List[Text] = BasicTool.find_all_files(d) 107ba991379Sopenharmony_ci for f in file_list: 108ba991379Sopenharmony_ci size = os.path.getsize(f) 109ba991379Sopenharmony_ci relative_filepath = f.replace(phone_dir, "").lstrip(os.sep) 110ba991379Sopenharmony_ci unit: Dict[Text, Any] = product_info_dict.get( 111ba991379Sopenharmony_ci relative_filepath) 112ba991379Sopenharmony_ci if not unit: 113ba991379Sopenharmony_ci bf = f.split('/')[-1] 114ba991379Sopenharmony_ci unit: Dict[Text, Any] = product_info_dict.get(bf) 115ba991379Sopenharmony_ci if not unit: 116ba991379Sopenharmony_ci unit = dict() 117ba991379Sopenharmony_ci unit["size"] = size 118ba991379Sopenharmony_ci unit["relative_filepath"] = relative_filepath 119ba991379Sopenharmony_ci cls.__put(unit, result_dict, rom_baseline_dict, add_baseline) 120ba991379Sopenharmony_ci output_dir, _ = os.path.split(output_file) 121ba991379Sopenharmony_ci if len(output_dir) != 0: 122ba991379Sopenharmony_ci os.makedirs(output_dir, exist_ok=True) 123ba991379Sopenharmony_ci if unit_adapt: 124ba991379Sopenharmony_ci cls.result_unit_adaptive(result_dict) 125ba991379Sopenharmony_ci with os.fdopen(os.open(output_file + ".json", os.O_WRONLY | os.O_CREAT, mode=0o640), 'w', encoding='utf-8') as f: 126ba991379Sopenharmony_ci f.write(json.dumps(result_dict, indent=4)) 127ba991379Sopenharmony_ci if output_execel: 128ba991379Sopenharmony_ci cls.__save_result_as_excel(result_dict, output_file, add_baseline) 129ba991379Sopenharmony_ci 130ba991379Sopenharmony_ci @classmethod 131ba991379Sopenharmony_ci def result_unit_adaptive(self, result_dict: Dict[str, Dict]) -> None: 132ba991379Sopenharmony_ci for subsystem_name, subsystem_info in result_dict.items(): 133ba991379Sopenharmony_ci size = unit_adaptive(subsystem_info["size"]) 134ba991379Sopenharmony_ci count = subsystem_info["file_count"] 135ba991379Sopenharmony_ci if "size" in subsystem_info.keys(): 136ba991379Sopenharmony_ci del subsystem_info["size"] 137ba991379Sopenharmony_ci if "file_count" in subsystem_info.keys(): 138ba991379Sopenharmony_ci del subsystem_info["file_count"] 139ba991379Sopenharmony_ci for component_name, component_info in subsystem_info.items(): 140ba991379Sopenharmony_ci component_info["size"] = unit_adaptive(component_info["size"]) 141ba991379Sopenharmony_ci subsystem_info["size"] = size 142ba991379Sopenharmony_ci subsystem_info["file_count"] = count 143ba991379Sopenharmony_ci 144ba991379Sopenharmony_ci @classmethod 145ba991379Sopenharmony_ci def __collect_product_info(cls, system_module_info_json: Text, 146ba991379Sopenharmony_ci project_path: Text, extra_info: Dict[str, Dict]) -> Dict[Text, Dict[Text, Text]]: 147ba991379Sopenharmony_ci """ 148ba991379Sopenharmony_ci 根据system_module_info.json生成target字典 149ba991379Sopenharmony_ci format: 150ba991379Sopenharmony_ci { 151ba991379Sopenharmony_ci "{file_name}":{ 152ba991379Sopenharmony_ci "{subsytem_name}": abc, 153ba991379Sopenharmony_ci "{component_name}": def, 154ba991379Sopenharmony_ci "{gn_path}": ghi 155ba991379Sopenharmony_ci } 156ba991379Sopenharmony_ci } 157ba991379Sopenharmony_ci if the unit of system_module_info.json has not field "label" and the "type" is "sa_profile", 158ba991379Sopenharmony_ci find the subsystem_name and component_name in the BUILD.gn 159ba991379Sopenharmony_ci """ 160ba991379Sopenharmony_ci with open(system_module_info_json, 'r', encoding='utf-8') as f: 161ba991379Sopenharmony_ci product_list = json.loads(f.read()) 162ba991379Sopenharmony_ci project_path = BasicTool.get_abs_path(project_path) 163ba991379Sopenharmony_ci product_info_dict: Dict[Text, Dict[Text, Text]] = dict() 164ba991379Sopenharmony_ci for unit in product_list: 165ba991379Sopenharmony_ci cs_flag = False 166ba991379Sopenharmony_ci dest: List = unit.get("dest") 167ba991379Sopenharmony_ci if not dest: 168ba991379Sopenharmony_ci print("warning: keyword 'dest' not found in {}".format( 169ba991379Sopenharmony_ci system_module_info_json)) 170ba991379Sopenharmony_ci continue 171ba991379Sopenharmony_ci label: Text = unit.get("label") 172ba991379Sopenharmony_ci gn_path = component_name = subsystem_name = None 173ba991379Sopenharmony_ci if label: 174ba991379Sopenharmony_ci cs_flag = True 175ba991379Sopenharmony_ci gn_path = os.path.join(project_path, label.split(':')[ 176ba991379Sopenharmony_ci 0].lstrip('/'), "BUILD.gn") 177ba991379Sopenharmony_ci component_name = unit.get("part_name") 178ba991379Sopenharmony_ci subsystem_name = unit.get("subsystem_name") 179ba991379Sopenharmony_ci if not component_name: 180ba991379Sopenharmony_ci cn, sn = GnCommonTool.find_part_subsystem( 181ba991379Sopenharmony_ci gn_path, project_path) 182ba991379Sopenharmony_ci component_name = cn 183ba991379Sopenharmony_ci if not subsystem_name: 184ba991379Sopenharmony_ci cn, sn = GnCommonTool.find_part_subsystem( 185ba991379Sopenharmony_ci gn_path, project_path) 186ba991379Sopenharmony_ci subsystem_name = sn 187ba991379Sopenharmony_ci else: 188ba991379Sopenharmony_ci print("warning: keyword 'label' not found in {}".format(unit)) 189ba991379Sopenharmony_ci for target in dest: 190ba991379Sopenharmony_ci if cs_flag: 191ba991379Sopenharmony_ci product_info_dict[target] = { 192ba991379Sopenharmony_ci "component_name": component_name, 193ba991379Sopenharmony_ci "subsystem_name": subsystem_name, 194ba991379Sopenharmony_ci "gn_path": gn_path, 195ba991379Sopenharmony_ci } 196ba991379Sopenharmony_ci continue 197ba991379Sopenharmony_ci tmp = target.split('/')[-1] 198ba991379Sopenharmony_ci pre_info = extra_info.get(tmp) 199ba991379Sopenharmony_ci if not pre_info: 200ba991379Sopenharmony_ci continue 201ba991379Sopenharmony_ci else: 202ba991379Sopenharmony_ci product_info_dict[target] = pre_info 203ba991379Sopenharmony_ci return product_info_dict 204ba991379Sopenharmony_ci 205ba991379Sopenharmony_ci @classmethod 206ba991379Sopenharmony_ci def __inside_save_result_as_excel(cls, add_baseline, subsystem_name, component_name, 207ba991379Sopenharmony_ci baseline, file_name, size): 208ba991379Sopenharmony_ci if add_baseline: 209ba991379Sopenharmony_ci return [subsystem_name, component_name, 210ba991379Sopenharmony_ci baseline, file_name, size] 211ba991379Sopenharmony_ci else: 212ba991379Sopenharmony_ci return [subsystem_name, component_name, file_name, size] 213ba991379Sopenharmony_ci 214ba991379Sopenharmony_ci @classmethod 215ba991379Sopenharmony_ci def __save_result_as_excel(cls, result_dict: dict, output_name: str, add_baseline: bool): 216ba991379Sopenharmony_ci header = ["subsystem_name", "component_name", 217ba991379Sopenharmony_ci "output_file", "size(Byte)"] 218ba991379Sopenharmony_ci if add_baseline: 219ba991379Sopenharmony_ci header = ["subsystem_name", "component_name", "baseline", 220ba991379Sopenharmony_ci "output_file", "size(Byte)"] 221ba991379Sopenharmony_ci tmp_dict = deepcopy(result_dict) 222ba991379Sopenharmony_ci excel_writer = SimpleExcelWriter("rom") 223ba991379Sopenharmony_ci excel_writer.set_sheet_header(headers=header) 224ba991379Sopenharmony_ci subsystem_start_row = 1 225ba991379Sopenharmony_ci subsystem_end_row = 0 226ba991379Sopenharmony_ci subsystem_col = 0 227ba991379Sopenharmony_ci component_start_row = 1 228ba991379Sopenharmony_ci component_end_row = 0 229ba991379Sopenharmony_ci component_col = 1 230ba991379Sopenharmony_ci if add_baseline: 231ba991379Sopenharmony_ci baseline_col = 2 232ba991379Sopenharmony_ci for subsystem_name in tmp_dict.keys(): 233ba991379Sopenharmony_ci subsystem_dict = tmp_dict.get(subsystem_name) 234ba991379Sopenharmony_ci subsystem_size = subsystem_dict.get("size") 235ba991379Sopenharmony_ci subsystem_file_count = subsystem_dict.get("file_count") 236ba991379Sopenharmony_ci del subsystem_dict["file_count"] 237ba991379Sopenharmony_ci del subsystem_dict["size"] 238ba991379Sopenharmony_ci subsystem_end_row += subsystem_file_count 239ba991379Sopenharmony_ci 240ba991379Sopenharmony_ci for component_name in subsystem_dict.keys(): 241ba991379Sopenharmony_ci component_dict: Dict[str, int] = subsystem_dict.get( 242ba991379Sopenharmony_ci component_name) 243ba991379Sopenharmony_ci component_size = component_dict.get("size") 244ba991379Sopenharmony_ci component_file_count = component_dict.get("file_count") 245ba991379Sopenharmony_ci baseline = component_dict.get("baseline") 246ba991379Sopenharmony_ci del component_dict["file_count"] 247ba991379Sopenharmony_ci del component_dict["size"] 248ba991379Sopenharmony_ci if add_baseline: 249ba991379Sopenharmony_ci del component_dict["baseline"] 250ba991379Sopenharmony_ci component_end_row += component_file_count 251ba991379Sopenharmony_ci 252ba991379Sopenharmony_ci for file_name, size in component_dict.items(): 253ba991379Sopenharmony_ci line = cls.__inside_save_result_as_excel(add_baseline, subsystem_name, component_name, 254ba991379Sopenharmony_ci baseline, file_name, size) 255ba991379Sopenharmony_ci excel_writer.append_line(line) 256ba991379Sopenharmony_ci excel_writer.write_merge(component_start_row, component_col, component_end_row, component_col, 257ba991379Sopenharmony_ci component_name) 258ba991379Sopenharmony_ci if add_baseline: 259ba991379Sopenharmony_ci excel_writer.write_merge(component_start_row, baseline_col, component_end_row, baseline_col, 260ba991379Sopenharmony_ci baseline) 261ba991379Sopenharmony_ci component_start_row = component_end_row + 1 262ba991379Sopenharmony_ci excel_writer.write_merge(subsystem_start_row, subsystem_col, subsystem_end_row, subsystem_col, 263ba991379Sopenharmony_ci subsystem_name) 264ba991379Sopenharmony_ci subsystem_start_row = subsystem_end_row + 1 265ba991379Sopenharmony_ci excel_writer.save(output_name + ".xls") 266ba991379Sopenharmony_ci 267ba991379Sopenharmony_ci @classmethod 268ba991379Sopenharmony_ci def __put(cls, unit: typing.Dict[Text, Any], result_dict: typing.Dict[Text, Dict], baseline_dict: Dict[str, Any], 269ba991379Sopenharmony_ci baseline: bool): 270ba991379Sopenharmony_ci 271ba991379Sopenharmony_ci component_name = NOTFOUND if unit.get( 272ba991379Sopenharmony_ci "component_name") is None else unit.get("component_name") 273ba991379Sopenharmony_ci subsystem_name = NOTFOUND if unit.get( 274ba991379Sopenharmony_ci "subsystem_name") is None else unit.get("subsystem_name") 275ba991379Sopenharmony_ci 276ba991379Sopenharmony_ci def get_rom_baseline(): 277ba991379Sopenharmony_ci if (not baseline_dict.get(subsystem_name)) or (not baseline_dict.get(subsystem_name).get(component_name)): 278ba991379Sopenharmony_ci return str() 279ba991379Sopenharmony_ci return baseline_dict.get(subsystem_name).get(component_name).get("rom") 280ba991379Sopenharmony_ci 281ba991379Sopenharmony_ci size = unit.get("size") 282ba991379Sopenharmony_ci relative_filepath = unit.get("relative_filepath") 283ba991379Sopenharmony_ci if result_dict.get(subsystem_name) is None: # 子系统 284ba991379Sopenharmony_ci result_dict[subsystem_name] = dict() 285ba991379Sopenharmony_ci result_dict[subsystem_name]["size"] = 0 286ba991379Sopenharmony_ci result_dict[subsystem_name]["file_count"] = 0 287ba991379Sopenharmony_ci 288ba991379Sopenharmony_ci if result_dict.get(subsystem_name).get(component_name) is None: # 部件 289ba991379Sopenharmony_ci result_dict[subsystem_name][component_name] = dict() 290ba991379Sopenharmony_ci result_dict[subsystem_name][component_name]["size"] = 0 291ba991379Sopenharmony_ci result_dict[subsystem_name][component_name]["file_count"] = 0 292ba991379Sopenharmony_ci if baseline: 293ba991379Sopenharmony_ci result_dict[subsystem_name][component_name]["baseline"] = get_rom_baseline( 294ba991379Sopenharmony_ci ) 295ba991379Sopenharmony_ci 296ba991379Sopenharmony_ci result_dict[subsystem_name]["size"] += size 297ba991379Sopenharmony_ci result_dict[subsystem_name]["file_count"] += 1 298ba991379Sopenharmony_ci result_dict[subsystem_name][component_name]["size"] += size 299ba991379Sopenharmony_ci result_dict[subsystem_name][component_name]["file_count"] += 1 300ba991379Sopenharmony_ci result_dict[subsystem_name][component_name][relative_filepath] = size 301ba991379Sopenharmony_ci 302ba991379Sopenharmony_ci 303ba991379Sopenharmony_cidef get_args(): 304ba991379Sopenharmony_ci version_num = 2.0 305ba991379Sopenharmony_ci parser = argparse.ArgumentParser( 306ba991379Sopenharmony_ci description=f"analyze rom size of component.\n") 307ba991379Sopenharmony_ci parser.add_argument("-v", "-version", action="version", 308ba991379Sopenharmony_ci version=f"version {version_num}") 309ba991379Sopenharmony_ci parser.add_argument("-p", "--project_path", type=str, required=True, 310ba991379Sopenharmony_ci help="root path of openharmony. eg: -p ~/openharmony") 311ba991379Sopenharmony_ci parser.add_argument("-j", "--module_info_json", required=True, type=str, 312ba991379Sopenharmony_ci help="path of out/{product_name}/packages/phone/system_module_info.json") 313ba991379Sopenharmony_ci parser.add_argument("-n", "--product_name", required=True, 314ba991379Sopenharmony_ci type=str, help="product name. eg: -n rk3568") 315ba991379Sopenharmony_ci parser.add_argument("-d", "--product_dir", required=True, action="append", 316ba991379Sopenharmony_ci help="subdirectories of out/{product_name}/packages/phone to be counted." 317ba991379Sopenharmony_ci "eg: -d system -d vendor") 318ba991379Sopenharmony_ci parser.add_argument("-b", "--baseline", action="store_true", 319ba991379Sopenharmony_ci help="add baseline of component to the result(-b) or not.") 320ba991379Sopenharmony_ci parser.add_argument("-o", "--output_file", type=str, default="rom_analysis_result", 321ba991379Sopenharmony_ci help="basename of output file, default: rom_analysis_result. eg: demo/rom_analysis_result") 322ba991379Sopenharmony_ci parser.add_argument("-u", "--unit_adaptive", 323ba991379Sopenharmony_ci action="store_true", help="unit adaptive") 324ba991379Sopenharmony_ci parser.add_argument("-e", "--excel", type=bool, default=False, 325ba991379Sopenharmony_ci help="if output result as excel, default: False. eg: -e True") 326ba991379Sopenharmony_ci args = parser.parse_args() 327ba991379Sopenharmony_ci return args 328ba991379Sopenharmony_ci 329ba991379Sopenharmony_ci 330ba991379Sopenharmony_ciif __name__ == '__main__': 331ba991379Sopenharmony_ci args = get_args() 332ba991379Sopenharmony_ci module_info_json = args.module_info_json 333ba991379Sopenharmony_ci project_origin_path = args.project_path 334ba991379Sopenharmony_ci product = args.product_name 335ba991379Sopenharmony_ci product_dirs = args.product_dir 336ba991379Sopenharmony_ci output_file_name = args.output_file 337ba991379Sopenharmony_ci output_excel = args.excel 338ba991379Sopenharmony_ci baseline_path = args.baseline 339ba991379Sopenharmony_ci unit_adaptiv = args.unit_adaptive 340ba991379Sopenharmony_ci RomAnalyzer.analysis(module_info_json, product_dirs, 341ba991379Sopenharmony_ci project_origin_path, product, output_file_name, output_excel, baseline_path, unit_adaptiv) 342