// +build ignore package main import ( "bytes" "go/format" "io/ioutil" "log" "net/http" "sort" "strings" "text/template" "time" "gopkg.in/yaml.v2" ) type CFCode int type HTTPCode int type Definition struct { CFCode `yaml:"-"` Name string `yaml:"name"` HTTPCode `yaml:"http_code"` Message string `yaml:"message"` } func main() { const url = "https://raw.githubusercontent.com/cloudfoundry/cloud_controller_ng/master/vendor/errors/v2.yml" resp, err := http.Get(url) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } var m map[CFCode]Definition if err := yaml.Unmarshal(body, &m); err != nil { log.Fatal(err) } var definitions []Definition for c, d := range m { d.CFCode = c definitions = append(definitions, d) } sort.Slice(definitions, func(i, j int) bool { return definitions[i].CFCode < definitions[j].CFCode }) buf := &bytes.Buffer{} if err := packageTemplate.Execute(buf, struct { Timestamp time.Time Definitions []Definition }{ Timestamp: time.Now(), Definitions: definitions, }); err != nil { log.Fatal(err) } dst, err := format.Source(buf.Bytes()) if err != nil { log.Printf("%s", buf.Bytes()) log.Fatal(err) } if err := ioutil.WriteFile("cf_error.go", dst, 0600); err != nil { log.Fatal(err) } } // destutter ensures that s does not end in "Error". func destutter(s string) string { return strings.TrimSuffix(s, "Error") } var packageTemplate = template.Must(template.New("").Funcs(template.FuncMap{ "destutter": destutter, }).Parse(` package cfclient // Code generated by go generate. DO NOT EDIT. // This file was generated by robots at // {{ .Timestamp }} import "github.com/pkg/errors" {{- range .Definitions }} {{$method := printf "Is%sError" (.Name | destutter) }} // {{ $method }} returns a boolean indicating whether // the error is known to report the Cloud Foundry error: // - Cloud Foundry code: {{ .CFCode }} // - HTTP code: {{ .HTTPCode }} // - message: {{ printf "%q" .Message }} func Is{{ .Name | destutter }}Error(err error) bool { cause := errors.Cause(err) cferr, ok := cause.(CloudFoundryError) if !ok { return false } return cferr.Code == {{ .CFCode }} } {{- end }} `))