15f9996aaSopenharmony_ci#!/usr/bin/env python3 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci# Copyright (c) 2022 Huawei Device Co., Ltd. 45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 65f9996aaSopenharmony_ci# You may obtain a copy of the License at 75f9996aaSopenharmony_ci# 85f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 145f9996aaSopenharmony_ci# limitations under the License. 155f9996aaSopenharmony_ci 165f9996aaSopenharmony_ciimport argparse 175f9996aaSopenharmony_ciimport os 185f9996aaSopenharmony_ciimport sys 195f9996aaSopenharmony_ciimport stat 205f9996aaSopenharmony_ciimport xml.etree.ElementTree as ET 215f9996aaSopenharmony_ciimport pandas as pd 225f9996aaSopenharmony_cifrom prettytable import PrettyTable 235f9996aaSopenharmony_ci 245f9996aaSopenharmony_cifrom gn_check.check_gn import CheckGn 255f9996aaSopenharmony_cifrom bundle_check.bundle_json_check import BundlesCheck 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_ci 285f9996aaSopenharmony_ciclass CsctGlobal(object): 295f9996aaSopenharmony_ci """This is a gn variable check class""" 305f9996aaSopenharmony_ci 315f9996aaSopenharmony_ci version = "" 325f9996aaSopenharmony_ci csct_path = "" 335f9996aaSopenharmony_ci ohos_root = "" 345f9996aaSopenharmony_ci repo_url = "" 355f9996aaSopenharmony_ci repo_num = "" 365f9996aaSopenharmony_ci diff_files_path = "" 375f9996aaSopenharmony_ci output_format = "" 385f9996aaSopenharmony_ci check_path = "" 395f9996aaSopenharmony_ci whitelist = () 405f9996aaSopenharmony_ci 415f9996aaSopenharmony_ci def __init__(self) -> None: 425f9996aaSopenharmony_ci version = "0.0.1" 435f9996aaSopenharmony_ci self.csct_path = sys.path[0] 445f9996aaSopenharmony_ci root = os.path.join(self.csct_path, "../../../..") 455f9996aaSopenharmony_ci self.ohos_root = os.path.normpath(root) 465f9996aaSopenharmony_ci self.whitelist = tuple() 475f9996aaSopenharmony_ci 485f9996aaSopenharmony_ci def load_ohos_xml(self, path): 495f9996aaSopenharmony_ci ret_dict = dict() 505f9996aaSopenharmony_ci tree = ET.parse(path) 515f9996aaSopenharmony_ci root = tree.getroot() 525f9996aaSopenharmony_ci for node in root.iter(): 535f9996aaSopenharmony_ci if node.tag != 'project': 545f9996aaSopenharmony_ci continue 555f9996aaSopenharmony_ci repo_info = node.attrib 565f9996aaSopenharmony_ci ret_item = {repo_info['path']: repo_info['groups']} 575f9996aaSopenharmony_ci ret_dict.update(ret_item) 585f9996aaSopenharmony_ci return ret_dict 595f9996aaSopenharmony_ci 605f9996aaSopenharmony_ci def handle_white_dir(self, check_path): 615f9996aaSopenharmony_ci xml_dict = self.load_ohos_xml(os.path.join( 625f9996aaSopenharmony_ci self.ohos_root, '.repo/manifests/ohos/ohos.xml')) 635f9996aaSopenharmony_ci ret_list = ['device', 'vendor', 'build', 'third_party', 'out'] 645f9996aaSopenharmony_ci for key, vlaues in xml_dict.items(): 655f9996aaSopenharmony_ci if key.startswith('third_party'): 665f9996aaSopenharmony_ci continue 675f9996aaSopenharmony_ci if vlaues.find('ohos:mini') != -1: 685f9996aaSopenharmony_ci ret_list.append(key) 695f9996aaSopenharmony_ci elif vlaues.find('ohos:small') != -1: 705f9996aaSopenharmony_ci ret_list.append(key) 715f9996aaSopenharmony_ci 725f9996aaSopenharmony_ci if check_path: 735f9996aaSopenharmony_ci ret_list = [x[len(check_path) + 1:] 745f9996aaSopenharmony_ci for x in ret_list if x.startswith(check_path)] 755f9996aaSopenharmony_ci 765f9996aaSopenharmony_ci return tuple(ret_list) 775f9996aaSopenharmony_ci 785f9996aaSopenharmony_ci def add_option(self, parser): 795f9996aaSopenharmony_ci parser.add_argument( 805f9996aaSopenharmony_ci "-w", 815f9996aaSopenharmony_ci "--white_dir_on", 825f9996aaSopenharmony_ci dest="white_dir_settings", 835f9996aaSopenharmony_ci type=str, 845f9996aaSopenharmony_ci default="on", 855f9996aaSopenharmony_ci choices=["on", "off"], 865f9996aaSopenharmony_ci help="turn on white dir function or not", 875f9996aaSopenharmony_ci ) 885f9996aaSopenharmony_ci parser.add_argument( 895f9996aaSopenharmony_ci "-v", "--version", action="version", version=f"%(prog)s {self.version}." 905f9996aaSopenharmony_ci ) 915f9996aaSopenharmony_ci parser.add_argument( 925f9996aaSopenharmony_ci "-gd", 935f9996aaSopenharmony_ci "--generate_diff", 945f9996aaSopenharmony_ci metavar=("repo", "prNum"), 955f9996aaSopenharmony_ci dest="repo_pr", 965f9996aaSopenharmony_ci nargs=2, 975f9996aaSopenharmony_ci type=str, 985f9996aaSopenharmony_ci help="generate diff files.", 995f9996aaSopenharmony_ci ) 1005f9996aaSopenharmony_ci parser.add_argument( 1015f9996aaSopenharmony_ci "-cd", 1025f9996aaSopenharmony_ci "--check_diffs", 1035f9996aaSopenharmony_ci metavar="diffFilesPath", 1045f9996aaSopenharmony_ci dest="diff_files_path", 1055f9996aaSopenharmony_ci nargs=1, 1065f9996aaSopenharmony_ci type=str, 1075f9996aaSopenharmony_ci help="check all diff files as specific path.", 1085f9996aaSopenharmony_ci ) 1095f9996aaSopenharmony_ci parser.add_argument( 1105f9996aaSopenharmony_ci "-p", 1115f9996aaSopenharmony_ci metavar="path", 1125f9996aaSopenharmony_ci type=str, 1135f9996aaSopenharmony_ci dest="path", 1145f9996aaSopenharmony_ci help="check all files as specific path\ 1155f9996aaSopenharmony_ci (the current directory by default).", 1165f9996aaSopenharmony_ci ) 1175f9996aaSopenharmony_ci parser.add_argument( 1185f9996aaSopenharmony_ci "-o", 1195f9996aaSopenharmony_ci metavar="stdout/xls/json", 1205f9996aaSopenharmony_ci nargs=1, 1215f9996aaSopenharmony_ci dest="output_format", 1225f9996aaSopenharmony_ci default="stdout", 1235f9996aaSopenharmony_ci choices=["stdout", "xls", "json"], 1245f9996aaSopenharmony_ci type=str, 1255f9996aaSopenharmony_ci help="specific output format(stdout by default).", 1265f9996aaSopenharmony_ci ) 1275f9996aaSopenharmony_ci 1285f9996aaSopenharmony_ci def store_args(self, args): 1295f9996aaSopenharmony_ci if args.repo_pr is not None: 1305f9996aaSopenharmony_ci self.repo_url = args.repo_pr[0] 1315f9996aaSopenharmony_ci self.repo_num = args.repo_pr[1] 1325f9996aaSopenharmony_ci self.diff_files_path = args.diff_files_path 1335f9996aaSopenharmony_ci self.output_format = args.output_format 1345f9996aaSopenharmony_ci if (args.path): 1355f9996aaSopenharmony_ci self.check_path = os.path.normpath(args.path) 1365f9996aaSopenharmony_ci self.white_dir_settings = args.white_dir_settings 1375f9996aaSopenharmony_ci 1385f9996aaSopenharmony_ci def pre_check(self): 1395f9996aaSopenharmony_ci if self.white_dir_settings == 'on': 1405f9996aaSopenharmony_ci self.whitelist = self.handle_white_dir(self.check_path) 1415f9996aaSopenharmony_ci 1425f9996aaSopenharmony_ci def start_check(self): 1435f9996aaSopenharmony_ci print("---Start check---\n") 1445f9996aaSopenharmony_ci # check all gn 1455f9996aaSopenharmony_ci gn_errs = CheckGn(self.ohos_root, black_dir=self.whitelist, 1465f9996aaSopenharmony_ci check_path=self.check_path).output() 1475f9996aaSopenharmony_ci 1485f9996aaSopenharmony_ci # check all bundle.json 1495f9996aaSopenharmony_ci bundle_errs = BundlesCheck.to_df(self.check_path) 1505f9996aaSopenharmony_ci 1515f9996aaSopenharmony_ci if not os.path.exists("out"): 1525f9996aaSopenharmony_ci os.mkdir("out") 1535f9996aaSopenharmony_ci out_path = os.path.join(os.getcwd(), "out") 1545f9996aaSopenharmony_ci table = PrettyTable(gn_errs.columns.to_list()) 1555f9996aaSopenharmony_ci table.add_rows(gn_errs.values.tolist()) 1565f9996aaSopenharmony_ci table_str = table.get_string() 1575f9996aaSopenharmony_ci flags = os.O_WRONLY | os.O_CREAT 1585f9996aaSopenharmony_ci modes = stat.S_IWUSR | stat.S_IRUSR 1595f9996aaSopenharmony_ci with os.fdopen( 1605f9996aaSopenharmony_ci os.open(os.path.join(out_path, "gn_problems.txt"), flags, modes), "w" 1615f9996aaSopenharmony_ci ) as file: 1625f9996aaSopenharmony_ci file.write(table_str) 1635f9996aaSopenharmony_ci 1645f9996aaSopenharmony_ci # merge excel 1655f9996aaSopenharmony_ci output_path = os.path.join(out_path, "output_errors.xlsx") 1665f9996aaSopenharmony_ci with pd.ExcelWriter(output_path) as writer: 1675f9996aaSopenharmony_ci bundle_errs.to_excel(writer, sheet_name="bundle_check", index=None) 1685f9996aaSopenharmony_ci gn_errs.to_excel(writer, sheet_name="gn_check", index=None) 1695f9996aaSopenharmony_ci 1705f9996aaSopenharmony_ci print("\nStatic check finish.\nPlease check: " + output_path) 1715f9996aaSopenharmony_ci return 1725f9996aaSopenharmony_ci 1735f9996aaSopenharmony_ci def check_end(self): 1745f9996aaSopenharmony_ci print("\n---End check---") 1755f9996aaSopenharmony_ci return 1765f9996aaSopenharmony_ci 1775f9996aaSopenharmony_ci 1785f9996aaSopenharmony_cidef main(): 1795f9996aaSopenharmony_ci csctglb = CsctGlobal() 1805f9996aaSopenharmony_ci parser = argparse.ArgumentParser( 1815f9996aaSopenharmony_ci description=f"Component Static Check Tool version {csctglb.version}", 1825f9996aaSopenharmony_ci ) 1835f9996aaSopenharmony_ci csctglb.add_option(parser) 1845f9996aaSopenharmony_ci args = parser.parse_args() 1855f9996aaSopenharmony_ci csctglb.store_args(args) 1865f9996aaSopenharmony_ci csctglb.pre_check() 1875f9996aaSopenharmony_ci csctglb.start_check() 1885f9996aaSopenharmony_ci csctglb.check_end() 1895f9996aaSopenharmony_ci return 0 1905f9996aaSopenharmony_ci 1915f9996aaSopenharmony_ci 1925f9996aaSopenharmony_ciif __name__ == "__main__": 1935f9996aaSopenharmony_ci sys.exit(main()) 194