#!/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