330 lines
11 KiB
Python
330 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
import os
|
|
import argparse
|
|
import sys
|
|
|
|
from enum import Enum
|
|
from resources.global_var import CURRENT_ARGS_DIR
|
|
from resources.global_var import CURRENT_BUILD_ARGS
|
|
from resources.global_var import DEFAULT_BUILD_ARGS
|
|
from resources.global_var import CURRENT_SET_ARGS
|
|
from resources.global_var import DEFAULT_SET_ARGS
|
|
from resources.global_var import CURRENT_CLEAN_ARGS
|
|
from resources.global_var import DEFAULT_CLEAN_ARGS
|
|
from resources.global_var import DEFAULT_ENV_ARGS
|
|
from resources.global_var import CURRENT_ENV_ARGS
|
|
from resources.global_var import DEFAULT_TOOL_ARGS
|
|
from resources.global_var import CURRENT_TOOL_ARGS
|
|
from resources.global_var import ARGS_DIR
|
|
from exceptions.ohos_exception import OHOSException
|
|
from util.log_util import LogUtil
|
|
from util.io_util import IoUtil
|
|
from util.type_check_util import TypeCheckUtil
|
|
from resolver.args_factory import ArgsFactory
|
|
from containers.status import throw_exception
|
|
|
|
|
|
class ModuleType(Enum):
|
|
|
|
BUILD = 0
|
|
SET = 1
|
|
ENV = 2
|
|
CLEAN = 3
|
|
TOOL = 4
|
|
|
|
|
|
class ArgType():
|
|
|
|
NONE = 0
|
|
BOOL = 1
|
|
INT = 2
|
|
STR = 3
|
|
LIST = 4
|
|
DICT = 5
|
|
SUBPARSERS = 6
|
|
|
|
@staticmethod
|
|
def get_type(value: str):
|
|
if value == 'bool':
|
|
return ArgType.BOOL
|
|
elif value == "int":
|
|
return ArgType.INT
|
|
elif value == 'str':
|
|
return ArgType.STR
|
|
elif value == "list":
|
|
return ArgType.LIST
|
|
elif value == 'dict':
|
|
return ArgType.DICT
|
|
elif value == 'subparsers':
|
|
return ArgType.SUBPARSERS
|
|
else:
|
|
return ArgType.NONE
|
|
|
|
|
|
class BuildPhase():
|
|
|
|
NONE = 0
|
|
PRE_BUILD = 1
|
|
PRE_LOAD = 2
|
|
LOAD = 3
|
|
PRE_TARGET_GENERATE = 4
|
|
TARGET_GENERATE = 5
|
|
POST_TARGET_GENERATE = 6
|
|
PRE_TARGET_COMPILATION = 7
|
|
TARGET_COMPILATION = 8
|
|
POST_TARGET_COMPILATION = 9
|
|
POST_BUILD = 10
|
|
|
|
@staticmethod
|
|
def get_type(value: str):
|
|
if value == 'prebuild':
|
|
return BuildPhase.PRE_BUILD
|
|
elif value == "preload":
|
|
return BuildPhase.PRE_LOAD
|
|
elif value == 'load':
|
|
return BuildPhase.LOAD
|
|
elif value == "preTargetGenerate":
|
|
return BuildPhase.PRE_TARGET_GENERATE
|
|
elif value == 'targetGenerate':
|
|
return BuildPhase.TARGET_GENERATE
|
|
elif value == 'postTargetGenerate':
|
|
return BuildPhase.POST_TARGET_GENERATE
|
|
elif value == 'preTargetCompilation':
|
|
return BuildPhase.PRE_TARGET_COMPILATION
|
|
elif value == 'targetCompilation':
|
|
return BuildPhase.TARGET_COMPILATION
|
|
elif value == 'postTargetCompilation':
|
|
return BuildPhase.POST_TARGET_COMPILATION
|
|
elif value == 'postbuild':
|
|
return BuildPhase.POST_BUILD
|
|
else:
|
|
return BuildPhase.NONE
|
|
|
|
|
|
class CleanPhase():
|
|
|
|
REGULAR = 0
|
|
DEEP = 1
|
|
NONE = 2
|
|
|
|
@staticmethod
|
|
def get_type(value: str):
|
|
if value == 'regular':
|
|
return CleanPhase.REGULAR
|
|
elif value == 'deep':
|
|
return CleanPhase.DEEP
|
|
else:
|
|
return CleanPhase.NONE
|
|
|
|
|
|
class Arg():
|
|
|
|
def __init__(self, name: str, helps: str, phase: str,
|
|
attribute: dict, argtype: ArgType, value,
|
|
resolve_function: str):
|
|
self._arg_name = name
|
|
self._arg_help = helps
|
|
self._arg_phase = phase
|
|
self._arg_attribute = attribute
|
|
self._arg_type = argtype
|
|
self._arg_value = value
|
|
self._resolve_function = resolve_function
|
|
|
|
@property
|
|
def arg_name(self):
|
|
return self._arg_name
|
|
|
|
@property
|
|
def arg_value(self):
|
|
return self._arg_value
|
|
|
|
@arg_value.setter
|
|
def arg_value(self, value):
|
|
self._arg_value = value
|
|
|
|
@property
|
|
def arg_help(self):
|
|
return self._arg_help
|
|
|
|
@property
|
|
def arg_attribute(self):
|
|
return self._arg_attribute
|
|
|
|
@property
|
|
def arg_phase(self):
|
|
return self._arg_phase
|
|
|
|
@property
|
|
def arg_type(self):
|
|
return self._arg_type
|
|
|
|
@property
|
|
def resolve_function(self):
|
|
return self._resolve_function
|
|
|
|
@resolve_function.setter
|
|
def resolve_function(self, value):
|
|
self._resolve_function = value
|
|
|
|
@staticmethod
|
|
@throw_exception
|
|
def create_instance_by_dict(data: dict):
|
|
arg_name = str(data['arg_name']).replace("-", "_")[2:]
|
|
arg_help = str(data['arg_help'])
|
|
arg_phase = BuildPhase.get_type(str(data['arg_phase']))
|
|
arg_attibute = dict(data['arg_attribute'])
|
|
arg_type = ArgType.get_type(data['arg_type'])
|
|
arg_value = ''
|
|
if arg_type == ArgType.BOOL:
|
|
arg_value = data['argDefault']
|
|
elif arg_type == ArgType.INT:
|
|
arg_value = int(data['argDefault'])
|
|
elif arg_type == ArgType.STR:
|
|
arg_value = data['argDefault']
|
|
elif arg_type == ArgType.LIST:
|
|
arg_value = list(data['argDefault'])
|
|
elif arg_type == ArgType.DICT:
|
|
arg_value = dict(data['argDefault'])
|
|
elif arg_type == ArgType.SUBPARSERS:
|
|
arg_value = list(data['argDefault'])
|
|
else:
|
|
raise OHOSException('Unknown arg type "{}" for arg "{}"'.format(
|
|
arg_type, arg_name), "0003")
|
|
resolve_function = data['resolve_function']
|
|
return Arg(arg_name, arg_help, arg_phase, arg_attibute, arg_type, arg_value, resolve_function)
|
|
|
|
@staticmethod
|
|
def get_help(module_type: ModuleType) -> str:
|
|
parser = argparse.ArgumentParser()
|
|
all_args = Arg.read_args_file(module_type)
|
|
|
|
for arg in all_args.values():
|
|
arg = dict(arg)
|
|
ArgsFactory.genetic_add_option(parser, arg)
|
|
|
|
parser.usage = 'hb {} [option]'.format(module_type.name.lower())
|
|
parser.parse_known_args(sys.argv[2:])
|
|
|
|
return parser.format_help()
|
|
|
|
@staticmethod
|
|
def parse_all_args(module_type: ModuleType) -> dict:
|
|
args_dict = {}
|
|
parser = argparse.ArgumentParser()
|
|
all_args = Arg.read_args_file(module_type)
|
|
|
|
for arg in all_args.values():
|
|
arg = dict(arg)
|
|
ArgsFactory.genetic_add_option(parser, arg)
|
|
oh_arg = Arg.create_instance_by_dict(arg)
|
|
args_dict[oh_arg.arg_name] = oh_arg
|
|
|
|
parser.usage = 'hb {} [option]'.format(module_type.name.lower())
|
|
parser_args = parser.parse_known_args(sys.argv[2:])
|
|
|
|
for oh_arg in args_dict.values():
|
|
if isinstance(oh_arg, Arg):
|
|
assigned_value = parser_args[0].__dict__[oh_arg.arg_name]
|
|
if oh_arg.arg_type == ArgType.LIST:
|
|
convert_assigned_value = TypeCheckUtil.tile_list(assigned_value)
|
|
convert_assigned_value = list(set(convert_assigned_value))
|
|
elif oh_arg.arg_type == ArgType.SUBPARSERS:
|
|
convert_assigned_value = TypeCheckUtil.tile_list(assigned_value)
|
|
if len(convert_assigned_value):
|
|
convert_assigned_value = list(set(convert_assigned_value))
|
|
convert_assigned_value.extend(parser_args[1])
|
|
convert_assigned_value.sort(key=sys.argv[2:].index)
|
|
elif oh_arg.arg_type == ArgType.BOOL:
|
|
if str(assigned_value).lower() == 'false':
|
|
convert_assigned_value = False
|
|
elif str(assigned_value).lower() == 'true' or assigned_value is None:
|
|
convert_assigned_value = True
|
|
else:
|
|
convert_assigned_value = assigned_value
|
|
|
|
if oh_arg.arg_attribute.get('deprecated', None) and oh_arg.arg_value != convert_assigned_value:
|
|
LogUtil.hb_warning(
|
|
'compile option "{}" will be deprecated, \
|
|
please consider use other options'.format(oh_arg.arg_name))
|
|
oh_arg.arg_value = convert_assigned_value
|
|
Arg.write_args_file(
|
|
oh_arg.arg_name, oh_arg.arg_value, module_type)
|
|
|
|
return args_dict
|
|
|
|
@staticmethod
|
|
@throw_exception
|
|
def write_args_file(key: str, value, module_type: ModuleType):
|
|
args_file_path = ''
|
|
if module_type == ModuleType.BUILD:
|
|
args_file_path = CURRENT_BUILD_ARGS
|
|
elif module_type == ModuleType.SET:
|
|
args_file_path = CURRENT_SET_ARGS
|
|
elif module_type == ModuleType.CLEAN:
|
|
args_file_path = CURRENT_CLEAN_ARGS
|
|
elif module_type == ModuleType.ENV:
|
|
args_file_path = CURRENT_ENV_ARGS
|
|
elif module_type == ModuleType.TOOL:
|
|
args_file_path = CURRENT_TOOL_ARGS
|
|
else:
|
|
raise OHOSException(
|
|
'You are trying to write args file, but there is no corresponding module "{}" args file'
|
|
.format(module_type), "0002")
|
|
args_file = Arg.read_args_file(module_type)
|
|
args_file[key]["argDefault"] = value
|
|
IoUtil.dump_json_file(args_file_path, args_file)
|
|
|
|
@staticmethod
|
|
@throw_exception
|
|
def read_args_file(module_type: ModuleType):
|
|
args_file_path = ''
|
|
default_file_path = ''
|
|
if module_type == ModuleType.BUILD:
|
|
args_file_path = CURRENT_BUILD_ARGS
|
|
default_file_path = DEFAULT_BUILD_ARGS
|
|
elif module_type == ModuleType.SET:
|
|
args_file_path = CURRENT_SET_ARGS
|
|
default_file_path = DEFAULT_SET_ARGS
|
|
elif module_type == ModuleType.CLEAN:
|
|
args_file_path = CURRENT_CLEAN_ARGS
|
|
default_file_path = DEFAULT_CLEAN_ARGS
|
|
elif module_type == ModuleType.ENV:
|
|
args_file_path = CURRENT_ENV_ARGS
|
|
default_file_path = DEFAULT_ENV_ARGS
|
|
elif module_type == ModuleType.TOOL:
|
|
args_file_path = CURRENT_TOOL_ARGS
|
|
default_file_path = DEFAULT_TOOL_ARGS
|
|
else:
|
|
raise OHOSException(
|
|
'You are trying to read args file, but there is no corresponding module "{}" args file'
|
|
.format(module_type.name.lower()), "0018")
|
|
if not os.path.exists(CURRENT_ARGS_DIR):
|
|
os.makedirs(CURRENT_ARGS_DIR, exist_ok=True)
|
|
if not os.path.exists(args_file_path):
|
|
IoUtil.copy_file(src=default_file_path, dst=args_file_path)
|
|
return IoUtil.read_json_file(args_file_path)
|
|
|
|
@staticmethod
|
|
def clean_args_file():
|
|
if os.path.exists(CURRENT_ARGS_DIR):
|
|
for file in os.listdir(CURRENT_ARGS_DIR):
|
|
if file.endswith('.json') and os.path.exists(os.path.join(CURRENT_ARGS_DIR, file)):
|
|
os.remove(os.path.join(CURRENT_ARGS_DIR, file))
|