• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4#
5# Copyright (c) 2023 Huawei Device Co., Ltd.
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import os
20import argparse
21import sys
22
23from enum import Enum
24from resources.global_var import CURRENT_ARGS_DIR
25from resources.global_var import CURRENT_BUILD_ARGS
26from resources.global_var import DEFAULT_BUILD_ARGS
27from resources.global_var import CURRENT_SET_ARGS
28from resources.global_var import DEFAULT_SET_ARGS
29from resources.global_var import CURRENT_CLEAN_ARGS
30from resources.global_var import DEFAULT_CLEAN_ARGS
31from resources.global_var import DEFAULT_ENV_ARGS
32from resources.global_var import CURRENT_ENV_ARGS
33from resources.global_var import DEFAULT_TOOL_ARGS
34from resources.global_var import CURRENT_TOOL_ARGS
35from resources.global_var import ARGS_DIR
36from exceptions.ohos_exception import OHOSException
37from util.log_util import LogUtil
38from util.io_util import IoUtil
39from util.type_check_util import TypeCheckUtil
40from resolver.args_factory import ArgsFactory
41from containers.status import throw_exception
42
43
44class ModuleType(Enum):
45
46    BUILD = 0
47    SET = 1
48    ENV = 2
49    CLEAN = 3
50    TOOL = 4
51
52
53class ArgType():
54
55    NONE = 0
56    BOOL = 1
57    INT = 2
58    STR = 3
59    LIST = 4
60    DICT = 5
61    SUBPARSERS = 6
62
63    @staticmethod
64    def get_type(value: str):
65        if value == 'bool':
66            return ArgType.BOOL
67        elif value == "int":
68            return ArgType.INT
69        elif value == 'str':
70            return ArgType.STR
71        elif value == "list":
72            return ArgType.LIST
73        elif value == 'dict':
74            return ArgType.DICT
75        elif value == 'subparsers':
76            return ArgType.SUBPARSERS
77        else:
78            return ArgType.NONE
79
80
81class BuildPhase():
82
83    NONE = 0
84    PRE_BUILD = 1
85    PRE_LOAD = 2
86    LOAD = 3
87    PRE_TARGET_GENERATE = 4
88    TARGET_GENERATE = 5
89    POST_TARGET_GENERATE = 6
90    PRE_TARGET_COMPILATION = 7
91    TARGET_COMPILATION = 8
92    POST_TARGET_COMPILATION = 9
93    POST_BUILD = 10
94
95    @staticmethod
96    def get_type(value: str):
97        if value == 'prebuild':
98            return BuildPhase.PRE_BUILD
99        elif value == "preload":
100            return BuildPhase.PRE_LOAD
101        elif value == 'load':
102            return BuildPhase.LOAD
103        elif value == "preTargetGenerate":
104            return BuildPhase.PRE_TARGET_GENERATE
105        elif value == 'targetGenerate':
106            return BuildPhase.TARGET_GENERATE
107        elif value == 'postTargetGenerate':
108            return BuildPhase.POST_TARGET_GENERATE
109        elif value == 'preTargetCompilation':
110            return BuildPhase.PRE_TARGET_COMPILATION
111        elif value == 'targetCompilation':
112            return BuildPhase.TARGET_COMPILATION
113        elif value == 'postTargetCompilation':
114            return BuildPhase.POST_TARGET_COMPILATION
115        elif value == 'postbuild':
116            return BuildPhase.POST_BUILD
117        else:
118            return BuildPhase.NONE
119
120
121class CleanPhase():
122
123    REGULAR = 0
124    DEEP = 1
125    NONE = 2
126
127    @staticmethod
128    def get_type(value: str):
129        if value == 'regular':
130            return CleanPhase.REGULAR
131        elif value == 'deep':
132            return CleanPhase.DEEP
133        else:
134            return CleanPhase.NONE
135
136
137class Arg():
138
139    def __init__(self, name: str, helps: str, phase: str,
140                 attribute: dict, argtype: ArgType, value,
141                 resolve_function: str):
142        self._arg_name = name
143        self._arg_help = helps
144        self._arg_phase = phase
145        self._arg_attribute = attribute
146        self._arg_type = argtype
147        self._arg_value = value
148        self._resolve_function = resolve_function
149
150    @property
151    def arg_name(self):
152        return self._arg_name
153
154    @property
155    def arg_value(self):
156        return self._arg_value
157
158    @arg_value.setter
159    def arg_value(self, value):
160        self._arg_value = value
161
162    @property
163    def arg_help(self):
164        return self._arg_help
165
166    @property
167    def arg_attribute(self):
168        return self._arg_attribute
169
170    @property
171    def arg_phase(self):
172        return self._arg_phase
173
174    @property
175    def arg_type(self):
176        return self._arg_type
177
178    @property
179    def resolve_function(self):
180        return self._resolve_function
181
182    @resolve_function.setter
183    def resolve_function(self, value):
184        self._resolve_function = value
185
186    @staticmethod
187    @throw_exception
188    def create_instance_by_dict(data: dict):
189        arg_name = str(data['arg_name']).replace("-", "_")[2:]
190        arg_help = str(data['arg_help'])
191        arg_phase = BuildPhase.get_type(str(data['arg_phase']))
192        arg_attibute = dict(data['arg_attribute'])
193        arg_type = ArgType.get_type(data['arg_type'])
194        arg_value = ''
195        if arg_type == ArgType.BOOL:
196            arg_value = data['argDefault']
197        elif arg_type == ArgType.INT:
198            arg_value = int(data['argDefault'])
199        elif arg_type == ArgType.STR:
200            arg_value = data['argDefault']
201        elif arg_type == ArgType.LIST:
202            arg_value = list(data['argDefault'])
203        elif arg_type == ArgType.DICT:
204            arg_value = dict(data['argDefault'])
205        elif arg_type == ArgType.SUBPARSERS:
206            arg_value = list(data['argDefault'])
207        else:
208            raise OHOSException('Unknown arg type "{}" for arg "{}"'.format(
209                arg_type, arg_name), "0003")
210        resolve_function = data['resolve_function']
211        return Arg(arg_name, arg_help, arg_phase, arg_attibute, arg_type, arg_value, resolve_function)
212
213    @staticmethod
214    def get_help(module_type: ModuleType) -> str:
215        parser = argparse.ArgumentParser()
216        all_args = Arg.read_args_file(module_type)
217
218        for arg in all_args.values():
219            arg = dict(arg)
220            ArgsFactory.genetic_add_option(parser, arg)
221
222        parser.usage = 'hb {} [option]'.format(module_type.name.lower())
223        parser.parse_known_args(sys.argv[2:])
224
225        return parser.format_help()
226
227    @staticmethod
228    def parse_all_args(module_type: ModuleType) -> dict:
229        args_dict = {}
230        parser = argparse.ArgumentParser()
231        all_args = Arg.read_args_file(module_type)
232
233        for arg in all_args.values():
234            arg = dict(arg)
235            ArgsFactory.genetic_add_option(parser, arg)
236            oh_arg = Arg.create_instance_by_dict(arg)
237            args_dict[oh_arg.arg_name] = oh_arg
238
239        parser.usage = 'hb {} [option]'.format(module_type.name.lower())
240        parser_args = parser.parse_known_args(sys.argv[2:])
241
242        for oh_arg in args_dict.values():
243            if isinstance(oh_arg, Arg):
244                assigned_value = parser_args[0].__dict__[oh_arg.arg_name]
245                if oh_arg.arg_type == ArgType.LIST:
246                    convert_assigned_value = TypeCheckUtil.tile_list(assigned_value)
247                    convert_assigned_value = list(set(convert_assigned_value))
248                elif oh_arg.arg_type == ArgType.SUBPARSERS:
249                    convert_assigned_value = TypeCheckUtil.tile_list(assigned_value)
250                    if len(convert_assigned_value):
251                        convert_assigned_value = list(set(convert_assigned_value))
252                        convert_assigned_value.extend(parser_args[1])
253                        convert_assigned_value.sort(key=sys.argv[2:].index)
254                elif oh_arg.arg_type == ArgType.BOOL:
255                    if str(assigned_value).lower() == 'false':
256                        convert_assigned_value = False
257                    elif str(assigned_value).lower() == 'true' or assigned_value is None:
258                        convert_assigned_value = True
259                else:
260                    convert_assigned_value = assigned_value
261
262                if oh_arg.arg_attribute.get('deprecated', None) and oh_arg.arg_value != convert_assigned_value:
263                    LogUtil.hb_warning(
264                        'compile option "{}" will be deprecated, \
265                            please consider use other options'.format(oh_arg.arg_name))
266                oh_arg.arg_value = convert_assigned_value
267                Arg.write_args_file(
268                    oh_arg.arg_name, oh_arg.arg_value, module_type)
269
270        return args_dict
271
272    @staticmethod
273    @throw_exception
274    def write_args_file(key: str, value, module_type: ModuleType):
275        args_file_path = ''
276        if module_type == ModuleType.BUILD:
277            args_file_path = CURRENT_BUILD_ARGS
278        elif module_type == ModuleType.SET:
279            args_file_path = CURRENT_SET_ARGS
280        elif module_type == ModuleType.CLEAN:
281            args_file_path = CURRENT_CLEAN_ARGS
282        elif module_type == ModuleType.ENV:
283            args_file_path = CURRENT_ENV_ARGS
284        elif module_type == ModuleType.TOOL:
285            args_file_path = CURRENT_TOOL_ARGS
286        else:
287            raise OHOSException(
288                'You are trying to write args file, but there is no corresponding module "{}" args file'
289                .format(module_type), "0002")
290        args_file = Arg.read_args_file(module_type)
291        args_file[key]["argDefault"] = value
292        IoUtil.dump_json_file(args_file_path, args_file)
293
294    @staticmethod
295    @throw_exception
296    def read_args_file(module_type: ModuleType):
297        args_file_path = ''
298        default_file_path = ''
299        if module_type == ModuleType.BUILD:
300            args_file_path = CURRENT_BUILD_ARGS
301            default_file_path = DEFAULT_BUILD_ARGS
302        elif module_type == ModuleType.SET:
303            args_file_path = CURRENT_SET_ARGS
304            default_file_path = DEFAULT_SET_ARGS
305        elif module_type == ModuleType.CLEAN:
306            args_file_path = CURRENT_CLEAN_ARGS
307            default_file_path = DEFAULT_CLEAN_ARGS
308        elif module_type == ModuleType.ENV:
309            args_file_path = CURRENT_ENV_ARGS
310            default_file_path = DEFAULT_ENV_ARGS
311        elif module_type == ModuleType.TOOL:
312            args_file_path = CURRENT_TOOL_ARGS
313            default_file_path = DEFAULT_TOOL_ARGS
314        else:
315            raise OHOSException(
316                'You are trying to read args file, but there is no corresponding module "{}" args file'
317                .format(module_type.name.lower()), "0018")
318        if not os.path.exists(CURRENT_ARGS_DIR):
319            os.makedirs(CURRENT_ARGS_DIR, exist_ok=True)
320        if not os.path.exists(args_file_path):
321            IoUtil.copy_file(src=default_file_path, dst=args_file_path)
322        return IoUtil.read_json_file(args_file_path)
323
324    @staticmethod
325    def clean_args_file():
326        if os.path.exists(CURRENT_ARGS_DIR):
327            for file in os.listdir(CURRENT_ARGS_DIR):
328                if file.endswith('.json') and os.path.exists(os.path.join(CURRENT_ARGS_DIR, file)):
329                    os.remove(os.path.join(CURRENT_ARGS_DIR, file))
330