refactor: replace the go model from custom to the official (#439)

This commit is contained in:
dshyjtdes8888 2024-05-18 20:05:04 +08:00 committed by GitHub
parent 966a635768
commit 1dd9dd449a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 101 additions and 69 deletions

View File

@ -176,10 +176,10 @@ func (o *runOption) preRunE(cmd *cobra.Command, args []string) (err error) {
}
if err == nil {
var swaggerAPI apispec.APIConverage
var swaggerAPI apispec.SwaggerAPI
if o.swaggerURL != "" {
if swaggerAPI, err = apispec.ParseURLToSwagger(o.swaggerURL); err == nil {
o.reportWriter.WithAPIConverage(swaggerAPI)
if swaggerAPI.Swagger, err = apispec.ParseURLToSwagger(o.swaggerURL); err == nil {
o.reportWriter.WithAPIConverage(&swaggerAPI)
}
}
}

6
go.mod
View File

@ -12,6 +12,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/go-logr/logr v1.4.1
github.com/go-logr/zapr v1.3.0
github.com/go-openapi/spec v0.21.0
github.com/gorilla/mux v1.8.1
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0
github.com/h2non/gock v1.2.0
@ -45,6 +46,9 @@ require (
github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect
github.com/cucumber/messages-go/v16 v16.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
@ -56,6 +60,8 @@ require (
github.com/iancoleman/orderedmap v0.3.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/phpdave11/gofpdi v1.0.14-0.20211212211723-1f10f9844311 // indirect

16
go.sum
View File

@ -43,6 +43,14 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@ -93,6 +101,8 @@ github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy77
github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls=
github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -109,6 +119,8 @@ github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161 h1:dSL/ah6za
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161/go.mod h1:QX22v61PxpOfJa4Xug8qzGTbPjclDZFx2j1PlGLknJw=
github.com/linuxsuren/unstructured v0.0.1 h1:ilUA8MUYbR6l9ebo/YPV2bKqlf62bzQursDSE+j00iU=
github.com/linuxsuren/unstructured v0.0.1/go.mod h1:KH6aTj+FegzGBzc1vS6mzZx3/duhTUTEVyW5sO7p4as=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@ -132,8 +144,8 @@ github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57
github.com/prometheus/common v0.50.0/go.mod h1:wHFBCEVWVmHMUpg7pYcOm2QUR/ocQdYSJVQJKnHc3xQ=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/santhosh-tekuri/jsonschema/v3 v3.1.0 h1:levPcBfnazlA1CyCMC3asL/QLZkq9pa8tQZOH513zQw=
github.com/santhosh-tekuri/jsonschema/v3 v3.1.0/go.mod h1:8kzK2TC0k0YjOForaAHdNEa7ik0fokNa2k30BKJ/W7Y=

View File

@ -1384,7 +1384,6 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
@ -1611,6 +1610,7 @@ github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4 h1:BN/Nyn2nWMoqGRA7G7paDNDqTXE30mXGqzzybrfo05w=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=

View File

@ -17,61 +17,72 @@ limitations under the License.
package apispec
import (
"encoding/json"
"github.com/go-openapi/spec"
"io"
"net/http"
"regexp"
"strings"
)
type Swagger struct {
Swagger string `json:"swagger"`
// Paths includes all the API requests.
// The keys is the HTTP request method which as lower-case, for example: get, post.
Paths map[string]map[string]SwaggerAPI `json:"paths"`
Info SwaggerInfo `json:"info"`
}
type SwaggerAPI struct {
OperationId string `json:"operationId"`
Parameters []Parameter `json:"parameters"`
Summary string `json:"summary"`
}
type Parameter struct {
Name string `json:"name"`
// In represents the parameter type, supported values: query, path
In string `json:"in"`
Required bool `json:"required"`
Schema Schema `json:"schema"`
}
type Schema struct {
Type string `json:"type"`
Format string `json:"format"`
}
type SwaggerInfo struct {
Description string `json:"description"`
Title string `json:"title"`
Version string `json:"version"`
}
type APIConverage interface {
HaveAPI(path, method string) (exist bool)
APICount() (count int)
}
type SwaggerAPI struct {
Swagger *spec.Swagger
ApiMap map[string][]string
}
func NewSwaggerAPI(swagger *spec.Swagger) *SwaggerAPI {
return &SwaggerAPI{
Swagger: swagger,
ApiMap: buildAPIMap(swagger),
}
}
func buildAPIMap(swagger *spec.Swagger) map[string][]string {
apiMap := make(map[string][]string)
for path, pathItem := range swagger.Paths.Paths {
var methods []string
if pathItem.Get != nil {
methods = append(methods, "get")
}
if pathItem.Put != nil {
methods = append(methods, "put")
}
if pathItem.Post != nil {
methods = append(methods, "post")
}
if pathItem.Delete != nil {
methods = append(methods, "delete")
}
if pathItem.Options != nil {
methods = append(methods, "options")
}
if pathItem.Head != nil {
methods = append(methods, "head")
}
if pathItem.Patch != nil {
methods = append(methods, "patch")
}
apiMap[path] = methods
}
return apiMap
}
// HaveAPI check if the swagger has the API.
// If the path is /api/v1/names/linuxsuren, then will match /api/v1/names/{name}
func (s *Swagger) HaveAPI(path, method string) (exist bool) {
func (s *SwaggerAPI) HaveAPI(path, method string) (exist bool) {
method = strings.ToLower(method)
for item := range s.Paths {
if matchAPI(path, item) {
for m := range s.Paths[item] {
if strings.ToLower(m) == method {
exist = true
return
for p := range s.ApiMap {
if matchAPI(path, p) {
if methods, ok := s.ApiMap[p]; ok {
for _, m := range methods {
if m == method {
exist = true
return
}
}
}
}
@ -98,22 +109,20 @@ func swaggerAPIConvert(text string) (result string) {
}
// APICount return the count of APIs
func (s *Swagger) APICount() (count int) {
for path := range s.Paths {
for range s.Paths[path] {
count++
}
func (s *SwaggerAPI) APICount() (count int) {
for _, methods := range s.ApiMap {
count += len(methods)
}
return
}
func ParseToSwagger(data []byte) (swagger *Swagger, err error) {
swagger = &Swagger{}
err = json.Unmarshal(data, swagger)
func ParseToSwagger(data []byte) (swagger *spec.Swagger, err error) {
swagger = &spec.Swagger{}
err = swagger.UnmarshalJSON(data)
return
}
func ParseURLToSwagger(swaggerURL string) (swagger *Swagger, err error) {
func ParseURLToSwagger(swaggerURL string) (swagger *spec.Swagger, err error) {
var resp *http.Response
if resp, err = http.Get(swaggerURL); err == nil && resp != nil && resp.StatusCode == http.StatusOK {
swagger, err = ParseStreamToSwagger(resp.Body)
@ -121,7 +130,7 @@ func ParseURLToSwagger(swaggerURL string) (swagger *Swagger, err error) {
return
}
func ParseStreamToSwagger(stream io.Reader) (swagger *Swagger, err error) {
func ParseStreamToSwagger(stream io.Reader) (swagger *spec.Swagger, err error) {
var data []byte
if data, err = io.ReadAll(stream); err == nil {
swagger, err = ParseToSwagger(data)

View File

@ -17,6 +17,7 @@ limitations under the License.
package apispec_test
import (
"github.com/go-openapi/spec"
"net/http"
"testing"
@ -31,18 +32,18 @@ func TestParseURLToSwagger(t *testing.T) {
tests := []struct {
name string
swaggerURL string
verify func(t *testing.T, swagger *apispec.Swagger, err error)
verify func(t *testing.T, swagger *spec.Swagger, err error)
}{{
name: "normal",
swaggerURL: urlFoo,
verify: func(t *testing.T, swagger *apispec.Swagger, err error) {
verify: func(t *testing.T, swagger *spec.Swagger, err error) {
assert.NoError(t, err)
assert.Equal(t, "2.0", swagger.Swagger)
assert.Equal(t, apispec.SwaggerInfo{
assert.Equal(t, spec.InfoProps{
Description: "sample",
Title: "sample",
Version: "1.0.0",
}, swagger.Info)
}, swagger.Info.InfoProps)
},
}}
for _, tt := range tests {
@ -93,8 +94,9 @@ func TestHaveAPI(t *testing.T) {
defer gock.Off()
swagger, err := apispec.ParseURLToSwagger(tt.swaggerURL)
swaggerAPI := apispec.NewSwaggerAPI(swagger)
assert.NoError(t, err)
exist := swagger.HaveAPI(tt.path, tt.method)
exist := swaggerAPI.HaveAPI(tt.path, tt.method)
assert.Equal(t, tt.expectExist, exist)
})
}
@ -116,8 +118,9 @@ func TestAPICount(t *testing.T) {
defer gock.Off()
swagger, err := apispec.ParseURLToSwagger(tt.swaggerURL)
swaggerAPI := apispec.NewSwaggerAPI(swagger)
assert.NoError(t, err)
count := swagger.APICount()
count := swaggerAPI.APICount()
assert.Equal(t, tt.expectCount, count)
})
}

View File

@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"github.com/go-openapi/spec"
"io"
"net/http"
"strings"
@ -230,13 +231,14 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st
return
}
var swaggerAPI *apispec.Swagger
if swaggerAPI, err = apispec.ParseURLToSwagger(suite.Spec.URL); err == nil && swaggerAPI != nil {
var swagger *spec.Swagger
if swagger, err = apispec.ParseURLToSwagger(suite.Spec.URL); err == nil && swagger != nil {
result = []*testing.TestCase{}
for api, item := range swaggerAPI.Paths {
for method, oper := range item {
swaggerAPI := apispec.NewSwaggerAPI(swagger)
for api, methods := range swaggerAPI.ApiMap {
for _, method := range methods {
testcase := &testing.TestCase{
Name: oper.OperationId,
Name: swagger.ID,
Request: testing.Request{
API: api,
Method: strings.ToUpper(method),
@ -244,7 +246,7 @@ func (r *simpleTestCaseRunner) GetSuggestedAPIs(suite *testing.TestSuite, api st
},
}
for _, param := range oper.Parameters {
for _, param := range swagger.Parameters {
switch param.In {
case "query":
// TODO should have a better way to provide the initial value