• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 # Copyright (c) 2023 Huawei Device Co., Ltd.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 
17 """
18 The tool for making hmp.
19 
20 positional arguments:
21   -pn PACKAGE_NAME, --package_name PACKAGE_NAME
22                         Module package name.
23   -op OUT_PACKAGE, --out_package OUT_PACKAGE
24                         Out package file path.
25   -pi PACK_INFO, --pack_info PACK_INFO
26                         Pack info file path.
27   -mf MODULE_FILES, --module_files MODULE_FILES
28                         Module files path.
29 """
30 import os
31 import sys
32 import argparse
33 import zipfile
34 import io
35 import logging
36 
37 
38 # 1000000: max number of function recursion depth
39 MAXIMUM_RECURSION_DEPTH = 1000000
40 sys.setrecursionlimit(MAXIMUM_RECURSION_DEPTH)
41 
42 
43 def package_name_check(arg):
44     """
45     Argument check, which is used to check whether the specified arg is none.
46     :param arg: the arg to check
47     :return:  Check result, which is False if the arg is invalid.
48     """
49     if arg is None:
50         UPDATE_LOGGER.print_log(
51             "Package name error: %s" % arg, UPDATE_LOGGER.ERROR_LOG)
52         return False
53     return arg
54 
55 
56 def check_out_package(arg):
57     """
58     Argument check, which is used to check whether
59     the update package path exists.
60     :param arg: The arg to check.
61     :return: Check result
62     """
63     make_dir_path = None
64     if os.path.exists(arg):
65         if os.path.isfile(arg):
66             UPDATE_LOGGER.print_log(
67                 "Out package must be a dir path, not a file path. "
68                 "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG)
69             return False
70     else:
71         try:
72             UPDATE_LOGGER.print_log(
73                 "Out package path does not exist. The dir will be created!"
74                 "path: %s" % arg, UPDATE_LOGGER.WARNING_LOG)
75             os.makedirs(arg)
76             make_dir_path = arg
77         except OSError:
78             UPDATE_LOGGER.print_log(
79                 "Make out package path dir failed! "
80                 "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG)
81             return False
82     return arg
83 
84 
85 def pack_info_check(arg):
86     """
87     Argument check, which is used to check whether
88     the specified arg is a pack info.
89     :param arg: the arg to check
90     :return: Check result, which is False if the arg is invalid.
91     """
92     if not os.path.isfile(arg):
93         UPDATE_LOGGER.print_log(
94             "FileNotFoundError, path: %s" % arg, UPDATE_LOGGER.ERROR_LOG)
95         return False
96     return arg
97 
98 
99 class UpdateToolLogger:
100     """
101     Global log class
102     """
103     INFO_LOG = 'INFO_LOG'
104     WARNING_LOG = 'WARNING_LOG'
105     ERROR_LOG = 'ERROR_LOG'
106     LOG_TYPE = (INFO_LOG, WARNING_LOG, ERROR_LOG)
107 
108     def __init__(self, output_type='console'):
109         self.__logger_obj = self.__get_logger_obj(output_type=output_type)
110 
111     @staticmethod
112     def __get_logger_obj(output_type='console'):
113         ota_logger = logging.getLogger(__name__)
114         ota_logger.setLevel(level=logging.INFO)
115         formatter = logging.Formatter(
116             '%(asctime)s %(levelname)s : %(message)s',
117             "%Y-%m-%d %H:%M:%S")
118         if output_type == 'console':
119             console_handler = logging.StreamHandler()
120             console_handler.setLevel(logging.INFO)
121             console_handler.setFormatter(formatter)
122             ota_logger.addHandler(console_handler)
123         elif output_type == 'file':
124             file_handler = logging.FileHandler("UpdateToolLog.txt")
125             file_handler.setLevel(logging.INFO)
126             file_handler.setFormatter(formatter)
127             ota_logger.addHandler(file_handler)
128         return ota_logger
129 
130     def print_log(self, msg, log_type=INFO_LOG):
131         """
132         Print log information.
133         :param msg: log information
134         :param log_type: log type
135         :return:
136         """
137         if log_type == self.LOG_TYPE[0]:
138             self.__logger_obj.info(msg)
139         elif log_type == self.LOG_TYPE[1]:
140             self.__logger_obj.warning(msg)
141         elif log_type == self.LOG_TYPE[2]:
142             self.__logger_obj.error(msg)
143         else:
144             self.__logger_obj.error("Unknown log type! %s", log_type)
145             return False
146         return True
147 
148     def print_uncaught_exception_msg(self, msg, exc_info):
149         """
150         Print log when an uncaught exception occurs.
151         :param msg: Uncaught exception
152         :param exc_info: information about the uncaught exception
153         """
154         self.__logger_obj.error(msg, exc_info=exc_info)
155 
156 
157 UPDATE_LOGGER = UpdateToolLogger()
158 
159 
160 def build_hmp(package_name, out_package, pack_info, module_files):
161     out_package_path = os.path.join(
162         out_package, '%s.zip' % package_name)
163     zip_file = zipfile.ZipFile(out_package_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
164     for module_file in module_files:
165         zip_file.write(module_file, os.path.basename(module_file))
166     zip_file.write(pack_info, os.path.basename(pack_info))
167     zip_file.close()
168     return True
169 
170 
171 def main(argv):
172     """
173     Entry function.
174     """
175     parser = argparse.ArgumentParser()
176 
177     parser.add_argument("-pn", "--package_name", type=package_name_check,
178                         default=None, help="Module package name.")
179     parser.add_argument("-op", "--out_package", type=check_out_package,
180                         default=None, help="Out package file path.")
181     parser.add_argument("-pi", "--pack_info", type=pack_info_check,
182                         default=None, help="Pack info file path.")
183     parser.add_argument("-mf", "--module_files", nargs='+',
184                         default=None, help="Module files path.")
185 
186     args = parser.parse_args(argv)
187 
188     # Generate the hmp.
189     build_re = build_hmp(args.package_name, args.out_package, args.pack_info, args.module_files)
190 
191 if __name__ == '__main__':
192     main(sys.argv[1:])
193