import 'package:swagger_generator_flutter/core/exceptions.dart'; /// 命令基类 /// 实现命令模式,提供统一的命令接口 abstract class BaseCommand { /// 命令名称 String get name; /// 命令描述 String get description; /// 命令用法 String get usage; /// 支持的选项 List get options => []; /// 支持的参数 List get arguments => []; /// 执行命令 Future execute(List args); /// 显示帮助信息 void showHelp() { print(''); print('命令: $name'); print('描述: $description'); print('用法: $usage'); if (arguments.isNotEmpty) { print(''); print('参数:'); for (final arg in arguments) { final required = arg.required ? '(必填)' : '(可选)'; print(' ${arg.name} ${arg.description} $required'); } } if (options.isNotEmpty) { print(''); print('选项:'); for (final option in options) { final short = option.shortName != null ? '-${option.shortName}, ' : ''; final defaultValue = option.defaultValue != null ? ' (默认: ${option.defaultValue})' : ''; print(' $short--${option.name} ${option.description}$defaultValue'); } } print(''); } /// 解析命令行参数 ParsedArguments parseArguments(List args) { final parser = ArgumentParser(this); return parser.parse(args); } /// 验证参数 void validateArguments(ParsedArguments parsedArgs) { // 验证必填参数 for (final arg in arguments.where((a) => a.required)) { if (!parsedArgs.hasArgument(arg.name)) { throw CommandException('缺少必填参数: ${arg.name}'); } } // 验证必填选项 for (final option in options.where((o) => o.required)) { if (!parsedArgs.hasOption(option.name)) { throw CommandException('缺少必填选项: --${option.name}'); } } } /// 处理执行前的准备工作 Future prepare(ParsedArguments parsedArgs) async { // 子类可以重写此方法进行准备工作 } /// 处理执行后的清理工作 Future cleanup(ParsedArguments parsedArgs) async { // 子类可以重写此方法进行清理工作 } /// 错误处理 void handleError(dynamic error, StackTrace stackTrace) { if (error is CommandException) { print('❌ 错误: ${error.message}'); if (error.details != null) { print('详细信息: ${error.details}'); } } else if (error is SwaggerException) { print('❌ Swagger错误: ${error.message}'); if (error.details != null) { print('详细信息: ${error.details}'); } } else { print('❌ 未知错误: $error'); print('堆栈跟踪: $stackTrace'); } } /// 成功消息 void success(String message) { print('✅ $message'); } /// 信息消息 void info(String message) { print('ℹ️ $message'); } /// 警告消息 void warning(String message) { print('⚠️ $message'); } /// 进度消息 void progress(String message) { print('🔄 $message'); } } /// 命令选项 class CommandOption { const CommandOption({ required this.name, required this.description, this.shortName, this.required = false, this.defaultValue, this.type = OptionType.flag, }); final String name; final String? shortName; final String description; final bool required; final dynamic defaultValue; final OptionType type; } /// 命令参数 class CommandArgument { const CommandArgument({ required this.name, required this.description, this.required = true, this.defaultValue, }); final String name; final String description; final bool required; final dynamic defaultValue; } /// 选项类型 enum OptionType { flag, string, int, double, list } /// 解析后的参数 class ParsedArguments { final Map _options = {}; final Map _arguments = {}; /// 设置选项值 void setOption(String name, dynamic value) { _options[name] = value; } /// 设置参数值 void setArgument(String name, dynamic value) { _arguments[name] = value; } /// 获取选项值 T? getOption(String name) { return _options[name] as T?; } /// 获取参数值 T? getArgument(String name) { return _arguments[name] as T?; } /// 检查是否有选项 bool hasOption(String name) { return _options.containsKey(name); } /// 检查是否有参数 bool hasArgument(String name) { return _arguments.containsKey(name); } /// 获取所有选项 Map get options => Map.unmodifiable(_options); /// 获取所有参数 Map get arguments => Map.unmodifiable(_arguments); } /// 参数解析器 class ArgumentParser { ArgumentParser(this.command); final BaseCommand command; /// 解析参数 ParsedArguments parse(List args) { final result = ParsedArguments(); final argQueue = List.from(args); var argumentIndex = 0; while (argQueue.isNotEmpty) { final current = argQueue.removeAt(0); if (current.startsWith('--')) { // 长选项 _parseLongOption(current, argQueue, result); } else if (current.startsWith('-') && current.length > 1) { // 短选项 _parseShortOption(current, argQueue, result); } else { // 位置参数 if (argumentIndex < command.arguments.length) { final arg = command.arguments[argumentIndex]; result.setArgument(arg.name, current); argumentIndex++; } else { throw CommandException('未知参数: $current'); } } } // 设置默认值 _setDefaultValues(result); return result; } /// 解析长选项 void _parseLongOption( String current, List argQueue, ParsedArguments result, ) { String optionName; String? optionValue; if (current.contains('=')) { final parts = current.split('='); optionName = parts[0].substring(2); optionValue = parts.sublist(1).join('='); } else { optionName = current.substring(2); } final option = command.options.firstWhere( (o) => o.name == optionName, orElse: () => throw CommandException('未知选项: --$optionName'), ); if (option.type == OptionType.flag) { result.setOption(optionName, true); } else { if (optionValue == null) { if (argQueue.isEmpty) { throw CommandException('选项 --$optionName 需要一个值'); } optionValue = argQueue.removeAt(0); } final convertedValue = _convertValue(optionValue, option.type); result.setOption(optionName, convertedValue); } } /// 解析短选项 void _parseShortOption( String current, List argQueue, ParsedArguments result, ) { final shortName = current.substring(1); final option = command.options.firstWhere( (o) => o.shortName == shortName, orElse: () => throw CommandException('未知选项: -$shortName'), ); if (option.type == OptionType.flag) { result.setOption(option.name, true); } else { if (argQueue.isEmpty) { throw CommandException('选项 -$shortName 需要一个值'); } final optionValue = argQueue.removeAt(0); final convertedValue = _convertValue(optionValue, option.type); result.setOption(option.name, convertedValue); } } /// 转换值类型 dynamic _convertValue(String value, OptionType type) { switch (type) { case OptionType.string: return value; case OptionType.int: return int.tryParse(value) ?? (throw CommandException('无效的整数值: $value')); case OptionType.double: return double.tryParse(value) ?? (throw CommandException('无效的浮点数值: $value')); case OptionType.list: return value.split(',').map((s) => s.trim()).toList(); case OptionType.flag: return true; } } /// 设置默认值 void _setDefaultValues(ParsedArguments result) { // 设置选项默认值 for (final option in command.options) { if (!result.hasOption(option.name) && option.defaultValue != null) { result.setOption(option.name, option.defaultValue); } } // 设置参数默认值 for (final argument in command.arguments) { if (!result.hasArgument(argument.name) && argument.defaultValue != null) { result.setArgument(argument.name, argument.defaultValue); } } } } /// 命令异常 class CommandException implements Exception { const CommandException(this.message, {this.details}); final String message; final String? details; @override String toString() { return 'CommandException: $message${details != null ? ' ($details)' : ''}'; } }