241 lines
11 KiB
Python
241 lines
11 KiB
Python
|
import argparse
|
|||
|
import sys, os
|
|||
|
from typing import List
|
|||
|
import textwrap
|
|||
|
import argparse
|
|||
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|||
|
import core.logger as logger
|
|||
|
from utils.utils import get_alkaid_root
|
|||
|
log = logger.get_logger()
|
|||
|
from database.base import BaseConfig, AutoInstanceDecorator
|
|||
|
|
|||
|
class ConfigureStyleHelpFormatter(argparse.HelpFormatter):
|
|||
|
"""自定义的帮助信息格式化类,用于美化 argparse 的帮助输出
|
|||
|
|
|||
|
特点:
|
|||
|
1. 带有彩色标记的输出样式
|
|||
|
2. 优化了选项和描述的对齐
|
|||
|
"""
|
|||
|
|
|||
|
# 颜色代码定义
|
|||
|
BLUE = "\033[1;34m" # 蓝色,用于位置参数
|
|||
|
GREEN = "\033[1;32m" # 绿色,用于普通选项
|
|||
|
YELLOW = "\033[1;33m" # 黄色,用于必选参数
|
|||
|
RESET = "\033[0m" # 重置颜色
|
|||
|
|
|||
|
def __init__(self, prog, indent_increment=2, max_help_position=8, width=None):
|
|||
|
# 根据终端宽度自动调整
|
|||
|
try:
|
|||
|
width = width or min(120, os.get_terminal_size().columns)
|
|||
|
except OSError:
|
|||
|
width = width or 120 # 使用默认宽度
|
|||
|
super().__init__(prog, indent_increment, max_help_position, width)
|
|||
|
|
|||
|
def _format_action_invocation(self, action):
|
|||
|
"""格式化参数选项的显示方式,添加彩色显示"""
|
|||
|
if not action.option_strings:
|
|||
|
# 位置参数,显示为蓝色
|
|||
|
metavar, = self._metavar_formatter(action, action.dest)(1)
|
|||
|
return f"{self.BLUE}{metavar}{self.RESET}"
|
|||
|
|
|||
|
# 处理可选参数
|
|||
|
parts = []
|
|||
|
|
|||
|
# 判断是否为必选参数,是则使用黄色,否则使用绿色
|
|||
|
color = self.YELLOW if action.required else self.GREEN
|
|||
|
|
|||
|
# 如果同时有短选项和长选项
|
|||
|
if len(action.option_strings) > 1:
|
|||
|
short, long = action.option_strings
|
|||
|
parts.append(f"{color}{short}{self.RESET}, {color}{long}{self.RESET}")
|
|||
|
else:
|
|||
|
# 只有一个选项
|
|||
|
parts.append(f"{color}{action.option_strings[0]}{self.RESET}")
|
|||
|
|
|||
|
# 添加 metavar(如果有)
|
|||
|
if action.metavar is not None:
|
|||
|
parts.append(f" {action.metavar}")
|
|||
|
elif action.nargs != 0:
|
|||
|
parts.append(f" {action.dest.upper()}")
|
|||
|
|
|||
|
return ''.join(parts)
|
|||
|
|
|||
|
def add_usage(self, usage, actions, groups, prefix=None):
|
|||
|
"""重写帮助信息的用法部分,优化了显示格式"""
|
|||
|
if prefix is None:
|
|||
|
prefix = 'usage: '
|
|||
|
return super().add_usage(usage, actions, groups, prefix)
|
|||
|
|
|||
|
def _format_action(self, action):
|
|||
|
"""重写格式化动作方法,确保帮助文本正确对齐和显示"""
|
|||
|
# 获取基础格式化的帮助文本
|
|||
|
result = super()._format_action(action)
|
|||
|
|
|||
|
# 如果有choices且不是帮助动作,则添加选项信息
|
|||
|
if hasattr(action, 'choices') and action.choices and action.option_strings:
|
|||
|
# 查找最后一个换行符后的位置
|
|||
|
last_line_start = result.rfind('\n') + 1
|
|||
|
# indentation = ' ' * (last_line_start - result.rfind('\n', 0, last_line_start - 1) - 1)
|
|||
|
indentation = ' ' * 8
|
|||
|
|
|||
|
# 格式化choices选项
|
|||
|
choices_str = f"{indentation} 可选值: {', '.join([str(c) for c in action.choices])}"
|
|||
|
result = f"{result}\n{choices_str} \n"
|
|||
|
|
|||
|
return result
|
|||
|
|
|||
|
def _split_lines(self, text, width):
|
|||
|
"""优化帮助文本的换行处理"""
|
|||
|
if not text:
|
|||
|
return []
|
|||
|
if '\n' in text:
|
|||
|
# 开头的文本按原样分行显示
|
|||
|
ret = []
|
|||
|
for _ in text.splitlines():
|
|||
|
_ = _.strip()
|
|||
|
ret.append(_[1:] if _[0] == '|' else _)
|
|||
|
return ret
|
|||
|
# 正常文本使用 textwrap 换行
|
|||
|
return textwrap.wrap(text, width)
|
|||
|
|
|||
|
def _fill_text(self, text, width, indent):
|
|||
|
"""优化帮助文本的填充显示"""
|
|||
|
if not text:
|
|||
|
return ""
|
|||
|
# 使用textwrap对文本进行缩进和填充
|
|||
|
text = self._whitespace_matcher.sub(' ', text).strip()
|
|||
|
paragraphs = text.split('.\n ')
|
|||
|
multi_paragraphs = '\n'.join([textwrap.fill(p, width) for p in paragraphs])
|
|||
|
return textwrap.indent(multi_paragraphs, indent)
|
|||
|
|
|||
|
|
|||
|
@AutoInstanceDecorator
|
|||
|
class ReleaseOptions(BaseConfig):
|
|||
|
"""Release 选项
|
|||
|
|
|||
|
Args:
|
|||
|
SkipCheckout (bool, optional): 是否跳过checkout kernel/mboot 的操作. Defaults to False.
|
|||
|
OpenSource (bool, optional):
|
|||
|
#是否开启SDK开源模式:
|
|||
|
#闭源模式: MI编译为lib和ko对外提供功能
|
|||
|
#开源模式:MI源码发布, 客户可直接获得MI原始代码
|
|||
|
# 开源的list:
|
|||
|
# sdk/interface/src/vpe/
|
|||
|
# sdk/interface/src/venc/
|
|||
|
# sdk/impl/vpe
|
|||
|
# sdk/impl/venc/. Defaults to False.
|
|||
|
Cm4Support (bool, optional): 支持release CM4. Defaults to False.
|
|||
|
RiscVSupport (bool, optional): 支持release RiscV. Defaults to False.
|
|||
|
MounRiverSDK (int, optional): 选择MounRiver SDK版本. Defaults to 0.
|
|||
|
ThreadNum (int, optional): 编译线程数. Defaults to 1.
|
|||
|
Doc2Pdf (bool, optional): 编译文档为pdf格式. Defaults to False.
|
|||
|
VerifyBuild (bool, optional): 验证编译结果. Defaults to False.
|
|||
|
Doc2Html (bool, optional): 编译文档为html格式. Defaults to False.
|
|||
|
ReduceCodeSize (bool, optional): 减小编译代码大小. Defaults to False.
|
|||
|
SkipSyncCode (bool, optional): 跳过代码同步. Defaults to False.
|
|||
|
Ipl_version (str, optional): 选择IPL版本. Defaults to "CN".
|
|||
|
"""
|
|||
|
_config = {
|
|||
|
# 必需参数
|
|||
|
"SWBoardAlias": "", # -a: 板子别名
|
|||
|
"TagId": "", # -t: 标签ID
|
|||
|
"SnapShotXml": "", # -s: 快照XML文件
|
|||
|
"SWBoardType": "", # -b: 板子类型
|
|||
|
"SWProductType": "", # -p: 产品类型
|
|||
|
|
|||
|
# 可选参数
|
|||
|
"AlkaidRootPath": '', # 仓库根路径
|
|||
|
"DocsPath": "", # -d: 文档路径
|
|||
|
"HWChipType": "", # -c: 硬件芯片类型
|
|||
|
"HWPackageType": "", # -k: 硬件包类型
|
|||
|
"OutPath": "", # -o: 输出路径
|
|||
|
"ThreadNum": 1, # -j: 线程数
|
|||
|
"IplVersion": "CN", # -l: IPL版本
|
|||
|
|
|||
|
# 布尔参数
|
|||
|
"SkipCheckout": False, # -i: 跳过从bin检出kernel/mboot
|
|||
|
"OpenSource": False, # -f: 开放源代码
|
|||
|
"MounRiverSDK": False, # -m: 启用RiscVSupport时支持MounRiverSDK
|
|||
|
"RiscVSupport": False, # -n: 支持riscv源码
|
|||
|
"Cm4Support": False, # -y: 支持cm4源码
|
|||
|
"Doc2Pdf": False, # -z: 文档转换为pdf
|
|||
|
"Doc2Html": False, # -h: 文档转换为html
|
|||
|
"VerifyBuild": False, # -v: 验证构建
|
|||
|
"ReduceCodeSize": False, # -u: 减小代码大小
|
|||
|
"SkipSyncCode": False, # -x: 跳过通过快照XML同步代码
|
|||
|
"OpenRtosWhiteList": False, # -X: 开放所有rtos白名单
|
|||
|
"OpenCm4WhiteList": False, # -Y: 开放所有cm4白名单
|
|||
|
}
|
|||
|
|
|||
|
def __init__(self):
|
|||
|
super().__init__()
|
|||
|
parser = argparse.ArgumentParser(description='Sigmastar Release SDK Options',
|
|||
|
formatter_class=ConfigureStyleHelpFormatter,
|
|||
|
epilog= "more help info see: http://xxxxxx",
|
|||
|
add_help=False) #-hhelp 信息被占用了
|
|||
|
add = parser.add_argument
|
|||
|
add('-a', '--SWBoardAlias' , required=True, type=str, help='板子别名 iford souffle muffin...')
|
|||
|
add('-t', '--TagId' , required=True, type=str, help='Release的Tag')
|
|||
|
add('-s', '--SnapShotXml' , required=True, type=str, help='Alkaid仓库快照XML文件')
|
|||
|
add('-b', '--SWBoardType' , required=True, type=str, help='板子类型')
|
|||
|
add('-p', '--SWProductType' , required=True, type=str, help='Release产品类型列表')
|
|||
|
add('-r', '--AlkaidRootPath', default = get_alkaid_root(), type=str, help='Alkaid仓库根目录路径')
|
|||
|
add('-d', '--DocsPath' , default = '', type=str, help='文档路径')
|
|||
|
add('-c', '--HWChipType' , default = '', type=str, help='硬件芯片类型')
|
|||
|
add('-k', '--HWPackageType' , default = '', type=str, help='硬件封装类型')
|
|||
|
add('-o', '--OutPath' , default = "release", type=str, help='Release输出路径')
|
|||
|
add('-j', '--ThreadNum' , default = 1, type=int, help='编译使用的线程数')
|
|||
|
add('-i', '--SkipCheckout' , default = False, action = "store_true", help='跳过从bin检出kernel/mboot')
|
|||
|
add('-f', '--OpenSource' , default = False, action = "store_true",
|
|||
|
help="""是否开启SDK开源模式:
|
|||
|
| 闭源模式: MI编译为lib和ko对外提供功能
|
|||
|
| 开源模式: MI源码发布, 客户可直接获得MI原始代码""")
|
|||
|
add('-n', '--RiscVSupport' , default = False, action = "store_true", help='支持riscv源码')
|
|||
|
add('-y', '--Cm4Support' , default = False, action = "store_true", help='支持cm4源码')
|
|||
|
add('-m', '--MounRiverSDK' , default = False, action = "store_true", help='启用RiscVSupport时支持MounRiverSDK')
|
|||
|
add('-z', '--Doc2Pdf' , default = False, action = "store_true", help='将文档转换为PDF格式')
|
|||
|
add('-l', '--IplVersion' , default = "CN", type=str, choices=["CN", "WW"], help='选择IPL版本')
|
|||
|
add('-h', '--Doc2Html' , default = False, action = "store_true", help='将文档转换为HTML格式')
|
|||
|
add('-v', '--VerifyBuild' , default = False, action = "store_true", help='验证构建')
|
|||
|
add('-u', '--ReduceCodeSize', default = False, action = "store_true", help='减小代码体积')
|
|||
|
add('-x', '--SkipSyncCode' , default = False, action = "store_true", help='跳过通过快照XML同步代码')
|
|||
|
add('--help', action='help', help='显示帮助信息')
|
|||
|
add('--log', type=str,choices=['error', 'warn', 'info', 'debug', 'trace'], default='info', help='设置日志级别')
|
|||
|
self.parser = parser
|
|||
|
|
|||
|
def parse(self, args:List[str]):
|
|||
|
args = self.parser.parse_args(args)
|
|||
|
for k,v in args.__dict__.items():
|
|||
|
if k.startswith('__'):
|
|||
|
continue
|
|||
|
self[k] = v
|
|||
|
def check(self) -> bool:
|
|||
|
"""
|
|||
|
检查参数配置是否合法
|
|||
|
"""
|
|||
|
# 检查必需参数
|
|||
|
required_params = ["SWBoardAlias", "TagId", "SWBoardType", "SWProductType"]
|
|||
|
for param in required_params:
|
|||
|
if not self[param]:
|
|||
|
raise ValueError(f"必需参数 {param} 不能为空")
|
|||
|
|
|||
|
# 检查数值参数
|
|||
|
if not isinstance(self.ThreadNum, int) or self.ThreadNum <= 0:
|
|||
|
raise ValueError("ThreadNum 必须为正整数")
|
|||
|
|
|||
|
# 检查布尔参数
|
|||
|
bool_params = [
|
|||
|
"SkipCheckout", "OpenSource", "RiscVSupport", "Cm4Support",
|
|||
|
"Doc2Pdf", "Doc2Html", "VerifyBuild", "ReduceCodeSize",
|
|||
|
"SkipSyncCode", "OpenRtosWhiteList", "OpenCm4WhiteList", "MounRiverSDK"
|
|||
|
]
|
|||
|
for param in bool_params:
|
|||
|
if not isinstance(self[param], bool):
|
|||
|
raise ValueError(f"参数 {param} 必须为布尔值")
|
|||
|
# 检查快照XML文件是否存在
|
|||
|
if not self.SkipSyncCode and not self.SnapShotXml:
|
|||
|
raise ValueError("SnapShotXml is required when SkipSyncCode is False")
|
|||
|
return True
|
|||
|
|
|||
|
def help(self):
|
|||
|
self.parser.print_help()
|