diff --git a/example/user.api b/example/user.api index 2b1409c..4a1bf59 100644 --- a/example/user.api +++ b/example/user.api @@ -36,6 +36,11 @@ type ( UserSearchReq { KeyWord string `form:"keyWord"` // 关键词 } + + ErrorResponse { + Code string `json:"code"` + Message string `json:"message"` + } ) @server( @@ -59,6 +64,13 @@ service user-api { summary: 获取用户信息 ) @handler getUserInfo + /* + @respdoc-400 ( + 100101: out of authority + 100102: user not exist + ) // Error code list + */ + /* @respdoc-500 (ErrorResponse) // Server Error */ get /user/:id (UserInfoReq) returns (UserInfoReply) @doc( diff --git a/example/user.json b/example/user.json index 77486f6..5ab1adf 100644 --- a/example/user.json +++ b/example/user.json @@ -103,6 +103,18 @@ "schema": { "$ref": "#/definitions/UserInfoReply" } + }, + "400": { + "description": "Error code list", + "schema": { + "example": "{\"100101\":\"out of authority\",\"100102\":\"user not exist\"}" + } + }, + "500": { + "description": "Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } } }, "parameters": [ @@ -120,6 +132,22 @@ } }, "definitions": { + "ErrorResponse": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "title": "ErrorResponse", + "required": [ + "code", + "message" + ] + }, "LoginReq": { "type": "object", "properties": { diff --git a/generate/parser.go b/generate/parser.go index 478ff34..843a231 100644 --- a/generate/parser.go +++ b/generate/parser.go @@ -2,6 +2,7 @@ package generate import ( "bytes" + "encoding/json" "fmt" "net/http" "reflect" @@ -26,6 +27,7 @@ const ( exampleOption = "example" optionSeparator = "|" equalToken = "=" + atRespDoc = "@respdoc-" ) func parseRangeOption(option string) (float64, float64, bool) { @@ -285,6 +287,52 @@ func renderServiceRoutes(service spec.Service, groups []spec.Group, paths swagge }, } + for _, v := range route.Doc { + markerIndex := strings.Index(v, atRespDoc) + if markerIndex >= 0 { + l := strings.Index(v, "(") + r := strings.Index(v, ")") + code := strings.TrimSpace(v[markerIndex+len(atRespDoc) : l]) + var comment string + commentIndex := strings.Index(v, "//") + if commentIndex > 0 { + comment = strings.TrimSpace(strings.Trim(v[commentIndex+2:], "*/")) + } + content := strings.TrimSpace(v[l+1 : r]) + if strings.Index(v, ":") > 0 { + lines := strings.Split(content, "\n") + kv := make(map[string]string, len(lines)) + for _, line := range lines { + sep := strings.Index(line, ":") + key := strings.TrimSpace(line[:sep]) + value := strings.TrimSpace(line[sep+1:]) + kv[key] = value + } + kvByte, err := json.Marshal(kv) + if err != nil { + continue + } + operationObject.Responses[code] = swaggerResponseObject{ + Description: comment, + Schema: swaggerSchemaObject{ + schemaCore: schemaCore{ + Example: string(kvByte), + }, + }, + } + } else if len(content) > 0 { + operationObject.Responses[code] = swaggerResponseObject{ + Description: comment, + Schema: swaggerSchemaObject{ + schemaCore: schemaCore{ + Ref: fmt.Sprintf("#/definitions/%s", content), + }, + }, + } + } + } + } + // set OperationID operationObject.OperationID = route.Handler diff --git a/go.mod b/go.mod index 7f736a3..24874d7 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 + github.com/spf13/cobra v1.5.0 // indirect github.com/urfave/cli/v2 v2.3.0 github.com/zeromicro/go-zero v1.3.0 github.com/zeromicro/go-zero/tools/goctl v1.3.2 diff --git a/go.sum b/go.sum index 8266c04..7a84415 100644 --- a/go.sum +++ b/go.sum @@ -74,8 +74,9 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -218,6 +219,8 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= @@ -322,9 +325,9 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -334,7 +337,10 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/swagtest b/swagtest index e49fbb7..a83422e 100755 Binary files a/swagtest and b/swagtest differ