github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/client/gen/client_generator.go (about) 1 package gen 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io/ioutil" 7 "net/http" 8 "path" 9 "regexp" 10 "strings" 11 12 "github.com/go-openapi/spec" 13 "github.com/morlay/oas" 14 "github.com/sirupsen/logrus" 15 16 "github.com/johnnyeven/libtools/codegen" 17 "github.com/johnnyeven/libtools/courier/client/gen/enums" 18 "github.com/johnnyeven/libtools/courier/client/gen/v2" 19 "github.com/johnnyeven/libtools/courier/client/gen/v3" 20 "github.com/johnnyeven/libtools/courier/status_error" 21 ) 22 23 type ClientGenerator struct { 24 File string 25 SpecURL string 26 BaseClient string 27 ServiceName string 28 swagger *spec.Swagger 29 openAPI *oas.OpenAPI 30 statusErrCodeMap status_error.StatusErrorCodeMap 31 } 32 33 func (g *ClientGenerator) Load(cwd string) { 34 if g.SpecURL == "" && g.File == "" { 35 logrus.Panicf("missing spec-url or file") 36 return 37 } 38 39 if g.SpecURL != "" { 40 g.loadBySpecURL() 41 } 42 43 if g.File != "" { 44 g.loadByFile() 45 } 46 } 47 48 func (g *ClientGenerator) loadByFile() { 49 data, err := ioutil.ReadFile(g.File) 50 if err != nil { 51 panic(err) 52 } 53 54 g.swagger, g.openAPI, g.statusErrCodeMap = bytesToSwaggerOrOpenAPI(data) 55 } 56 57 func (g *ClientGenerator) loadBySpecURL() { 58 hc := http.Client{} 59 req, err := http.NewRequest("GET", g.SpecURL, nil) 60 if err != nil { 61 panic(err) 62 } 63 64 resp, err := hc.Do(req) 65 if err != nil { 66 panic(err) 67 } 68 69 bodyBytes, err := ioutil.ReadAll(resp.Body) 70 if err != nil { 71 panic(err) 72 } 73 74 g.swagger, g.openAPI, g.statusErrCodeMap = bytesToSwaggerOrOpenAPI(bodyBytes) 75 if g.ServiceName == "" { 76 g.ServiceName = getIdFromUrl(g.SpecURL) 77 } 78 } 79 80 func bytesToSwaggerOrOpenAPI(data []byte) (*spec.Swagger, *oas.OpenAPI, status_error.StatusErrorCodeMap) { 81 checker := struct { 82 OpenAPI string `json:"openapi"` 83 }{} 84 85 err := json.Unmarshal(data, &checker) 86 if err != nil { 87 panic(err) 88 } 89 90 data = bytes.Replace(data, []byte("golib/timelib"), []byte("github.com/johnnyeven/libtools/timelib"), -1) 91 data = bytes.Replace(data, []byte("golib/httplib"), []byte("github.com/johnnyeven/libtools/httplib"), -1) 92 93 statusErrCodeMap := status_error.StatusErrorCodeMap{} 94 95 regexp.MustCompile("@httpError[^;]+;").ReplaceAllFunc(data, func(i []byte) []byte { 96 v := bytes.Replace(i, []byte(`\"`), []byte(`"`), -1) 97 s := status_error.ParseString(string(v)) 98 statusErrCodeMap[s.Code] = *s 99 return i 100 }) 101 102 if checker.OpenAPI == "" { 103 swagger := new(spec.Swagger) 104 105 err := json.Unmarshal(data, swagger) 106 if err != nil { 107 panic(err) 108 } 109 110 return swagger, nil, statusErrCodeMap 111 } 112 113 openAPI := new(oas.OpenAPI) 114 115 err = json.Unmarshal(data, openAPI) 116 if err != nil { 117 panic(err) 118 } 119 120 return nil, openAPI, statusErrCodeMap 121 } 122 123 func getIdFromUrl(url string) string { 124 paths := strings.Split(url, "/") 125 return paths[len(paths)-1] 126 } 127 128 func (g *ClientGenerator) Pick() { 129 } 130 131 func (g *ClientGenerator) Output(cwd string) codegen.Outputs { 132 outputs := codegen.Outputs{} 133 pkgName := codegen.ToLowerSnakeCase("Client-" + g.ServiceName) 134 135 if g.swagger != nil { 136 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "client.go")), v2.ToClient(g.BaseClient, g.ServiceName, g.swagger)) 137 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "types.go")), v2.ToTypes(g.ServiceName, pkgName, g.swagger)) 138 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "enums.go")), enums.ToEnums(g.ServiceName, pkgName)) 139 } 140 141 if g.openAPI != nil { 142 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "client.go")), v3.ToClient(g.BaseClient, g.ServiceName, g.openAPI)) 143 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "types.go")), v3.ToTypes(g.ServiceName, pkgName, g.openAPI)) 144 outputs.Add(codegen.GeneratedSuffix(path.Join(pkgName, "enums.go")), enums.ToEnums(g.ServiceName, pkgName)) 145 } 146 147 return outputs 148 }