140681896Sopenharmony_ci#!/usr/bin/env python3 240681896Sopenharmony_ci# -*- coding: utf-8 -*- 340681896Sopenharmony_ci 440681896Sopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 540681896Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 640681896Sopenharmony_ci# you may not use this file except in compliance with the License. 740681896Sopenharmony_ci# You may obtain a copy of the License at 840681896Sopenharmony_ci# 940681896Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 1040681896Sopenharmony_ci# 1140681896Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1240681896Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1340681896Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1440681896Sopenharmony_ci# See the License for the specific language governing permissions and 1540681896Sopenharmony_ci# limitations under the License. 1640681896Sopenharmony_ci 1740681896Sopenharmony_ci""" 1840681896Sopenharmony_ciThe tool for making hmp. 1940681896Sopenharmony_ci 2040681896Sopenharmony_cipositional arguments: 2140681896Sopenharmony_ci -pn PACKAGE_NAME, --package_name PACKAGE_NAME 2240681896Sopenharmony_ci Module package name. 2340681896Sopenharmony_ci -op OUT_PACKAGE, --out_package OUT_PACKAGE 2440681896Sopenharmony_ci Out package file path. 2540681896Sopenharmony_ci -pi PACK_INFO, --pack_info PACK_INFO 2640681896Sopenharmony_ci Pack info file path. 2740681896Sopenharmony_ci -mf MODULE_FILES, --module_files MODULE_FILES 2840681896Sopenharmony_ci Module files path. 2940681896Sopenharmony_ci""" 3040681896Sopenharmony_ciimport os 3140681896Sopenharmony_ciimport sys 3240681896Sopenharmony_ciimport argparse 3340681896Sopenharmony_ciimport zipfile 3440681896Sopenharmony_ciimport io 3540681896Sopenharmony_ciimport logging 3640681896Sopenharmony_ci 3740681896Sopenharmony_ci 3840681896Sopenharmony_ci# 1000000: max number of function recursion depth 3940681896Sopenharmony_ciMAXIMUM_RECURSION_DEPTH = 1000000 4040681896Sopenharmony_cisys.setrecursionlimit(MAXIMUM_RECURSION_DEPTH) 4140681896Sopenharmony_ci 4240681896Sopenharmony_ci 4340681896Sopenharmony_cidef package_name_check(arg): 4440681896Sopenharmony_ci """ 4540681896Sopenharmony_ci Argument check, which is used to check whether the specified arg is none. 4640681896Sopenharmony_ci :param arg: the arg to check 4740681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 4840681896Sopenharmony_ci """ 4940681896Sopenharmony_ci if arg is None: 5040681896Sopenharmony_ci UPDATE_LOGGER.print_log( 5140681896Sopenharmony_ci "Package name error: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 5240681896Sopenharmony_ci return False 5340681896Sopenharmony_ci return arg 5440681896Sopenharmony_ci 5540681896Sopenharmony_ci 5640681896Sopenharmony_cidef check_out_package(arg): 5740681896Sopenharmony_ci """ 5840681896Sopenharmony_ci Argument check, which is used to check whether 5940681896Sopenharmony_ci the update package path exists. 6040681896Sopenharmony_ci :param arg: The arg to check. 6140681896Sopenharmony_ci :return: Check result 6240681896Sopenharmony_ci """ 6340681896Sopenharmony_ci make_dir_path = None 6440681896Sopenharmony_ci if os.path.exists(arg): 6540681896Sopenharmony_ci if os.path.isfile(arg): 6640681896Sopenharmony_ci UPDATE_LOGGER.print_log( 6740681896Sopenharmony_ci "Out package must be a dir path, not a file path. " 6840681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 6940681896Sopenharmony_ci return False 7040681896Sopenharmony_ci else: 7140681896Sopenharmony_ci try: 7240681896Sopenharmony_ci UPDATE_LOGGER.print_log( 7340681896Sopenharmony_ci "Out package path does not exist. The dir will be created!" 7440681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.WARNING_LOG) 7540681896Sopenharmony_ci os.makedirs(arg) 7640681896Sopenharmony_ci make_dir_path = arg 7740681896Sopenharmony_ci except OSError: 7840681896Sopenharmony_ci UPDATE_LOGGER.print_log( 7940681896Sopenharmony_ci "Make out package path dir failed! " 8040681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 8140681896Sopenharmony_ci return False 8240681896Sopenharmony_ci return arg 8340681896Sopenharmony_ci 8440681896Sopenharmony_ci 8540681896Sopenharmony_cidef pack_info_check(arg): 8640681896Sopenharmony_ci """ 8740681896Sopenharmony_ci Argument check, which is used to check whether 8840681896Sopenharmony_ci the specified arg is a pack info. 8940681896Sopenharmony_ci :param arg: the arg to check 9040681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 9140681896Sopenharmony_ci """ 9240681896Sopenharmony_ci if not os.path.isfile(arg): 9340681896Sopenharmony_ci UPDATE_LOGGER.print_log( 9440681896Sopenharmony_ci "FileNotFoundError, path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 9540681896Sopenharmony_ci return False 9640681896Sopenharmony_ci return arg 9740681896Sopenharmony_ci 9840681896Sopenharmony_ci 9940681896Sopenharmony_ciclass UpdateToolLogger: 10040681896Sopenharmony_ci """ 10140681896Sopenharmony_ci Global log class 10240681896Sopenharmony_ci """ 10340681896Sopenharmony_ci INFO_LOG = 'INFO_LOG' 10440681896Sopenharmony_ci WARNING_LOG = 'WARNING_LOG' 10540681896Sopenharmony_ci ERROR_LOG = 'ERROR_LOG' 10640681896Sopenharmony_ci LOG_TYPE = (INFO_LOG, WARNING_LOG, ERROR_LOG) 10740681896Sopenharmony_ci 10840681896Sopenharmony_ci def __init__(self, output_type='console'): 10940681896Sopenharmony_ci self.__logger_obj = self.__get_logger_obj(output_type=output_type) 11040681896Sopenharmony_ci 11140681896Sopenharmony_ci @staticmethod 11240681896Sopenharmony_ci def __get_logger_obj(output_type='console'): 11340681896Sopenharmony_ci ota_logger = logging.getLogger(__name__) 11440681896Sopenharmony_ci ota_logger.setLevel(level=logging.INFO) 11540681896Sopenharmony_ci formatter = logging.Formatter( 11640681896Sopenharmony_ci '%(asctime)s %(levelname)s : %(message)s', 11740681896Sopenharmony_ci "%Y-%m-%d %H:%M:%S") 11840681896Sopenharmony_ci if output_type == 'console': 11940681896Sopenharmony_ci console_handler = logging.StreamHandler() 12040681896Sopenharmony_ci console_handler.setLevel(logging.INFO) 12140681896Sopenharmony_ci console_handler.setFormatter(formatter) 12240681896Sopenharmony_ci ota_logger.addHandler(console_handler) 12340681896Sopenharmony_ci elif output_type == 'file': 12440681896Sopenharmony_ci file_handler = logging.FileHandler("UpdateToolLog.txt") 12540681896Sopenharmony_ci file_handler.setLevel(logging.INFO) 12640681896Sopenharmony_ci file_handler.setFormatter(formatter) 12740681896Sopenharmony_ci ota_logger.addHandler(file_handler) 12840681896Sopenharmony_ci return ota_logger 12940681896Sopenharmony_ci 13040681896Sopenharmony_ci def print_log(self, msg, log_type=INFO_LOG): 13140681896Sopenharmony_ci """ 13240681896Sopenharmony_ci Print log information. 13340681896Sopenharmony_ci :param msg: log information 13440681896Sopenharmony_ci :param log_type: log type 13540681896Sopenharmony_ci :return: 13640681896Sopenharmony_ci """ 13740681896Sopenharmony_ci if log_type == self.LOG_TYPE[0]: 13840681896Sopenharmony_ci self.__logger_obj.info(msg) 13940681896Sopenharmony_ci elif log_type == self.LOG_TYPE[1]: 14040681896Sopenharmony_ci self.__logger_obj.warning(msg) 14140681896Sopenharmony_ci elif log_type == self.LOG_TYPE[2]: 14240681896Sopenharmony_ci self.__logger_obj.error(msg) 14340681896Sopenharmony_ci else: 14440681896Sopenharmony_ci self.__logger_obj.error("Unknown log type! %s", log_type) 14540681896Sopenharmony_ci return False 14640681896Sopenharmony_ci return True 14740681896Sopenharmony_ci 14840681896Sopenharmony_ci def print_uncaught_exception_msg(self, msg, exc_info): 14940681896Sopenharmony_ci """ 15040681896Sopenharmony_ci Print log when an uncaught exception occurs. 15140681896Sopenharmony_ci :param msg: Uncaught exception 15240681896Sopenharmony_ci :param exc_info: information about the uncaught exception 15340681896Sopenharmony_ci """ 15440681896Sopenharmony_ci self.__logger_obj.error(msg, exc_info=exc_info) 15540681896Sopenharmony_ci 15640681896Sopenharmony_ci 15740681896Sopenharmony_ciUPDATE_LOGGER = UpdateToolLogger() 15840681896Sopenharmony_ci 15940681896Sopenharmony_ci 16040681896Sopenharmony_cidef build_hmp(package_name, out_package, pack_info, module_files): 16140681896Sopenharmony_ci out_package_path = os.path.join( 16240681896Sopenharmony_ci out_package, '%s.zip' % package_name) 16340681896Sopenharmony_ci zip_file = zipfile.ZipFile(out_package_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True) 16440681896Sopenharmony_ci for module_file in module_files: 16540681896Sopenharmony_ci zip_file.write(module_file, os.path.basename(module_file)) 16640681896Sopenharmony_ci zip_file.write(pack_info, os.path.basename(pack_info)) 16740681896Sopenharmony_ci zip_file.close() 16840681896Sopenharmony_ci return True 16940681896Sopenharmony_ci 17040681896Sopenharmony_ci 17140681896Sopenharmony_cidef main(argv): 17240681896Sopenharmony_ci """ 17340681896Sopenharmony_ci Entry function. 17440681896Sopenharmony_ci """ 17540681896Sopenharmony_ci parser = argparse.ArgumentParser() 17640681896Sopenharmony_ci 17740681896Sopenharmony_ci parser.add_argument("-pn", "--package_name", type=package_name_check, 17840681896Sopenharmony_ci default=None, help="Module package name.") 17940681896Sopenharmony_ci parser.add_argument("-op", "--out_package", type=check_out_package, 18040681896Sopenharmony_ci default=None, help="Out package file path.") 18140681896Sopenharmony_ci parser.add_argument("-pi", "--pack_info", type=pack_info_check, 18240681896Sopenharmony_ci default=None, help="Pack info file path.") 18340681896Sopenharmony_ci parser.add_argument("-mf", "--module_files", nargs='+', 18440681896Sopenharmony_ci default=None, help="Module files path.") 18540681896Sopenharmony_ci 18640681896Sopenharmony_ci args = parser.parse_args(argv) 18740681896Sopenharmony_ci 18840681896Sopenharmony_ci # Generate the hmp. 18940681896Sopenharmony_ci build_re = build_hmp(args.package_name, args.out_package, args.pack_info, args.module_files) 19040681896Sopenharmony_ci 19140681896Sopenharmony_ciif __name__ == '__main__': 19240681896Sopenharmony_ci main(sys.argv[1:]) 193