package main import ( "encoding/json" "fmt" "io/ioutil" "log" "os" "strings" "text/template" ) type ciModel struct { Name string `json:"name"` Constant string `json:"constant"` Env interface{} `json:"env"` Pr interface{} `json:"pr"` } type templateData struct { CIs []ciModel } func (ci ciModel) EnvMatcherMethod() string { return getMatcherMethod(ci.Env) } func (ci ciModel) PrMatcherMethod() string { return getMatcherMethod(ci.Pr) } func interfaceSliceToStr(input []interface{}) []string { res := make([]string, 0) for _, elm := range input { res = append(res, elm.(string)) } return res } func getMatcherMethod(rawMatcher interface{}) string { if rawMatcher == nil { return "nil" } switch rawMatcher.(type) { case string: return fmt.Sprintf(`simpleEnvMatcher{"%s"}`, rawMatcher) case []interface{}: envvars := interfaceSliceToStr(rawMatcher.([]interface{})) return fmt.Sprintf(`allEnvMatcher{[]string{"%s"}}`, strings.Join(envvars, `", "`)) case map[string]interface{}: envvarsMap := rawMatcher.(map[string]interface{}) if eEnv, exists := envvarsMap["env"]; exists { return fmt.Sprintf(`neEnvMatcher{"%s", "%s"}`, eEnv, envvarsMap["ne"]) } if eAny, exists := envvarsMap["any"]; exists { return fmt.Sprintf(`anyEnvMatcher{[]string{"%s"}}`, strings.Join(interfaceSliceToStr(eAny.([]interface{})), `", "`)) } envvarsList := make([]string, 0) for key, value := range envvarsMap { envvarsList = append(envvarsList, fmt.Sprintf(`"%s": "%s"`, key, value)) } return fmt.Sprintf(`kvEnvMatcher{map[string]string{%s}}`, strings.Join(envvarsList, ", ")) } return fmt.Sprintf("// Error: could not parse %s", rawMatcher) } func main() { // Open our jsonFile jsonFile, err := os.Open("vendors.json") if err != nil { log.Fatalln(err) } defer func(jsonFile *os.File) { _ = jsonFile.Close() }(jsonFile) byteValue, _ := ioutil.ReadAll(jsonFile) data := templateData{} err = json.Unmarshal(byteValue, &data.CIs) if err != nil { log.Fatalln(err) } tmpl := template.New("code") tmpl, err = tmpl.Parse(codeTemplate) if err != nil { log.Fatalln(err) } err = tmpl.Execute(os.Stdout, data) if err != nil { log.Fatalln(err) } } const codeTemplate = `package ci_ingo // The list of CI vendors is auto-generated from the vendors.json file // of the original ci-info package. Don't edit this file directly. var vendors = []vendorCI{ {{- range .CIs}} { name: "{{.Name}}", constant: "{{.Constant}}", env: {{.EnvMatcherMethod}}, pr: {{.PrMatcherMethod}}, }, {{- end}} } `