package main import ( "encoding/json" "os" "os/exec" "strings" "github.com/alecthomas/template" ) const ( tmpl = `package kingpin // This file is autogenerated by "go generate .". Do not modify. {{range .}} {{if not .NoValueParser}} // -- {{.Type}} Value type {{.|ValueName}} struct { v *{{.Type}} } func new{{.|Name}}Value(p *{{.Type}}) *{{.|ValueName}} { return &{{.|ValueName}}{p} } func (f *{{.|ValueName}}) Set(s string) error { v, err := {{.Parser}} if err == nil { *f.v = ({{.Type}})(v) } return err } func (f *{{.|ValueName}}) Get() interface{} { return ({{.Type}})(*f.v) } func (f *{{.|ValueName}}) String() string { return {{.|Format}} } {{if .Help}} // {{.Help}} {{else}}\ // {{.|Name}} parses the next command-line value as {{.Type}}. {{end}}\ func (p *parserMixin) {{.|Name}}() (target *{{.Type}}) { target = new({{.Type}}) p.{{.|Name}}Var(target) return } func (p *parserMixin) {{.|Name}}Var(target *{{.Type}}) { p.SetValue(new{{.|Name}}Value(target)) } {{end}} // {{.|Plural}} accumulates {{.Type}} values into a slice. func (p *parserMixin) {{.|Plural}}() (target *[]{{.Type}}) { target = new([]{{.Type}}) p.{{.|Plural}}Var(target) return } func (p *parserMixin) {{.|Plural}}Var(target *[]{{.Type}}) { p.SetValue(newAccumulator(target, func(v interface{}) Value { return new{{.|Name}}Value(v.(*{{.Type}})) })) } {{end}} ` ) type Value struct { Name string `json:"name"` NoValueParser bool `json:"no_value_parser"` Type string `json:"type"` Parser string `json:"parser"` Format string `json:"format"` Plural string `json:"plural"` Help string `json:"help"` } func fatalIfError(err error) { if err != nil { panic(err) } } func main() { r, err := os.Open("values.json") fatalIfError(err) defer r.Close() v := []Value{} err = json.NewDecoder(r).Decode(&v) fatalIfError(err) valueName := func(v *Value) string { if v.Name != "" { return v.Name } return strings.Title(v.Type) } t, err := template.New("genvalues").Funcs(template.FuncMap{ "Lower": strings.ToLower, "Format": func(v *Value) string { if v.Format != "" { return v.Format } return "fmt.Sprintf(\"%v\", *f.v)" }, "ValueName": func(v *Value) string { name := valueName(v) return strings.ToLower(name[0:1]) + name[1:] + "Value" }, "Name": valueName, "Plural": func(v *Value) string { if v.Plural != "" { return v.Plural } return valueName(v) + "List" }, }).Parse(tmpl) fatalIfError(err) w, err := os.Create("values_generated.go") fatalIfError(err) defer w.Close() err = t.Execute(w, v) fatalIfError(err) err = exec.Command("goimports", "-w", "values_generated.go").Run() fatalIfError(err) }