import 'dart:io'; import 'package:path/path.dart' as path; import 'package:yaml/yaml.dart'; import 'package:yx_icon_fonts/src/config/generator_config.dart'; /// 配置加载器 /// /// 负责从 YAML 文件加载配置 class ConfigLoader { /// 默认配置文件名 static const String defaultConfigFileName = 'icon_generator_config.yaml'; /// 加载配置文件 /// /// [configPath] 配置文件路径,如果为 null 则使用默认路径 /// [workingDir] 工作目录,默认为当前目录 static GeneratorConfig load({ String? configPath, String? workingDir, }) { final directory = workingDir ?? Directory.current.path; final filePath = configPath ?? path.join(directory, defaultConfigFileName); final file = File(filePath); if (!file.existsSync()) { throw ConfigNotFoundException( '配置文件不存在: $filePath\n' '请运行 "dart run yx_icon_fonts init" 创建配置文件', ); } try { final content = file.readAsStringSync(); final yamlMap = loadYaml(content) as YamlMap?; if (yamlMap == null) { throw ConfigParseException('配置文件为空或格式错误'); } // 将 YamlMap 转换为 Map final map = _convertYamlMap(yamlMap); return GeneratorConfig.fromMap(map); } on YamlException catch (e) { throw ConfigParseException('YAML 解析错误: ${e.message}'); } } /// 检查配置文件是否存在 static bool exists({String? configPath, String? workingDir}) { final directory = workingDir ?? Directory.current.path; final filePath = configPath ?? path.join(directory, defaultConfigFileName); return File(filePath).existsSync(); } /// 将 YamlMap 递归转换为 Map static Map _convertYamlMap(YamlMap yamlMap) { final result = {}; for (final key in yamlMap.keys) { final value = yamlMap[key]; if (value is YamlMap) { result[key.toString()] = _convertYamlMap(value); } else if (value is YamlList) { result[key.toString()] = _convertYamlList(value); } else { result[key.toString()] = value; } } return result; } /// 将 YamlList 递归转换为 List static List _convertYamlList(YamlList yamlList) { return yamlList.map((item) { if (item is YamlMap) { return _convertYamlMap(item); } else if (item is YamlList) { return _convertYamlList(item); } return item; }).toList(); } } /// 配置文件未找到异常 class ConfigNotFoundException implements Exception { ConfigNotFoundException(this.message); final String message; @override String toString() => 'ConfigNotFoundException: $message'; } /// 配置解析异常 class ConfigParseException implements Exception { ConfigParseException(this.message); final String message; @override String toString() => 'ConfigParseException: $message'; }