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 16import argparse 17import os 18import sys 19import stat 20import xml.etree.ElementTree as ET 21import pandas as pd 22from prettytable import PrettyTable 23 24from gn_check.check_gn import CheckGn 25from bundle_check.bundle_json_check import BundlesCheck 26 27 28class CsctGlobal(object): 29 """This is a gn variable check class""" 30 31 version = "" 32 csct_path = "" 33 ohos_root = "" 34 repo_url = "" 35 repo_num = "" 36 diff_files_path = "" 37 output_format = "" 38 check_path = "" 39 whitelist = () 40 41 def __init__(self) -> None: 42 version = "0.0.1" 43 self.csct_path = sys.path[0] 44 root = os.path.join(self.csct_path, "../../../..") 45 self.ohos_root = os.path.normpath(root) 46 self.whitelist = tuple() 47 48 def load_ohos_xml(self, path): 49 ret_dict = dict() 50 tree = ET.parse(path) 51 root = tree.getroot() 52 for node in root.iter(): 53 if node.tag != 'project': 54 continue 55 repo_info = node.attrib 56 ret_item = {repo_info['path']: repo_info['groups']} 57 ret_dict.update(ret_item) 58 return ret_dict 59 60 def handle_white_dir(self, check_path): 61 xml_dict = self.load_ohos_xml(os.path.join( 62 self.ohos_root, '.repo/manifests/ohos/ohos.xml')) 63 ret_list = ['device', 'vendor', 'build', 'third_party', 'out'] 64 for key, vlaues in xml_dict.items(): 65 if key.startswith('third_party'): 66 continue 67 if vlaues.find('ohos:mini') != -1: 68 ret_list.append(key) 69 elif vlaues.find('ohos:small') != -1: 70 ret_list.append(key) 71 72 if check_path: 73 ret_list = [x[len(check_path)+1:] 74 for x in ret_list if x.startswith(check_path)] 75 76 return tuple(ret_list) 77 78 def add_option(self, parser): 79 parser.add_argument( 80 "-w", 81 "--white_dir_on", 82 dest="white_dir_settings", 83 type=str, 84 default="on", 85 choices=["on", "off"], 86 help="turn on white dir function or not", 87 ) 88 parser.add_argument( 89 "-v", "--version", action="version", version=f"%(prog)s {self.version}." 90 ) 91 parser.add_argument( 92 "-gd", 93 "--generate_diff", 94 metavar=("repo", "prNum"), 95 dest="repo_pr", 96 nargs=2, 97 type=str, 98 help="generate diff files.", 99 ) 100 parser.add_argument( 101 "-cd", 102 "--check_diffs", 103 metavar="diffFilesPath", 104 dest="diff_files_path", 105 nargs=1, 106 type=str, 107 help="check all diff files as specific path.", 108 ) 109 parser.add_argument( 110 "-p", 111 metavar="path", 112 type=str, 113 dest="path", 114 help="check all files as specific path\ 115 (the current directory by default).", 116 ) 117 parser.add_argument( 118 "-o", 119 metavar="stdout/xls/json", 120 nargs=1, 121 dest="output_format", 122 default="stdout", 123 choices=["stdout", "xls", "json"], 124 type=str, 125 help="specific output format(stdout by default).", 126 ) 127 128 def store_args(self, args): 129 if args.repo_pr is not None: 130 self.repo_url = args.repo_pr[0] 131 self.repo_num = args.repo_pr[1] 132 self.diff_files_path = args.diff_files_path 133 self.output_format = args.output_format 134 if (args.path): 135 self.check_path = os.path.normpath(args.path) 136 self.white_dir_settings = args.white_dir_settings 137 138 def pre_check(self): 139 if self.white_dir_settings == 'on': 140 self.whitelist = self.handle_white_dir(self.check_path) 141 142 def start_check(self): 143 print("---Start check---\n") 144 # check all gn 145 gn_errs = CheckGn(self.ohos_root, black_dir=self.whitelist, 146 check_path=self.check_path).output() 147 148 # check all bundle.json 149 bundle_errs = BundlesCheck.to_df(self.check_path) 150 151 if not os.path.exists("out"): 152 os.mkdir("out") 153 out_path = os.path.join(os.getcwd(), "out") 154 table = PrettyTable(gn_errs.columns.to_list()) 155 table.add_rows(gn_errs.values.tolist()) 156 table_str = table.get_string() 157 flags = os.O_WRONLY | os.O_CREAT 158 modes = stat.S_IWUSR | stat.S_IRUSR 159 with os.fdopen( 160 os.open(os.path.join(out_path, "gn_problems.txt"), flags, modes), "w" 161 ) as file: 162 file.write(table_str) 163 164 # merge excel 165 output_path = os.path.join(out_path, "output_errors.xlsx") 166 with pd.ExcelWriter(output_path) as writer: 167 bundle_errs.to_excel(writer, sheet_name="bundle_check", index=None) 168 gn_errs.to_excel(writer, sheet_name="gn_check", index=None) 169 170 print("\nStatic check finish.\nPlease check: " + output_path) 171 return 172 173 def check_end(self): 174 print("\n---End check---") 175 return 176 177 178def main(): 179 csctglb = CsctGlobal() 180 parser = argparse.ArgumentParser( 181 description=f"Component Static Check Tool version {csctglb.version}", 182 ) 183 csctglb.add_option(parser) 184 args = parser.parse_args() 185 csctglb.store_args(args) 186 csctglb.pre_check() 187 csctglb.start_check() 188 csctglb.check_end() 189 return 0 190 191 192if __name__ == "__main__": 193 sys.exit(main()) 194