package utils import ( "fmt" "os" "path/filepath" "regexp" "xg_dba/internal/models" "github.com/mitchellh/mapstructure" "github.com/spf13/viper" ) // fileExists 检查给定路径的文件是否存在。 func FileExists(filename string) bool { info, err := os.Stat(filename) if os.IsNotExist(err) { return false } return !info.IsDir() } // parseTomlFile 使用 viper 解析 TOML 文件到提供的结构体中。 func ParseTomlFile1(filePath string, v interface{}) error { // 为了防止 viper 的全局状态干扰解析结果,使用新的 viper 实例 vp := viper.New() vp.SetConfigFile(filePath) vp.SetConfigType("toml") if err := vp.ReadInConfig(); err != nil { return err } // 使用 `vp.AllSettings()` 将配置映射到提供的结构体 settings := vp.AllSettings() if err := DecodeSettings(settings, v); err != nil { return err } return nil } // parseTomlFile 使用 viper 解析 TOML 文件到提供的结构体中。 func ParseTomlFile(filePath string, v interface{}) error { // 创建一个新的 viper 实例,防止全局状态干扰 vp := viper.New() vp.SetConfigFile(filePath) vp.SetConfigType("toml") // 读取配置文件 if err := vp.ReadInConfig(); err != nil { return err } // 将配置文件内容解析到提供的结构体 if err := vp.Unmarshal(v); err != nil { return err } return nil } // decodeSettings 将 viper 的设置映射解码到目标结构体。 func DecodeSettings(settings map[string]interface{}, v interface{}) error { decoderConfig := &mapstructure.DecoderConfig{ Result: v, TagName: "toml", WeaklyTypedInput: true, } decoder, err := mapstructure.NewDecoder(decoderConfig) if err != nil { return err } return decoder.Decode(settings) } // getLatestOsInfoFile 在给定目录中查找最新的 os_info TOML 文件。 // 它查找匹配模式 "os_info_.toml" 的文件,并返回最新的一个。 func GetLatestOsInfoFiles(dirPath string) (map[string]models.SystemMetaInfo, error) { // 编译正则表达式,匹配并捕获 pattern := regexp.MustCompile(`^(\d{1,3}(?:\.\d{1,3}){3})_os_info_(\d{8}_\d{6})\.toml$`) files, err := os.ReadDir(dirPath) if err != nil { return nil, err } // 创建用于存储最新文件的映射 latestFiles := make(map[string]string) latestTimestamps := make(map[string]string) for _, file := range files { if !file.IsDir() { name := file.Name() matches := pattern.FindStringSubmatch(name) if len(matches) == 3 { ip := matches[1] timestamp := matches[2] // 比较并更新最新的时间戳 if prevTimestamp, exists := latestTimestamps[ip]; !exists || timestamp > prevTimestamp { latestTimestamps[ip] = timestamp latestFiles[ip] = filepath.Join(dirPath, name) } } } } systemMeta := make(map[string]models.SystemMetaInfo) for ip, path := range latestFiles { fmt.Printf("Latest os_info file for %s: %s\n", ip, path) var systemMetaInfo models.SystemMetaInfo if err := ParseTomlFile(path, &systemMetaInfo); err != nil { return nil, err } systemMeta[ip] = systemMetaInfo fmt.Println("获取目录中最新的 os_info.toml 文件:", systemMetaInfo) } return systemMeta, nil }