package main import ( "fmt" "log" "os" "path/filepath" "strings" "text/template" "golang.org/x/text/cases" "golang.org/x/text/language" "gopkg.in/yaml.v3" ) type ErrorItem struct { Name string Value string } type TplData struct { Items []ErrorItem } func toCamel(s string) string { caser := cases.Title(language.English) s = strings.ReplaceAll(s, "-", "_") parts := strings.Split(s, "_") for i := range parts { parts[i] = caser.String(parts[i]) } return strings.Join(parts, "") } func recursiveParse(prefix string, raw any, items *[]ErrorItem) { switch v := raw.(type) { case map[string]any: for key, val := range v { recursiveParse(prefix+toCamel(key), val, items) } case string: *items = append(*items, ErrorItem{ Name: prefix, Value: v, }) case int, int64: *items = append(*items, ErrorItem{ Name: prefix, Value: fmt.Sprintf("%v", v), }) } } func main() { yamlDir := "cmd/gen_exception/definitions" outputDir := "internal/exception" tplPath := "cmd/gen_exception/exception.tmpl" if _, err := os.Stat(tplPath); os.IsNotExist(err) { log.Fatalf("Cannot found tmpl %s", tplPath) } funcMap := template.FuncMap{"ToCamel": toCamel} tmpl := template.Must(template.New("exception.tmpl").Funcs(funcMap).ParseFiles(tplPath)) os.MkdirAll(outputDir, 0755) files, _ := filepath.Glob(filepath.Join(yamlDir, "*.yaml")) for _, yamlFile := range files { content, err := os.ReadFile(yamlFile) if err != nil { log.Printf("Read file error: %v", err) continue } var rawData any if err := yaml.Unmarshal(content, &rawData); err != nil { log.Printf("Unmarshal error in %s: %v", yamlFile, err) continue } var items []ErrorItem recursiveParse("", rawData, &items) baseName := strings.TrimSuffix(filepath.Base(yamlFile), filepath.Ext(yamlFile)) outputFileName := baseName + "_gen.go" outputPath := filepath.Join(outputDir, outputFileName) f, _ := os.Create(outputPath) tmpl.Execute(f, TplData{Items: items}) f.Close() fmt.Printf("Generated: %s (%d constants)\n", outputPath, len(items)) } }