104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
参数解析器
|
|
"""
|
|
|
|
import sys
|
|
from typing import List, Dict, Any, Tuple
|
|
|
|
from .types import CommandConfig
|
|
from ..logger import logger
|
|
|
|
class ArgumentParser:
|
|
"""命令行参数解析器"""
|
|
|
|
def __init__(self, commands: Dict[str, CommandConfig]):
|
|
self.commands = commands
|
|
|
|
def parse_arguments(self, args: List[str]) -> Tuple[str, Dict[str, Any]]:
|
|
"""
|
|
解析命令行参数
|
|
|
|
Args:
|
|
args: 命令行参数列表
|
|
|
|
Returns:
|
|
(command, parsed_args) 元组
|
|
"""
|
|
if len(args) < 1:
|
|
raise ValueError("No command provided")
|
|
|
|
command = args[0]
|
|
|
|
if command not in self.commands:
|
|
raise ValueError(f"Unknown command: {command}")
|
|
|
|
command_config = self.commands[command]
|
|
|
|
# 解析参数
|
|
parsed_args = {}
|
|
remaining_args = args[1:]
|
|
|
|
# 处理必需参数
|
|
if len(remaining_args) < len(command_config.required_args):
|
|
missing_args = command_config.required_args[len(remaining_args):]
|
|
raise ValueError(f"Missing required arguments: {missing_args}")
|
|
|
|
# 设置必需参数
|
|
for i, arg_name in enumerate(command_config.required_args):
|
|
parsed_args[arg_name] = remaining_args[i]
|
|
|
|
# 处理可选参数
|
|
optional_start = len(command_config.required_args)
|
|
i = optional_start
|
|
|
|
while i < len(remaining_args):
|
|
arg = remaining_args[i]
|
|
|
|
if arg.startswith('--'):
|
|
arg_name = arg[2:]
|
|
|
|
if arg_name in command_config.optional_args:
|
|
arg_config = command_config.optional_args[arg_name]
|
|
|
|
# 检查是否需要值
|
|
if arg_config.get('type') == bool:
|
|
parsed_args[arg_name] = True
|
|
i += 1
|
|
elif i + 1 < len(remaining_args) and not remaining_args[i + 1].startswith('--'):
|
|
value_str = remaining_args[i + 1]
|
|
|
|
# 类型转换
|
|
try:
|
|
arg_type = arg_config.get('type', str)
|
|
if arg_type == bool:
|
|
value = value_str.lower() in ('true', '1', 'yes', 'on')
|
|
else:
|
|
value = arg_type(value_str)
|
|
|
|
# 检查选择范围
|
|
choices = arg_config.get('choices')
|
|
if choices and value not in choices:
|
|
raise ValueError(f"Invalid value for {arg_name}: {value}. Choices: {choices}")
|
|
|
|
parsed_args[arg_name] = value
|
|
i += 2
|
|
except (ValueError, TypeError) as e:
|
|
raise ValueError(f"Invalid value for {arg_name}: {value_str}. {e}")
|
|
else:
|
|
raise ValueError(f"Missing value for argument: {arg_name}")
|
|
else:
|
|
logger.warning(f"Unknown optional argument: {arg_name}")
|
|
i += 1
|
|
else:
|
|
i += 1
|
|
|
|
# 设置默认值
|
|
for arg_name, arg_config in command_config.optional_args.items():
|
|
if arg_name not in parsed_args:
|
|
default_value = arg_config.get('default')
|
|
if default_value is not None:
|
|
parsed_args[arg_name] = default_value
|
|
|
|
return command, parsed_args
|