package model import ( "fmt" "os" "path/filepath" ) type ValidationResult struct { Valid bool Files map[string]string Missing []string Problems []string } func ValidateModelDir(profile ModelProfile, dir string) ValidationResult { result := ValidationResult{ Valid: true, Files: make(map[string]string), } info, err := os.Stat(dir) if err != nil { result.Valid = false result.Missing = append(result.Missing, dir) return result } if !info.IsDir() { result.Valid = false result.Problems = append(result.Problems, fmt.Sprintf("%s is not a directory", dir)) return result } for _, rule := range profile.RequiredFiles { if !rule.Required { continue } if len(rule.AllOf) > 0 { for _, rel := range rule.AllOf { path := filepath.Join(dir, rel) if !validRequiredPath(path, rule.Directory) { result.Valid = false result.Missing = append(result.Missing, rel) continue } if rule.Role != "" && result.Files[rule.Role] == "" { result.Files[rule.Role] = path } } } if len(rule.AnyOf) > 0 { var selected string for _, rel := range rule.AnyOf { path := filepath.Join(dir, rel) if validRequiredPath(path, rule.Directory) { selected = path break } } if selected == "" { result.Valid = false result.Missing = append(result.Missing, fmt.Sprintf("%s:anyOf(%v)", rule.Role, rule.AnyOf)) } else if rule.Role != "" { result.Files[rule.Role] = selected } } } return result } func validRequiredFile(path string) bool { return validRequiredPath(path, false) } func validRequiredPath(path string, directory bool) bool { info, err := os.Stat(path) if err != nil { return false } if directory { return info.IsDir() } if info.IsDir() { return false } return info.Size() > 0 }