- 更新项目名称为 AUTO_MAA_Go_Updater - 重构代码结构,优化函数命名和逻辑 - 移除 CDK 相关的冗余代码 - 调整版本号为 git commit hash - 更新构建配置和脚本 - 优化 API 客户端实现
199 lines
5.0 KiB
Go
199 lines
5.0 KiB
Go
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
|
||
"AUTO_MAA_Go_Updater/assets"
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// Config 表示应用程序配置
|
||
type Config struct {
|
||
ResourceID string `yaml:"resource_id"`
|
||
CurrentVersion string `yaml:"current_version"`
|
||
UserAgent string `yaml:"user_agent"`
|
||
BackupURL string `yaml:"backup_url"`
|
||
LogLevel string `yaml:"log_level"`
|
||
AutoCheck bool `yaml:"auto_check"`
|
||
CheckInterval int `yaml:"check_interval"` // 秒
|
||
}
|
||
|
||
// ConfigManager 定义配置管理的接口方法
|
||
type ConfigManager interface {
|
||
Load() (*Config, error)
|
||
Save(config *Config) error
|
||
GetConfigPath() string
|
||
}
|
||
|
||
// DefaultConfigManager 实现 ConfigManager 接口
|
||
type DefaultConfigManager struct {
|
||
configPath string
|
||
}
|
||
|
||
// NewConfigManager 创建新的配置管理器
|
||
func NewConfigManager() ConfigManager {
|
||
configDir := getConfigDir()
|
||
configPath := filepath.Join(configDir, "config.yaml")
|
||
return &DefaultConfigManager{
|
||
configPath: configPath,
|
||
}
|
||
}
|
||
|
||
// GetConfigPath 返回配置文件的路径
|
||
func (cm *DefaultConfigManager) GetConfigPath() string {
|
||
return cm.configPath
|
||
}
|
||
|
||
// Load 读取并解析配置文件
|
||
func (cm *DefaultConfigManager) Load() (*Config, error) {
|
||
// 如果配置目录不存在则创建
|
||
configDir := filepath.Dir(cm.configPath)
|
||
if err := os.MkdirAll(configDir, 0755); err != nil {
|
||
return nil, fmt.Errorf("创建配置目录失败: %w", err)
|
||
}
|
||
|
||
// 如果配置文件不存在,创建默认配置
|
||
if _, err := os.Stat(cm.configPath); os.IsNotExist(err) {
|
||
defaultConfig := getDefaultConfig()
|
||
if err := cm.Save(defaultConfig); err != nil {
|
||
return nil, fmt.Errorf("创建默认配置失败: %w", err)
|
||
}
|
||
return defaultConfig, nil
|
||
}
|
||
|
||
// 读取现有配置文件
|
||
data, err := os.ReadFile(cm.configPath)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
||
}
|
||
|
||
var config Config
|
||
if err := yaml.Unmarshal(data, &config); err != nil {
|
||
return nil, fmt.Errorf("解析配置文件失败: %w", err)
|
||
}
|
||
|
||
// 验证并应用缺失字段的默认值
|
||
if err := validateAndApplyDefaults(&config); err != nil {
|
||
return nil, fmt.Errorf("配置验证失败: %w", err)
|
||
}
|
||
|
||
return &config, nil
|
||
}
|
||
|
||
// Save 将配置写入文件
|
||
func (cm *DefaultConfigManager) Save(config *Config) error {
|
||
// 保存前验证配置
|
||
if err := validateConfig(config); err != nil {
|
||
return fmt.Errorf("配置验证失败: %w", err)
|
||
}
|
||
|
||
// 如果配置目录不存在则创建
|
||
configDir := filepath.Dir(cm.configPath)
|
||
if err := os.MkdirAll(configDir, 0755); err != nil {
|
||
return fmt.Errorf("创建配置目录失败: %w", err)
|
||
}
|
||
|
||
// 将配置序列化为 YAML
|
||
data, err := yaml.Marshal(config)
|
||
if err != nil {
|
||
return fmt.Errorf("序列化配置失败: %w", err)
|
||
}
|
||
|
||
// 写入文件
|
||
if err := os.WriteFile(cm.configPath, data, 0644); err != nil {
|
||
return fmt.Errorf("写入配置文件失败: %w", err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// getDefaultConfig 返回带有默认值的配置
|
||
func getDefaultConfig() *Config {
|
||
// 首先尝试从嵌入模板加载
|
||
if templateData, err := assets.GetConfigTemplate(); err == nil {
|
||
var config Config
|
||
if err := yaml.Unmarshal(templateData, &config); err == nil {
|
||
return &config
|
||
}
|
||
}
|
||
|
||
// 如果模板加载失败则回退到硬编码默认值
|
||
return &Config{
|
||
ResourceID: "M9A", // 默认资源 ID
|
||
CurrentVersion: "v1.0.0",
|
||
UserAgent: "AUTO_MAA_Go_Updater/1.0",
|
||
BackupURL: "",
|
||
LogLevel: "info",
|
||
AutoCheck: true,
|
||
CheckInterval: 3600, // 1 小时
|
||
}
|
||
}
|
||
|
||
// validateConfig 验证配置值
|
||
func validateConfig(config *Config) error {
|
||
if config == nil {
|
||
return fmt.Errorf("配置不能为空")
|
||
}
|
||
|
||
if config.ResourceID == "" {
|
||
return fmt.Errorf("resource_id 不能为空")
|
||
}
|
||
|
||
if config.CurrentVersion == "" {
|
||
return fmt.Errorf("current_version 不能为空")
|
||
}
|
||
|
||
if config.UserAgent == "" {
|
||
return fmt.Errorf("user_agent 不能为空")
|
||
}
|
||
|
||
validLogLevels := map[string]bool{
|
||
"debug": true,
|
||
"info": true,
|
||
"warn": true,
|
||
"error": true,
|
||
}
|
||
if !validLogLevels[config.LogLevel] {
|
||
return fmt.Errorf("无效的 log_level: %s (必须是 debug, info, warn 或 error)", config.LogLevel)
|
||
}
|
||
|
||
if config.CheckInterval < 60 {
|
||
return fmt.Errorf("check_interval 必须至少为 60 秒")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// validateAndApplyDefaults 验证配置并为缺失字段应用默认值
|
||
func validateAndApplyDefaults(config *Config) error {
|
||
defaults := getDefaultConfig()
|
||
|
||
// 为空字段应用默认值
|
||
if config.UserAgent == "" {
|
||
config.UserAgent = defaults.UserAgent
|
||
}
|
||
if config.LogLevel == "" {
|
||
config.LogLevel = defaults.LogLevel
|
||
}
|
||
if config.CheckInterval == 0 {
|
||
config.CheckInterval = defaults.CheckInterval
|
||
}
|
||
if config.CurrentVersion == "" {
|
||
config.CurrentVersion = defaults.CurrentVersion
|
||
}
|
||
|
||
// 应用默认值后进行验证
|
||
return validateConfig(config)
|
||
}
|
||
|
||
// getConfigDir 返回配置目录路径
|
||
func getConfigDir() string {
|
||
// 在 Windows 上使用 APPDATA,回退到当前目录
|
||
if appData := os.Getenv("APPDATA"); appData != "" {
|
||
return filepath.Join(appData, "AUTO_MAA_Go_Updater")
|
||
}
|
||
return "."
|
||
}
|