├── .gitignore ├── test ├── api │ ├── v1 │ │ ├── no_group.api │ │ ├── swagger.api │ │ ├── book.api │ │ ├── cart.api │ │ └── user.api │ └── someapp.api ├── example │ ├── logic │ │ ├── ping_logic.go │ │ ├── swagger │ │ │ └── swagger_logic.go │ │ ├── book │ │ │ ├── add_book_logic.go │ │ │ ├── get_book_logic.go │ │ │ ├── edit_book_logic.go │ │ │ └── get_book_list_logic.go │ │ └── user │ │ │ ├── add_user_logic.go │ │ │ ├── get_user_logic.go │ │ │ ├── cart │ │ │ ├── add_cart_logic.go │ │ │ ├── get_cart_logic.go │ │ │ ├── edit_cart_logic.go │ │ │ └── get_cart_list_logic.go │ │ │ ├── edit_user_logic.go │ │ │ └── get_user_list_logic.go │ ├── middleware │ │ ├── auth_middleware.go │ │ ├── cors_middleware.go │ │ ├── some_middleware.go │ │ └── jwt_option_middleware.go │ ├── routes │ │ ├── routes.go │ │ ├── swagger │ │ │ └── routes.go │ │ ├── user │ │ │ ├── routes.go │ │ │ └── cart │ │ │ │ └── routes.go │ │ ├── setup.go │ │ └── book │ │ │ └── routes.go │ ├── etc │ │ ├── someapp-dev.yaml │ │ ├── someapp-local.yaml │ │ └── someapp-prod.yaml │ ├── handler │ │ ├── ping_handle.go │ │ ├── swagger │ │ │ └── swagger_handle.go │ │ ├── book │ │ │ ├── add_book_handle.go │ │ │ ├── get_book_handle.go │ │ │ ├── edit_book_handle.go │ │ │ └── get_book_list_handle.go │ │ └── user │ │ │ ├── cart │ │ │ ├── add_cart_handle.go │ │ │ ├── edit_cart_handle.go │ │ │ ├── get_cart_handle.go │ │ │ └── get_cart_list_handle.go │ │ │ ├── add_user_handle.go │ │ │ ├── get_user_handle.go │ │ │ ├── edit_user_handle.go │ │ │ └── get_user_list_handle.go │ ├── config │ │ └── config.go │ ├── someapp.go │ ├── svc │ │ └── svc_context.go │ ├── internal │ │ ├── response │ │ │ └── response.go │ │ └── translator │ │ │ └── i18n.go │ └── types │ │ └── types.go └── gengin_test.go ├── main.go ├── tpl ├── types.tpl ├── middleware.tpl ├── etc.tpl ├── routes_setup.tpl ├── logic.tpl ├── config.tpl ├── routes.tpl ├── main.tpl ├── handler.tpl ├── svc_context.tpl ├── template.go ├── response.tpl └── i18n.tpl ├── generator ├── vars.go ├── gen_config.go ├── gen_i18n.go ├── gen_svc_context.go ├── gen_response.go ├── gen_main.go ├── gen_etc.go ├── gen_middleware.go ├── gen_logic.go ├── gen_handlers.go ├── generator.go ├── gen_routes.go └── gen_types.go ├── go.mod ├── LICENSE ├── cmd └── root.go ├── prepare └── prepare.go ├── pkg └── parse_query.go ├── README.md └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | genginv2* 3 | -------------------------------------------------------------------------------- /test/api/v1/no_group.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | 4 | service someapp { 5 | @doc "无Group信息" 6 | @handler ping 7 | get /ping 8 | } -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/cmd" 5 | ) 6 | 7 | func main() { 8 | cmd.Execute() 9 | } 10 | -------------------------------------------------------------------------------- /tpl/types.tpl: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package types 3 | 4 | {{if .hasFile}}import "mime/multipart"{{end}} 5 | 6 | {{.types}} 7 | -------------------------------------------------------------------------------- /generator/vars.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | const ( 4 | fileNameStyle = "go_zero" 5 | dirStyle = "go/zero" 6 | 7 | groupProperty = "group" 8 | ) 9 | -------------------------------------------------------------------------------- /test/api/v1/swagger.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | @server( 4 | group: swagger 5 | ) 6 | 7 | 8 | service someapp { 9 | @handler swagger 10 | get /swagger 11 | } 12 | -------------------------------------------------------------------------------- /test/api/someapp.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | info( 4 | title: "some app" 5 | baseapi: "" 6 | ) 7 | 8 | import ( 9 | "v1/user.api" 10 | "v1/book.api" 11 | "v1/swagger.api" 12 | "v1/cart.api" 13 | "v1/no_group.api" 14 | ) 15 | -------------------------------------------------------------------------------- /generator/gen_config.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/tpl" 5 | ) 6 | 7 | func GenConfig() error { 8 | return GenFile( 9 | "config.go", 10 | tpl.ConfigTemplate, 11 | WithSubDir("config"), 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /generator/gen_i18n.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/tpl" 5 | ) 6 | 7 | func GenI18N() error { 8 | return GenFile( 9 | "i18n.go", 10 | tpl.I18nTemplate, 11 | WithSubDir("internal/translator"), 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /generator/gen_svc_context.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/tpl" 5 | ) 6 | 7 | func GenSvcContext() error { 8 | return GenFile( 9 | "svc_context.go", 10 | tpl.SvcContextTemplate, 11 | WithSubDir("svc"), 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/ping_logic.go: -------------------------------------------------------------------------------- 1 | package logic 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | ) 6 | 7 | // Ping 无Group信息 8 | func Ping(ctx *svc.ServiceContext) error { 9 | // todo: add your logic here and delete this line 10 | 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /test/example/logic/swagger/swagger_logic.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | ) 6 | 7 | // Swagger 8 | func Swagger(ctx *svc.ServiceContext) error { 9 | // todo: add your logic here and delete this line 10 | 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /tpl/middleware.tpl: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | 8 | func {{.name}}(c *gin.Context) { 9 | // TODO generate middleware implement function, delete after code implementation 10 | 11 | // Passthrough to next handler if need 12 | c.Next() 13 | } 14 | -------------------------------------------------------------------------------- /test/example/middleware/auth_middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | func AuthMiddleware(c *gin.Context) { 8 | // TODO generate middleware implement function, delete after code implementation 9 | 10 | // Passthrough to next handler if need 11 | c.Next() 12 | } 13 | -------------------------------------------------------------------------------- /test/example/middleware/cors_middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | func CorsMiddleware(c *gin.Context) { 8 | // TODO generate middleware implement function, delete after code implementation 9 | 10 | // Passthrough to next handler if need 11 | c.Next() 12 | } 13 | -------------------------------------------------------------------------------- /test/example/middleware/some_middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | func SomeMiddleware(c *gin.Context) { 8 | // TODO generate middleware implement function, delete after code implementation 9 | 10 | // Passthrough to next handler if need 11 | c.Next() 12 | } 13 | -------------------------------------------------------------------------------- /test/example/routes/routes.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package routes 3 | 4 | import ( 5 | "github.com/MasterJoyHunan/gengin/test/example/handler" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func RegisterRoute(e *gin.Engine) { 11 | g := e.Group("") 12 | g.GET("/ping", handler.PingHandle) 13 | } 14 | -------------------------------------------------------------------------------- /tpl/etc.tpl: -------------------------------------------------------------------------------- 1 | Server: 2 | Name: {{.serviceName}} 3 | Host: {{.host}} 4 | Port: {{.port}} 5 | 6 | Jwt: 7 | Secret: 8 | Expire: 9 | 10 | Log: 11 | Dir: 12 | Level: 13 | 14 | Mysql: 15 | Host: 16 | Port: 17 | User: 18 | Pwd: 19 | Db: 20 | 21 | Redis: 22 | Host: 23 | Port: 24 | User: 25 | Pwd: 26 | Db: -------------------------------------------------------------------------------- /test/example/middleware/jwt_option_middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | func JwtOptionMiddleware(c *gin.Context) { 8 | // TODO generate middleware implement function, delete after code implementation 9 | 10 | // Passthrough to next handler if need 11 | c.Next() 12 | } 13 | -------------------------------------------------------------------------------- /test/example/etc/someapp-dev.yaml: -------------------------------------------------------------------------------- 1 | Server: 2 | Name: someapp 3 | Host: 127.0.0.1 4 | Port: 8888 5 | 6 | Jwt: 7 | Secret: 8 | Expire: 9 | 10 | Log: 11 | Dir: 12 | Level: 13 | 14 | Mysql: 15 | Host: 16 | Port: 17 | User: 18 | Pwd: 19 | Db: 20 | 21 | Redis: 22 | Host: 23 | Port: 24 | User: 25 | Pwd: 26 | Db: -------------------------------------------------------------------------------- /test/example/etc/someapp-local.yaml: -------------------------------------------------------------------------------- 1 | Server: 2 | Name: someapp 3 | Host: 127.0.0.1 4 | Port: 8888 5 | 6 | Jwt: 7 | Secret: 8 | Expire: 9 | 10 | Log: 11 | Dir: 12 | Level: 13 | 14 | Mysql: 15 | Host: 16 | Port: 17 | User: 18 | Pwd: 19 | Db: 20 | 21 | Redis: 22 | Host: 23 | Port: 24 | User: 25 | Pwd: 26 | Db: -------------------------------------------------------------------------------- /test/example/etc/someapp-prod.yaml: -------------------------------------------------------------------------------- 1 | Server: 2 | Name: someapp 3 | Host: 127.0.0.1 4 | Port: 8888 5 | 6 | Jwt: 7 | Secret: 8 | Expire: 9 | 10 | Log: 11 | Dir: 12 | Level: 13 | 14 | Mysql: 15 | Host: 16 | Port: 17 | User: 18 | Pwd: 19 | Db: 20 | 21 | Redis: 22 | Host: 23 | Port: 24 | User: 25 | Pwd: 26 | Db: -------------------------------------------------------------------------------- /test/example/routes/swagger/routes.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package swagger 3 | 4 | import ( 5 | "github.com/MasterJoyHunan/gengin/test/example/handler/swagger" 6 | 7 | "github.com/gin-gonic/gin" 8 | ) 9 | 10 | func RegisterSwaggerRoute(e *gin.Engine) { 11 | g := e.Group("") 12 | g.GET("/swagger", swagger.SwaggerHandle) 13 | } 14 | -------------------------------------------------------------------------------- /generator/gen_response.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/prepare" 5 | "github.com/MasterJoyHunan/gengin/tpl" 6 | ) 7 | 8 | func GenResponse() error { 9 | return GenFile( 10 | "response.go", 11 | tpl.ResponseTemplate, 12 | WithSubDir("internal/response"), 13 | WithData(map[string]string{ 14 | "rootPkg": prepare.RootPkg, 15 | }), 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /test/example/logic/book/add_book_logic.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // AddBook 添加书本信息 9 | func AddBook(ctx *svc.ServiceContext, req *types.BookRequest) (resp types.BookResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/book/get_book_logic.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetBook 获取书本信息 9 | func GetBook(ctx *svc.ServiceContext, req *types.BookRequest) (resp types.BookResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/add_user_logic.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // AddUser 添加用户信息 9 | func AddUser(ctx *svc.ServiceContext, req *types.UserRequest) (resp types.UserResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/get_user_logic.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetUser 获取用户信息 9 | func GetUser(ctx *svc.ServiceContext, req *types.UserRequest) (resp types.UserResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/book/edit_book_logic.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // EditBook 编辑书本信息 9 | func EditBook(ctx *svc.ServiceContext, req *types.BookRequest) (resp types.BookResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/cart/add_cart_logic.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // AddCart 添加购物车信息 9 | func AddCart(ctx *svc.ServiceContext, req *types.CartRequest) (resp types.CartResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/cart/get_cart_logic.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetCart 获取购物车信息 9 | func GetCart(ctx *svc.ServiceContext, req *types.CartRequest) (resp types.CartResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/edit_user_logic.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // EditUser 编辑用户信息 9 | func EditUser(ctx *svc.ServiceContext, req *types.UserRequest) (resp types.UserResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/cart/edit_cart_logic.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // EditCart 编辑购物车信息 9 | func EditCart(ctx *svc.ServiceContext, req *types.CartRequest) (resp types.CartResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/book/get_book_list_logic.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetBookList 获取所有书本信息 9 | func GetBookList(ctx *svc.ServiceContext, req *types.BookRequest) (resp types.BookResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/get_user_list_logic.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetUserList 获取所有用户信息 9 | func GetUserList(ctx *svc.ServiceContext, req *types.UserRequest) (resp types.UserResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /test/example/logic/user/cart/get_cart_list_logic.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/svc" 5 | "github.com/MasterJoyHunan/gengin/test/example/types" 6 | ) 7 | 8 | // GetCartList 获取所有购物车信息 9 | func GetCartList(ctx *svc.ServiceContext, req *types.CartRequest) (resp types.CartResponse, err error) { 10 | // todo: add your logic here and delete this line 11 | 12 | return 13 | } 14 | -------------------------------------------------------------------------------- /tpl/routes_setup.tpl: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package routes 3 | 4 | import ( 5 | {{- range .routes}} 6 | {{if not (eq .pkg "routes")}}{{.alias}} "{{$.rootPkg}}/{{.pkg}}"{{end}} 7 | {{- end}} 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | func Setup(e *gin.Engine) { 13 | {{- range .routes}} 14 | {{if not (eq .base "routes")}}{{.alias}}.{{end}}Register{{.name}}Route(e) 15 | {{- end}} 16 | } 17 | -------------------------------------------------------------------------------- /test/example/handler/ping_handle.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // PingHandle 无Group信息 12 | func PingHandle(c *gin.Context) { 13 | err := logic.Ping(svc.NewServiceContext(c)) 14 | response.HandleResponse(c, nil, err) 15 | } 16 | -------------------------------------------------------------------------------- /tpl/logic.tpl: -------------------------------------------------------------------------------- 1 | package {{.pkgName}} 2 | 3 | import ( 4 | "{{.rootPkg}}/svc" 5 | {{if .needImportTypePkg}}"{{.rootPkg}}/types"{{end}} 6 | ) 7 | 8 | // {{.logicName}} {{.comment}} 9 | func {{.logicName}}(ctx *svc.ServiceContext{{if .hasReq}}, req *types.{{.requestType}}{{end}}) {{if .hasResp}}(resp {{.responseType}}, err error){{else}}error{{end}} { 10 | // todo: add your logic here and delete this line 11 | 12 | {{if .hasResp}}return{{else}}return nil{{end}} 13 | } 14 | -------------------------------------------------------------------------------- /test/example/handler/swagger/swagger_handle.go: -------------------------------------------------------------------------------- 1 | package swagger 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/swagger" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | // SwaggerHandle 12 | func SwaggerHandle(c *gin.Context) { 13 | err := swagger.Swagger(svc.NewServiceContext(c)) 14 | response.HandleResponse(c, nil, err) 15 | } 16 | -------------------------------------------------------------------------------- /test/example/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type Server struct { 4 | Name string 5 | Host string 6 | Port int 7 | } 8 | 9 | type Jwt struct { 10 | Secret string 11 | Expire int 12 | } 13 | 14 | type Log struct { 15 | Dir string 16 | Level string 17 | } 18 | 19 | type Mysql struct { 20 | Host string 21 | Port int 22 | User string 23 | Pwd string 24 | Db string 25 | } 26 | 27 | type Redis struct { 28 | Host string 29 | Port int 30 | User string 31 | Pwd string 32 | Db int 33 | } 34 | -------------------------------------------------------------------------------- /tpl/config.tpl: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type Server struct { 4 | Name string 5 | Host string 6 | Port int 7 | } 8 | 9 | type Jwt struct { 10 | Secret string 11 | Expire int 12 | } 13 | 14 | type Log struct { 15 | Dir string 16 | Level string 17 | } 18 | 19 | type Mysql struct{ 20 | Host string 21 | Port int 22 | User string 23 | Pwd string 24 | Db string 25 | } 26 | 27 | type Redis struct{ 28 | Host string 29 | Port int 30 | User string 31 | Pwd string 32 | Db int 33 | } 34 | -------------------------------------------------------------------------------- /tpl/routes.tpl: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package {{.pkgName}} 3 | 4 | import ( 5 | "{{.rootPkg}}/{{.handlePkg}}" 6 | {{if .hasMiddleware}}"{{.rootPkg}}/middleware"{{end}} 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func Register{{.funcName}}Route(e *gin.Engine) { 12 | g := e.Group("{{if .hasPrefix}}{{.prefix}}{{end}}"){{if .hasMiddleware}} 13 | g.Use({{range .middleware}}middleware.{{.}}, {{end}}){{end}} 14 | {{- range .routes}} 15 | g.{{.method}}("{{.path}}", {{$.handleBase}}.{{.handle}}Handle) 16 | {{- end}} 17 | } 18 | -------------------------------------------------------------------------------- /test/example/routes/user/routes.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package user 3 | 4 | import ( 5 | "github.com/MasterJoyHunan/gengin/test/example/handler/user" 6 | "github.com/MasterJoyHunan/gengin/test/example/middleware" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func RegisterUserRoute(e *gin.Engine) { 12 | g := e.Group("/v1") 13 | g.Use(middleware.AuthMiddleware, middleware.SomeMiddleware) 14 | g.GET("/user", user.GetUserListHandle) 15 | g.GET("/user/:id", user.GetUserHandle) 16 | g.POST("/user", user.AddUserHandle) 17 | g.PUT("/user/:id", user.EditUserHandle) 18 | } 19 | -------------------------------------------------------------------------------- /test/example/routes/user/cart/routes.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package cart 3 | 4 | import ( 5 | "github.com/MasterJoyHunan/gengin/test/example/handler/user/cart" 6 | "github.com/MasterJoyHunan/gengin/test/example/middleware" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func RegisterUserCartRoute(e *gin.Engine) { 12 | g := e.Group("/v1") 13 | g.Use(middleware.AuthMiddleware, middleware.SomeMiddleware, middleware.CorsMiddleware) 14 | g.GET("/cart", cart.GetCartListHandle) 15 | g.GET("/cart/:id", cart.GetCartHandle) 16 | g.POST("/cart", cart.AddCartHandle) 17 | g.PUT("/cart/:id", cart.EditCartHandle) 18 | } 19 | -------------------------------------------------------------------------------- /test/example/routes/setup.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package routes 3 | 4 | import ( 5 | book "github.com/MasterJoyHunan/gengin/test/example/routes/book" 6 | swagger "github.com/MasterJoyHunan/gengin/test/example/routes/swagger" 7 | user "github.com/MasterJoyHunan/gengin/test/example/routes/user" 8 | userCart "github.com/MasterJoyHunan/gengin/test/example/routes/user/cart" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | func Setup(e *gin.Engine) { 14 | user.RegisterUserRoute(e) 15 | book.RegisterBookRoute(e) 16 | swagger.RegisterSwaggerRoute(e) 17 | userCart.RegisterUserCartRoute(e) 18 | RegisterRoute(e) 19 | } 20 | -------------------------------------------------------------------------------- /tpl/main.tpl: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "net/http" 7 | 8 | "{{.rootPkg}}/routes" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | var release string 14 | 15 | func init() { 16 | flag.StringVar(&release, "release", "local", "release model, optional local/dev/prod") 17 | } 18 | 19 | func main() { 20 | flag.Parse() 21 | 22 | // configFile := fmt.Sprintf("etc/{{.configName}}-%s.yaml", release) 23 | 24 | e := gin.Default() 25 | 26 | routes.Setup(e) 27 | 28 | server := http.Server{ 29 | Addr: fmt.Sprintf("%s:%d", "{{.host}}", {{.port}}), 30 | Handler: e, 31 | } 32 | 33 | server.ListenAndServe() 34 | } 35 | -------------------------------------------------------------------------------- /test/example/routes/book/routes.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package book 3 | 4 | import ( 5 | "github.com/MasterJoyHunan/gengin/test/example/handler/book" 6 | "github.com/MasterJoyHunan/gengin/test/example/middleware" 7 | 8 | "github.com/gin-gonic/gin" 9 | ) 10 | 11 | func RegisterBookRoute(e *gin.Engine) { 12 | g := e.Group("/v1") 13 | g.Use(middleware.AuthMiddleware, middleware.SomeMiddleware, middleware.CorsMiddleware, middleware.JwtOptionMiddleware) 14 | g.GET("/book", book.GetBookListHandle) 15 | g.GET("/book/:id", book.GetBookHandle) 16 | g.POST("/book", book.AddBookHandle) 17 | g.PUT("/book/:id", book.EditBookHandle) 18 | } 19 | -------------------------------------------------------------------------------- /generator/gen_main.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/prepare" 5 | "github.com/MasterJoyHunan/gengin/tpl" 6 | 7 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 8 | ) 9 | 10 | func GenMain() error { 11 | filename, err := format.FileNamingFormat(fileNameStyle, prepare.ApiSpec.Service.Name) 12 | if err != nil { 13 | return err 14 | } 15 | 16 | return GenFile( 17 | filename+".go", 18 | tpl.MainTemplate, 19 | WithData(map[string]interface{}{ 20 | "rootPkg": prepare.RootPkg, 21 | "configName": filename, 22 | "host": defaultHost, 23 | "port": defaultPort, 24 | }), 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /tpl/handler.tpl: -------------------------------------------------------------------------------- 1 | package {{.pkgName}} 2 | 3 | import ( 4 | {{if .hasReq}}"{{.rootPkg}}/types"{{end}} 5 | "{{.rootPkg}}/{{.logicPkg}}" 6 | "{{.rootPkg}}/svc" 7 | "{{.rootPkg}}/internal/response" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // {{.handlerName}}Handle {{.comment}} 13 | func {{.handlerName}}Handle(c *gin.Context) { 14 | {{- if .hasReq -}} 15 | var req types.{{.requestType}} 16 | {{.parseRequest}} 17 | {{- end -}} 18 | {{if .hasResp}}resp, {{end}}err := {{.logicBase}}.{{.handlerName}}(svc.NewServiceContext(c), {{if .hasReq}}&req{{end}}) 19 | response.HandleResponse(c, {{if .hasResp}}resp{{else}}nil{{end}}, err) 20 | } 21 | -------------------------------------------------------------------------------- /test/example/someapp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/MasterJoyHunan/gengin/test/example/routes" 9 | 10 | "github.com/gin-gonic/gin" 11 | ) 12 | 13 | var release string 14 | 15 | func init() { 16 | flag.StringVar(&release, "release", "local", "release model, optional local/dev/prod") 17 | } 18 | 19 | func main() { 20 | flag.Parse() 21 | 22 | // configFile := fmt.Sprintf("etc/someapp-%s.yaml", release) 23 | 24 | e := gin.Default() 25 | 26 | routes.Setup(e) 27 | 28 | server := http.Server{ 29 | Addr: fmt.Sprintf("%s:%d", "127.0.0.1", 8888), 30 | Handler: e, 31 | } 32 | 33 | server.ListenAndServe() 34 | } 35 | -------------------------------------------------------------------------------- /test/example/handler/book/add_book_handle.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/book" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // AddBookHandle 添加书本信息 13 | func AddBookHandle(c *gin.Context) { 14 | var req types.BookRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := book.AddBook(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/book/get_book_handle.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/book" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetBookHandle 获取书本信息 13 | func GetBookHandle(c *gin.Context) { 14 | var req types.BookRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := book.GetBook(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/book/edit_book_handle.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/book" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // EditBookHandle 编辑书本信息 13 | func EditBookHandle(c *gin.Context) { 14 | var req types.BookRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := book.EditBook(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/user/cart/add_cart_handle.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user/cart" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // AddCartHandle 添加购物车信息 13 | func AddCartHandle(c *gin.Context) { 14 | var req types.CartRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := cart.AddCart(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/user/cart/edit_cart_handle.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user/cart" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // EditCartHandle 编辑购物车信息 13 | func EditCartHandle(c *gin.Context) { 14 | var req types.CartRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := cart.EditCart(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/user/cart/get_cart_handle.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user/cart" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetCartHandle 获取购物车信息 13 | func GetCartHandle(c *gin.Context) { 14 | var req types.CartRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := cart.GetCart(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/MasterJoyHunan/gengin 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/samber/lo v1.39.0 7 | github.com/spf13/cobra v1.4.0 8 | github.com/zeromicro/go-zero/tools/goctl v1.3.8 9 | golang.org/x/text v0.15.0 10 | ) 11 | 12 | require ( 13 | github.com/fatih/structtag v1.2.0 // indirect 14 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 15 | github.com/logrusorgru/aurora v2.0.3+incompatible // indirect 16 | github.com/spf13/pflag v1.0.5 // indirect 17 | github.com/stretchr/testify v1.9.0 // indirect 18 | github.com/zeromicro/antlr v0.0.1 // indirect 19 | github.com/zeromicro/go-zero v1.3.2 // indirect 20 | golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect 21 | ) 22 | -------------------------------------------------------------------------------- /test/example/handler/book/get_book_list_handle.go: -------------------------------------------------------------------------------- 1 | package book 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/book" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetBookListHandle 获取所有书本信息 13 | func GetBookListHandle(c *gin.Context) { 14 | var req types.BookRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := book.GetBookList(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/handler/user/cart/get_cart_list_handle.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user/cart" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetCartListHandle 获取所有购物车信息 13 | func GetCartListHandle(c *gin.Context) { 14 | var req types.CartRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | resp, err := cart.GetCartList(svc.NewServiceContext(c), &req) 20 | response.HandleResponse(c, resp, err) 21 | } 22 | -------------------------------------------------------------------------------- /test/example/svc/svc_context.go: -------------------------------------------------------------------------------- 1 | package svc 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // ServiceContext 实现 context.Context 接口 10 | type ServiceContext struct { 11 | GinContext *gin.Context 12 | } 13 | 14 | func NewServiceContext(c *gin.Context) *ServiceContext { 15 | return &ServiceContext{ 16 | GinContext: c, 17 | } 18 | } 19 | 20 | func (c *ServiceContext) Deadline() (deadline time.Time, ok bool) { 21 | return c.GinContext.Deadline() 22 | } 23 | 24 | func (c *ServiceContext) Done() <-chan struct{} { 25 | return c.GinContext.Done() 26 | } 27 | 28 | func (c *ServiceContext) Err() error { 29 | return c.GinContext.Err() 30 | } 31 | 32 | func (c *ServiceContext) Value(key any) any { 33 | return c.GinContext.Value(key) 34 | } 35 | -------------------------------------------------------------------------------- /tpl/svc_context.tpl: -------------------------------------------------------------------------------- 1 | package svc 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // ServiceContext 实现 context.Context 接口 10 | type ServiceContext struct { 11 | GinContext *gin.Context 12 | } 13 | 14 | func NewServiceContext(c *gin.Context) *ServiceContext { 15 | return &ServiceContext{ 16 | GinContext: c, 17 | } 18 | } 19 | 20 | func (c *ServiceContext) Deadline() (deadline time.Time, ok bool) { 21 | return c.GinContext.Deadline() 22 | } 23 | 24 | func (c *ServiceContext) Done() <-chan struct{} { 25 | return c.GinContext.Done() 26 | } 27 | 28 | func (c *ServiceContext) Err() error { 29 | return c.GinContext.Err() 30 | } 31 | 32 | func (c *ServiceContext) Value(key any) any { 33 | return c.GinContext.Value(key) 34 | } 35 | -------------------------------------------------------------------------------- /test/example/handler/user/add_user_handle.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // AddUserHandle 添加用户信息 13 | func AddUserHandle(c *gin.Context) { 14 | var req types.UserRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | if err := c.ShouldBindUri(&req); err != nil { 20 | response.HandleResponse(c, nil, err) 21 | return 22 | } 23 | resp, err := user.AddUser(svc.NewServiceContext(c), &req) 24 | response.HandleResponse(c, resp, err) 25 | } 26 | -------------------------------------------------------------------------------- /test/example/handler/user/get_user_handle.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetUserHandle 获取用户信息 13 | func GetUserHandle(c *gin.Context) { 14 | var req types.UserRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | if err := c.ShouldBindUri(&req); err != nil { 20 | response.HandleResponse(c, nil, err) 21 | return 22 | } 23 | resp, err := user.GetUser(svc.NewServiceContext(c), &req) 24 | response.HandleResponse(c, resp, err) 25 | } 26 | -------------------------------------------------------------------------------- /tpl/template.go: -------------------------------------------------------------------------------- 1 | package tpl 2 | 3 | import _ "embed" 4 | 5 | var ( 6 | //go:embed etc.tpl 7 | EtcTemplate string 8 | 9 | //go:embed config.tpl 10 | ConfigTemplate string 11 | 12 | //go:embed svc_context.tpl 13 | SvcContextTemplate string 14 | 15 | //go:embed main.tpl 16 | MainTemplate string 17 | 18 | //go:embed middleware.tpl 19 | MiddlewareTemplate string 20 | 21 | //go:embed types.tpl 22 | TypesTemplate string 23 | 24 | //go:embed logic.tpl 25 | LogicTemplate string 26 | 27 | //go:embed routes.tpl 28 | RoutesTemplate string 29 | 30 | //go:embed routes_setup.tpl 31 | RoutesSetupTemplate string 32 | 33 | //go:embed handler.tpl 34 | HandlerTemplate string 35 | 36 | //go:embed response.tpl 37 | ResponseTemplate string 38 | 39 | //go:embed i18n.tpl 40 | I18nTemplate string 41 | ) 42 | -------------------------------------------------------------------------------- /test/example/handler/user/edit_user_handle.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // EditUserHandle 编辑用户信息 13 | func EditUserHandle(c *gin.Context) { 14 | var req types.UserRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | if err := c.ShouldBindUri(&req); err != nil { 20 | response.HandleResponse(c, nil, err) 21 | return 22 | } 23 | resp, err := user.EditUser(svc.NewServiceContext(c), &req) 24 | response.HandleResponse(c, resp, err) 25 | } 26 | -------------------------------------------------------------------------------- /test/example/handler/user/get_user_list_handle.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/response" 5 | "github.com/MasterJoyHunan/gengin/test/example/logic/user" 6 | "github.com/MasterJoyHunan/gengin/test/example/svc" 7 | "github.com/MasterJoyHunan/gengin/test/example/types" 8 | 9 | "github.com/gin-gonic/gin" 10 | ) 11 | 12 | // GetUserListHandle 获取所有用户信息 13 | func GetUserListHandle(c *gin.Context) { 14 | var req types.UserRequest 15 | if err := c.ShouldBind(&req); err != nil { 16 | response.HandleResponse(c, nil, err) 17 | return 18 | } 19 | if err := c.ShouldBindUri(&req); err != nil { 20 | response.HandleResponse(c, nil, err) 21 | return 22 | } 23 | resp, err := user.GetUserList(svc.NewServiceContext(c), &req) 24 | response.HandleResponse(c, resp, err) 25 | } 26 | -------------------------------------------------------------------------------- /test/api/v1/book.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | type bookRequest { 4 | Name string `json:"name"` // 姓名 5 | Age int `json:"age"` // 年龄 6 | } 7 | 8 | type bookResponse { 9 | Code int `json:"code"` // 业务码 10 | Msg string `json:"msg"` // 业务消息 11 | } 12 | 13 | @server( 14 | jwt: Auth 15 | group: book 16 | middleware: SomeMiddleware,CorsMiddleware,JwtOption 17 | prefix: /v1 18 | swtags: "书本" 19 | ) 20 | 21 | service someapp { 22 | @doc "获取所有书本信息" 23 | @handler getBookList 24 | get /book (bookRequest) returns (bookResponse) 25 | 26 | @doc "获取书本信息" 27 | @handler getBook 28 | get /book/:id (bookRequest) returns (bookResponse) 29 | 30 | @doc "添加书本信息" 31 | @handler addBook 32 | post /book (bookRequest) returns (bookResponse) 33 | 34 | @doc "编辑书本信息" 35 | @handler editBook 36 | put /book/:id (bookRequest) returns (bookResponse) 37 | } -------------------------------------------------------------------------------- /test/api/v1/cart.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | type cartRequest struct { 4 | Name string `json:"name"` // 姓名 5 | Age int `json:"age"` // 年龄 6 | } 7 | 8 | 9 | type cartResponse struct { 10 | Name string `json:"name"` // 姓名 11 | Age int `json:"age"` // 年龄 12 | } 13 | 14 | 15 | 16 | @server( 17 | jwt: Auth 18 | group: userCart 19 | middleware: SomeMiddleware,CorsMiddleware 20 | prefix: /v1 21 | swtags: "购物车" 22 | ) 23 | 24 | service someapp { 25 | @doc "获取所有购物车信息" 26 | @handler getCartList 27 | get /cart (cartRequest) returns (cartResponse) 28 | 29 | @doc "获取购物车信息" 30 | @handler getCart 31 | get /cart/:id (cartRequest) returns (cartResponse) 32 | 33 | @doc "添加购物车信息" 34 | @handler addCart 35 | post /cart (cartRequest) returns (cartResponse) 36 | 37 | @doc "编辑购物车信息" 38 | @handler editCart 39 | put /cart/:id (cartRequest) returns (cartResponse) 40 | } -------------------------------------------------------------------------------- /test/example/internal/response/response.go: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import ( 4 | "github.com/MasterJoyHunan/gengin/test/example/internal/translator" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // UnifiedResponse 统一返回 10 | type UnifiedResponse struct { 11 | Code int `json:"code"` 12 | Data any `json:"data"` 13 | Message string `json:"message"` 14 | } 15 | 16 | // HandleResponse 统一返回处理 17 | func HandleResponse(c *gin.Context, data any, err error) { 18 | if err != nil { 19 | c.JSON(200, UnifiedResponse{ 20 | Code: 500, 21 | Data: nil, 22 | Message: translator.Translate(err), 23 | }) 24 | return 25 | } 26 | 27 | c.JSON(200, UnifiedResponse{ 28 | Code: 0, 29 | Data: data, 30 | Message: "成功", 31 | }) 32 | } 33 | 34 | // HandleAbortResponse 统一 Abort 返回处理 35 | func HandleAbortResponse(c *gin.Context, err string) { 36 | c.AbortWithStatusJSON(200, UnifiedResponse{ 37 | Code: 500, 38 | Data: nil, 39 | Message: err, 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /generator/gen_etc.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/MasterJoyHunan/gengin/prepare" 8 | "github.com/MasterJoyHunan/gengin/tpl" 9 | 10 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 11 | ) 12 | 13 | const ( 14 | defaultHost = "127.0.0.1" 15 | defaultPort = 8888 16 | devModel = "local|dev|prod" 17 | ) 18 | 19 | func GenEtc() error { 20 | filename, err := format.FileNamingFormat(fileNameStyle, prepare.ApiSpec.Service.Name) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | mode := strings.Split(devModel, "|") 26 | 27 | for _, m := range mode { 28 | err = GenFile( 29 | fmt.Sprintf("%s-%s.yaml", filename, m), 30 | tpl.EtcTemplate, 31 | WithSubDir("etc"), 32 | WithData(map[string]any{ 33 | "serviceName": prepare.ApiSpec.Service.Name, 34 | "host": defaultHost, 35 | "port": defaultPort, 36 | }), 37 | ) 38 | if err != nil { 39 | return err 40 | } 41 | } 42 | 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /tpl/response.tpl: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import ( 4 | "{{.rootPkg}}/internal/translator" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | // UnifiedResponse 统一返回 10 | type UnifiedResponse struct { 11 | Code int `json:"code"` 12 | Data any `json:"data"` 13 | Message string `json:"message"` 14 | } 15 | 16 | // HandleResponse 统一返回处理 17 | func HandleResponse(c *gin.Context, data any, err error) { 18 | if err != nil { 19 | c.JSON(200, UnifiedResponse{ 20 | Code: 500, 21 | Data: nil, 22 | Message: translator.Translate(err), 23 | }) 24 | return 25 | } 26 | 27 | c.JSON(200, UnifiedResponse{ 28 | Code: 0, 29 | Data: data, 30 | Message: "成功", 31 | }) 32 | } 33 | 34 | // HandleAbortResponse 统一 Abort 返回处理 35 | func HandleAbortResponse(c *gin.Context, err string) { 36 | c.AbortWithStatusJSON(200, UnifiedResponse{ 37 | Code: 500, 38 | Data: nil, 39 | Message: err, 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 谭武洋 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/MasterJoyHunan/gengin/generator" 8 | "github.com/MasterJoyHunan/gengin/prepare" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | var ( 13 | rootCmd = &cobra.Command{ 14 | Use: "gengin", 15 | Short: "生成基于 GIN 框架的 WEB 服务的极简项目结构", 16 | Example: "gengin --dir=. some.api", 17 | Args: cobra.ExactValidArgs(1), 18 | RunE: GenGinCode, 19 | } 20 | ) 21 | 22 | func Execute() { 23 | if err := rootCmd.Execute(); err != nil { 24 | fmt.Println(err.Error()) 25 | os.Exit(1) 26 | } 27 | } 28 | 29 | func init() { 30 | rootCmd.Flags().StringVar(&prepare.OutputDir, "dir", ".", "生成项目目录") 31 | } 32 | 33 | func GenGinCode(cmd *cobra.Command, args []string) error { 34 | prepare.ApiFile = args[0] 35 | prepare.Setup() 36 | Must(generator.GenEtc()) 37 | Must(generator.GenConfig()) 38 | Must(generator.GenMain()) 39 | Must(generator.GenMiddleware()) 40 | Must(generator.GenTypes()) 41 | Must(generator.GenLogic()) 42 | Must(generator.GenRoutes()) 43 | Must(generator.GenHandlers()) 44 | Must(generator.GenResponse()) 45 | Must(generator.GenI18N()) 46 | Must(generator.GenSvcContext()) 47 | return nil 48 | } 49 | 50 | func Must(err error) { 51 | if err != nil { 52 | panic(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /prepare/prepare.go: -------------------------------------------------------------------------------- 1 | package prepare 2 | 3 | import ( 4 | "path/filepath" 5 | "strings" 6 | 7 | "github.com/zeromicro/go-zero/tools/goctl/api/parser" 8 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 9 | "github.com/zeromicro/go-zero/tools/goctl/util/ctx" 10 | "github.com/zeromicro/go-zero/tools/goctl/util/pathx" 11 | ) 12 | 13 | var ( 14 | ApiSpec *spec.ApiSpec 15 | RootPkg string 16 | OutputDir string 17 | ApiFile string 18 | ) 19 | 20 | func Setup() { 21 | var err error 22 | ApiSpec, err = parser.Parse(ApiFile) 23 | if err != nil { 24 | panic(err) 25 | } 26 | 27 | if err = ApiSpec.Validate(); err != nil { 28 | panic(err) 29 | } 30 | 31 | RootPkg, err = GetParentPackage(OutputDir) 32 | if err != nil { 33 | panic(err) 34 | } 35 | } 36 | 37 | func GetParentPackage(dir string) (string, error) { 38 | abs, err := filepath.Abs(dir) 39 | if err != nil { 40 | return "", err 41 | } 42 | 43 | projectCtx, err := ctx.Prepare(abs) 44 | if err != nil { 45 | return "", err 46 | } 47 | 48 | wd := projectCtx.WorkDir 49 | d := projectCtx.Dir 50 | same, err := pathx.SameFile(wd, d) 51 | if err != nil { 52 | return "", err 53 | } 54 | 55 | trim := strings.TrimPrefix(projectCtx.WorkDir, projectCtx.Dir) 56 | if same { 57 | trim = strings.TrimPrefix(strings.ToLower(projectCtx.WorkDir), strings.ToLower(projectCtx.Dir)) 58 | } 59 | 60 | return filepath.ToSlash(filepath.Join(projectCtx.Path, trim)), nil 61 | } 62 | -------------------------------------------------------------------------------- /test/api/v1/user.api: -------------------------------------------------------------------------------- 1 | syntax = "v1" 2 | 3 | type userRequest { 4 | Name string `path:"name"` // 姓名 5 | Age int `json:"age"` 6 | embed1 []Embed1 `json:"em1"` // xs 7 | embed2 Embed2 `json:"em2"` // dsd 8 | map2 map[string]Value1 `json:"map2"` 9 | } 10 | 11 | type userResponse { 12 | Code int `json:"code"` 13 | Msg string `json:"msg"` 14 | embed1 []Embed1 `json:"em1"` 15 | embed2 Embed2 `json:"em2"` 16 | map1 map[string]string `json:"map1"` // test 17 | map2 map[string]Value1 `json:"map2"` 18 | } 19 | 20 | type Embed1 { 21 | foo int `json:"foo"` // x 22 | Embed3 Embed3 `json:"embed3"` // esc234 23 | } 24 | type Embed2 { 25 | foo int `json:"foo"` // y 26 | } 27 | 28 | type Embed3 { 29 | foo int `json:"foo"` // Embed3 30 | } 31 | 32 | 33 | 34 | type Value1 { 35 | name string `json:"name"` // vads3 36 | } 37 | 38 | 39 | @server( 40 | jwt: Auth 41 | group: user 42 | middleware: someMiddleware 43 | prefix: /v1 44 | swtags: "用户相关" 45 | ) 46 | 47 | 48 | service someapp { 49 | @doc "获取所有用户信息" 50 | @handler getUserList 51 | get /user (userRequest) returns (userResponse) 52 | 53 | @doc "获取用户信息" 54 | @handler getUser 55 | get /user/:id (userRequest) returns (userResponse) 56 | 57 | @doc "添加用户信息" 58 | @handler addUser 59 | post /user (userRequest) returns (userResponse) 60 | 61 | @doc "编辑用户信息" 62 | @handler editUser 63 | put /user/:id (userRequest) returns (userResponse) 64 | 65 | } 66 | -------------------------------------------------------------------------------- /test/example/types/types.go: -------------------------------------------------------------------------------- 1 | // Code generated by goctl. DO NOT EDIT. 2 | package types 3 | 4 | type UserRequest struct { 5 | Name string `uri:"name" label:"姓名"` // 姓名 6 | Age int `json:"age"` 7 | Embed1 []Embed1 `json:"em1" label:"xs"` // xs 8 | Embed2 Embed2 `json:"em2" label:"dsd"` // dsd 9 | Map2 map[string]Value1 `json:"map2"` 10 | } 11 | 12 | type UserResponse struct { 13 | Code int `json:"code"` 14 | Msg string `json:"msg"` 15 | Embed1 []Embed1 `json:"em1"` 16 | Embed2 Embed2 `json:"em2"` 17 | Map1 map[string]string `json:"map1"` // test 18 | Map2 map[string]Value1 `json:"map2"` 19 | } 20 | 21 | type Embed1 struct { 22 | Foo int `json:"foo"` // x 23 | Embed3 Embed3 `json:"embed3"` // esc234 24 | } 25 | 26 | type Embed2 struct { 27 | Foo int `json:"foo"` // y 28 | } 29 | 30 | type Embed3 struct { 31 | Foo int `json:"foo"` // Embed3 32 | } 33 | 34 | type Value1 struct { 35 | Name string `json:"name"` // vads3 36 | } 37 | 38 | type BookRequest struct { 39 | Name string `json:"name" label:"姓名"` // 姓名 40 | Age int `json:"age" label:"年龄"` // 年龄 41 | } 42 | 43 | type BookResponse struct { 44 | Code int `json:"code"` // 业务码 45 | Msg string `json:"msg"` // 业务消息 46 | } 47 | 48 | type CartRequest struct { 49 | Name string `json:"name" label:"姓名"` // 姓名 50 | Age int `json:"age" label:"年龄"` // 年龄 51 | } 52 | 53 | type CartResponse struct { 54 | Name string `json:"name"` // 姓名 55 | Age int `json:"age"` // 年龄 56 | } 57 | -------------------------------------------------------------------------------- /generator/gen_middleware.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/MasterJoyHunan/gengin/prepare" 7 | "github.com/MasterJoyHunan/gengin/tpl" 8 | "github.com/samber/lo" 9 | "golang.org/x/text/cases" 10 | "golang.org/x/text/language" 11 | 12 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 13 | ) 14 | 15 | func GenMiddleware() error { 16 | middlewares := getMiddlewares() 17 | for _, item := range middlewares { 18 | middlewareName, err := format.FileNamingFormat(fileNameStyle, item) 19 | if err != nil { 20 | return err 21 | } 22 | filename := strings.TrimSuffix(strings.TrimSuffix(strings.ToLower(middlewareName), "middleware"), "_") + "_middleware" 23 | 24 | name := strings.TrimSuffix(item, "Middleware") + "Middleware" 25 | 26 | err = GenFile( 27 | filename+".go", 28 | tpl.MiddlewareTemplate, 29 | WithSubDir("middleware"), 30 | WithData(map[string]string{ 31 | "name": cases.Title(language.English, cases.NoLower).String(name), 32 | }), 33 | ) 34 | if err != nil { 35 | return err 36 | } 37 | } 38 | 39 | return nil 40 | } 41 | 42 | func getMiddlewares() []string { 43 | middlewares := make(map[string]any) 44 | for _, g := range prepare.ApiSpec.Service.Groups { 45 | middleware := g.GetAnnotation("middleware") 46 | if len(middleware) > 0 { 47 | for _, item := range strings.Split(middleware, ",") { 48 | middlewares[strings.TrimSpace(item)] = nil 49 | } 50 | } 51 | jwtMiddleware := g.GetAnnotation("jwt") 52 | if len(jwtMiddleware) > 0 { 53 | middlewares[strings.TrimSpace(jwtMiddleware)] = nil 54 | } 55 | } 56 | 57 | return lo.Keys(middlewares) 58 | } 59 | -------------------------------------------------------------------------------- /tpl/i18n.tpl: -------------------------------------------------------------------------------- 1 | package translator 2 | 3 | import ( 4 | "reflect" 5 | "regexp" 6 | 7 | "github.com/gin-gonic/gin/binding" 8 | "github.com/go-playground/locales/zh" 9 | "github.com/go-playground/universal-translator" 10 | "github.com/go-playground/validator/v10" 11 | zhTranslations "github.com/go-playground/validator/v10/translations/zh" 12 | ) 13 | 14 | var trans ut.Translator 15 | 16 | const labelName = "label" 17 | 18 | func init() { 19 | validate := binding.Validator.Engine().(*validator.Validate) 20 | uni := ut.New(zh.New()) 21 | trans, _ = uni.GetTranslator("zh") 22 | 23 | validate.RegisterTagNameFunc(func(field reflect.StructField) string { 24 | label := field.Tag.Get(labelName) 25 | if label == "" { 26 | return field.Name 27 | } 28 | return label 29 | }) 30 | customError(validate) 31 | _ = zhTranslations.RegisterDefaultTranslations(validate, trans) 32 | } 33 | 34 | // Translate 校验异常 35 | func Translate(errs error) string { 36 | errors, ok := errs.(validator.ValidationErrors) 37 | if !ok { 38 | return errs.Error() 39 | } 40 | return errors[0].Translate(trans) 41 | } 42 | 43 | // customError 自定义异常 44 | func customError(validate *validator.Validate) { 45 | validate.RegisterValidation( 46 | "phone", 47 | func(fl validator.FieldLevel) bool { 48 | regular := "^1\\d{2}\\d{8}$" 49 | reg := regexp.MustCompile(regular) 50 | return reg.MatchString(fl.Field().String()) 51 | }) 52 | validate.RegisterTranslation( 53 | "phone", 54 | trans, 55 | func(ut ut.Translator) error { 56 | return ut.Add("phone", "{0}输入错误", false) 57 | }, 58 | func(ut ut.Translator, fe validator.FieldError) string { 59 | t, _ := ut.T(fe.Tag(), fe.Field()) 60 | return t 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /test/example/internal/translator/i18n.go: -------------------------------------------------------------------------------- 1 | package translator 2 | 3 | import ( 4 | "reflect" 5 | "regexp" 6 | 7 | "github.com/gin-gonic/gin/binding" 8 | "github.com/go-playground/locales/zh" 9 | "github.com/go-playground/universal-translator" 10 | "github.com/go-playground/validator/v10" 11 | zhTranslations "github.com/go-playground/validator/v10/translations/zh" 12 | ) 13 | 14 | var trans ut.Translator 15 | 16 | const labelName = "label" 17 | 18 | func init() { 19 | validate := binding.Validator.Engine().(*validator.Validate) 20 | uni := ut.New(zh.New()) 21 | trans, _ = uni.GetTranslator("zh") 22 | 23 | validate.RegisterTagNameFunc(func(field reflect.StructField) string { 24 | label := field.Tag.Get(labelName) 25 | if label == "" { 26 | return field.Name 27 | } 28 | return label 29 | }) 30 | customError(validate) 31 | _ = zhTranslations.RegisterDefaultTranslations(validate, trans) 32 | } 33 | 34 | // Translate 校验异常 35 | func Translate(errs error) string { 36 | errors, ok := errs.(validator.ValidationErrors) 37 | if !ok { 38 | return errs.Error() 39 | } 40 | return errors[0].Translate(trans) 41 | } 42 | 43 | // customError 自定义异常 44 | func customError(validate *validator.Validate) { 45 | validate.RegisterValidation( 46 | "phone", 47 | func(fl validator.FieldLevel) bool { 48 | regular := "^1\\d{2}\\d{8}$" 49 | reg := regexp.MustCompile(regular) 50 | return reg.MatchString(fl.Field().String()) 51 | }) 52 | validate.RegisterTranslation( 53 | "phone", 54 | trans, 55 | func(ut ut.Translator) error { 56 | return ut.Add("phone", "{0}输入错误", false) 57 | }, 58 | func(ut ut.Translator, fe validator.FieldError) string { 59 | t, _ := ut.T(fe.Tag(), fe.Field()) 60 | return t 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /test/gengin_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/MasterJoyHunan/gengin/generator" 7 | "github.com/MasterJoyHunan/gengin/prepare" 8 | ) 9 | 10 | func TestMain(m *testing.M) { 11 | setup() 12 | m.Run() 13 | } 14 | 15 | func TestGenEtc(t *testing.T) { 16 | if err := generator.GenEtc(); err != nil { 17 | t.Failed() 18 | } 19 | } 20 | func TestGenConfig(t *testing.T) { 21 | if err := generator.GenConfig(); err != nil { 22 | t.Failed() 23 | } 24 | } 25 | func TestGenMain(t *testing.T) { 26 | if err := generator.GenMain(); err != nil { 27 | t.Failed() 28 | } 29 | } 30 | func TestGenMiddleware(t *testing.T) { 31 | if err := generator.GenMiddleware(); err != nil { 32 | t.Failed() 33 | } 34 | } 35 | func TestGenTypes(t *testing.T) { 36 | if err := generator.GenTypes(); err != nil { 37 | t.Failed() 38 | } 39 | } 40 | 41 | func TestGenLogic(t *testing.T) { 42 | if err := generator.GenLogic(); err != nil { 43 | t.Failed() 44 | } 45 | } 46 | 47 | func TestGenRoutes(t *testing.T) { 48 | if err := generator.GenRoutes(); err != nil { 49 | t.Failed() 50 | } 51 | } 52 | 53 | func TestGenHandlers(t *testing.T) { 54 | if err := generator.GenHandlers(); err != nil { 55 | t.Failed() 56 | } 57 | } 58 | 59 | func TestGenResponse(t *testing.T) { 60 | if err := generator.GenResponse(); err != nil { 61 | t.Failed() 62 | } 63 | } 64 | 65 | func TestGenI18N(t *testing.T) { 66 | if err := generator.GenI18N(); err != nil { 67 | t.Failed() 68 | } 69 | } 70 | 71 | func TestGenSvcContext(t *testing.T) { 72 | if err := generator.GenSvcContext(); err != nil { 73 | t.Failed() 74 | } 75 | } 76 | 77 | func setup() { 78 | prepare.OutputDir = "example" 79 | prepare.ApiFile = "api/someapp.api" 80 | prepare.Setup() 81 | } 82 | -------------------------------------------------------------------------------- /generator/gen_logic.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | 7 | "github.com/MasterJoyHunan/gengin/prepare" 8 | "github.com/MasterJoyHunan/gengin/tpl" 9 | "golang.org/x/text/cases" 10 | "golang.org/x/text/language" 11 | 12 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 13 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 14 | ) 15 | 16 | func GenLogic() error { 17 | for _, g := range prepare.ApiSpec.Service.Groups { 18 | for _, r := range g.Routes { 19 | err := genLogicByRoute(g, r) 20 | if err != nil { 21 | return err 22 | } 23 | } 24 | } 25 | return nil 26 | } 27 | 28 | func genLogicByRoute(group spec.Group, route spec.Route) error { 29 | logicName, err := format.FileNamingFormat(fileNameStyle, route.Handler) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | logicFileName := strings.TrimSuffix(strings.TrimSuffix(logicName, "logic"), "_") + "_logic.go" 35 | 36 | subDir := group.GetAnnotation(groupProperty) 37 | subDir, err = format.FileNamingFormat(dirStyle, subDir) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | logicPkg := path.Join("logic", subDir) 43 | logicBase := path.Base(logicPkg) 44 | 45 | respIsPrimitiveType, respTypeName := parseResponseType(route.ResponseType) 46 | 47 | return GenFile( 48 | logicFileName, 49 | tpl.LogicTemplate, 50 | WithSubDir(logicPkg), 51 | WithData(map[string]any{ 52 | "rootPkg": prepare.RootPkg, 53 | "pkgName": logicBase, 54 | "comment": parseComment(route), 55 | "logicName": cases.Title(language.English, cases.NoLower).String(route.Handler), 56 | "requestType": cases.Title(language.English, cases.NoLower).String(route.RequestTypeName()), 57 | "responseType": respTypeName, 58 | "needImportTypePkg": len(route.RequestTypeName()) > 0 || (!respIsPrimitiveType && len(route.ResponseTypeName()) > 0), 59 | "hasReq": len(route.RequestTypeName()) > 0, 60 | "hasResp": len(route.ResponseTypeName()) > 0, 61 | }), 62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/parse_query.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 8 | ) 9 | 10 | type ParseRequestBody struct{} 11 | 12 | func (p *ParseRequestBody) BuildParseRequestStr(requestType spec.Type) string { 13 | if requestType == nil { 14 | return "" 15 | } 16 | var sb strings.Builder 17 | sb.WriteString(p.from(requestType)) 18 | sb.WriteString(p.header(requestType)) 19 | sb.WriteString(p.uri(requestType)) 20 | return sb.String() 21 | } 22 | 23 | func (p *ParseRequestBody) header(i spec.Type) string { 24 | if p.hasTag(i, "header") { 25 | return p.returnCode("ShouldBindHeader") 26 | } 27 | return "" 28 | } 29 | 30 | func (p *ParseRequestBody) uri(i spec.Type) string { 31 | if p.hasTag(i, "path") || p.hasTag(i, "uri") { 32 | return p.returnCode("ShouldBindUri") 33 | } 34 | return "" 35 | } 36 | 37 | func (p *ParseRequestBody) from(i spec.Type) string { 38 | if p.hasTag(i, "form") || p.hasTag(i, "json") { 39 | return p.returnCode("ShouldBind") 40 | } 41 | return "" 42 | } 43 | 44 | func (p *ParseRequestBody) hasTag(i spec.Type, needTag string) bool { 45 | switch v := i.(type) { 46 | case spec.DefineStruct: 47 | for _, vv := range v.Members { 48 | before, _, found := strings.Cut(vv.Tag, ":") 49 | if found && strings.HasSuffix(before, needTag) { 50 | return true 51 | } 52 | if p.hasTag(vv.Type, needTag) { 53 | return true 54 | } 55 | } 56 | 57 | //case spec.PrimitiveType: // 内置 58 | 59 | case spec.MapType: 60 | if p.hasTag(v.Value, needTag) { 61 | return true 62 | } 63 | case spec.ArrayType: 64 | if p.hasTag(v.Value, needTag) { 65 | return true 66 | } 67 | //case spec.InterfaceType: 68 | // 不允许 69 | case spec.PointerType: 70 | // 不允许 71 | if p.hasTag(v.Type, needTag) { 72 | return true 73 | } 74 | } 75 | 76 | return false 77 | } 78 | 79 | func (p *ParseRequestBody) returnCode(method string) string { 80 | return fmt.Sprintf(` if err := c.%s(&req); err != nil { 81 | response.HandleResponse(c, nil, err) 82 | return 83 | }`, method) + "\n" 84 | } 85 | -------------------------------------------------------------------------------- /generator/gen_handlers.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | 7 | "github.com/MasterJoyHunan/gengin/pkg" 8 | "github.com/MasterJoyHunan/gengin/prepare" 9 | "github.com/MasterJoyHunan/gengin/tpl" 10 | "golang.org/x/text/cases" 11 | "golang.org/x/text/language" 12 | 13 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 14 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 15 | ) 16 | 17 | func GenHandlers() error { 18 | for _, group := range prepare.ApiSpec.Service.Groups { 19 | for _, r := range group.Routes { 20 | if err := genHandler(group, r); err != nil { 21 | return err 22 | } 23 | } 24 | } 25 | return nil 26 | } 27 | 28 | func genHandler(group spec.Group, route spec.Route) error { 29 | handlerName, err := format.FileNamingFormat(fileNameStyle, route.Handler) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | handlerFileName := strings.TrimSuffix(strings.TrimSuffix(handlerName, "handle"), "_") + "_handle.go" 35 | 36 | subDir := group.GetAnnotation(groupProperty) 37 | subDir, err = format.FileNamingFormat(dirStyle, subDir) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | handlePkg := path.Join("handler", subDir) 43 | logicPkg := path.Join("logic", subDir) 44 | 45 | handleBase := path.Base(handlePkg) 46 | logicBase := path.Base(logicPkg) 47 | 48 | // 解析请求 49 | p := new(pkg.ParseRequestBody) 50 | parseRequest := p.BuildParseRequestStr(route.RequestType) 51 | 52 | return GenFile( 53 | handlerFileName, 54 | tpl.HandlerTemplate, 55 | WithSubDir(handlePkg), 56 | WithData(map[string]any{ 57 | "rootPkg": prepare.RootPkg, 58 | "pkgName": handleBase, 59 | "logicPkg": logicPkg, 60 | "logicBase": logicBase, 61 | "comment": parseComment(route), 62 | "handlerName": cases.Title(language.English, cases.NoLower).String(route.Handler), 63 | "requestType": cases.Title(language.English, cases.NoLower).String(route.RequestTypeName()), 64 | "hasResp": len(route.ResponseTypeName()) > 0, 65 | "hasReq": len(route.RequestTypeName()) > 0, 66 | "parseRequest": parseRequest, 67 | }), 68 | ) 69 | } 70 | -------------------------------------------------------------------------------- /generator/generator.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "bytes" 5 | goformat "go/format" 6 | "os" 7 | "path" 8 | "strings" 9 | "text/template" 10 | 11 | "github.com/MasterJoyHunan/gengin/prepare" 12 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 13 | "golang.org/x/text/cases" 14 | "golang.org/x/text/language" 15 | ) 16 | 17 | type fileGenConfig struct { 18 | dir string 19 | subDir string 20 | filename string 21 | templateName string 22 | templateText string 23 | data any 24 | } 25 | 26 | func GenFile(fileName, templateText string, opt ...Option) error { 27 | templateName, _, _ := strings.Cut(fileName, ".") 28 | 29 | cfg := &fileGenConfig{ 30 | filename: fileName, 31 | templateName: templateName, 32 | templateText: templateText, 33 | } 34 | for _, fn := range opt { 35 | fn(cfg) 36 | } 37 | 38 | if len(cfg.dir) == 0 { 39 | cfg.dir = prepare.OutputDir 40 | } 41 | 42 | filePath := path.Join(cfg.dir, cfg.subDir, cfg.filename) 43 | _, err := os.Stat(filePath) 44 | if err == nil { 45 | // 文件已存在 46 | return nil 47 | } 48 | 49 | err = os.MkdirAll(path.Join(cfg.dir, cfg.subDir), os.ModePerm) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | file, err := os.Create(filePath) 55 | if err != nil { 56 | return err 57 | } 58 | defer file.Close() 59 | 60 | t := template.Must(template.New(cfg.templateName).Parse(cfg.templateText)) 61 | buffer := new(bytes.Buffer) 62 | err = t.Execute(buffer, cfg.data) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | code := formatCode(buffer.String()) 68 | _, err = file.WriteString(code) 69 | 70 | return err 71 | } 72 | 73 | type Option func(*fileGenConfig) 74 | 75 | // WithDir 设置目录 76 | func WithDir(dir string) Option { 77 | return func(config *fileGenConfig) { 78 | config.dir = dir 79 | } 80 | } 81 | 82 | // WithSubDir 设置二级目录 83 | func WithSubDir(dir string) Option { 84 | return func(config *fileGenConfig) { 85 | config.subDir = dir 86 | } 87 | } 88 | 89 | // WithData 设置数据 90 | func WithData(data any) Option { 91 | return func(config *fileGenConfig) { 92 | config.data = data 93 | } 94 | } 95 | 96 | func formatCode(code string) string { 97 | ret, err := goformat.Source([]byte(code)) 98 | if err != nil { 99 | return code 100 | } 101 | 102 | return string(ret) 103 | } 104 | 105 | func parseComment(r spec.Route) string { 106 | if r.AtDoc.Text != "" { 107 | return strings.Trim(r.AtDoc.Text, "\"") 108 | } 109 | if len(r.HandlerDoc) != 0 { 110 | str := "" 111 | for _, d := range r.HandlerDoc { 112 | str += strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(d, "/", ""), "*", ""), "\n", ""), "\t", "") 113 | } 114 | return str 115 | } 116 | return "" 117 | } 118 | 119 | func parseResponseType(t spec.Type) (isPrimitiveType bool, typeName string) { 120 | if t == nil { 121 | return true, "" 122 | } 123 | switch v := t.(type) { 124 | case spec.DefineStruct: 125 | return false, "types." + cases.Title(language.English, cases.NoLower).String(t.Name()) 126 | case spec.PrimitiveType: // 内置 127 | return true, t.Name() 128 | case spec.MapType: 129 | // 不允许 130 | case spec.ArrayType: 131 | isPrimitiveType, typeName = parseResponseType(v.Value) 132 | return isPrimitiveType, "[]" + typeName 133 | case spec.InterfaceType: 134 | // 不允许 135 | case spec.PointerType: 136 | // 不允许 137 | } 138 | return true, "" 139 | } 140 | -------------------------------------------------------------------------------- /generator/gen_routes.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "strings" 7 | 8 | "github.com/MasterJoyHunan/gengin/prepare" 9 | "github.com/MasterJoyHunan/gengin/tpl" 10 | "github.com/samber/lo" 11 | "github.com/zeromicro/go-zero/tools/goctl/util/format" 12 | "golang.org/x/text/cases" 13 | "golang.org/x/text/language" 14 | 15 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 16 | ) 17 | 18 | func GenRoutes() error { 19 | for _, group := range prepare.ApiSpec.Service.Groups { 20 | subDir := group.GetAnnotation(groupProperty) 21 | subDir, err := format.FileNamingFormat(dirStyle, subDir) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | routesPkg := path.Join("routes", subDir) 27 | routesBase := path.Base(routesPkg) 28 | 29 | os.Remove(path.Join(prepare.OutputDir, routesPkg, "routes.go")) 30 | 31 | // handle 32 | handlePkg := path.Join("handler", subDir) 33 | handleBase := path.Base(handlePkg) 34 | 35 | // prefix 36 | prefix := group.GetAnnotation(spec.RoutePrefixKey) 37 | 38 | // middlewares 39 | var middlewares []string 40 | if len(group.GetAnnotation("jwt")) > 0 { 41 | middlewares = append(middlewares, group.GetAnnotation("jwt")) 42 | } 43 | 44 | if len(group.GetAnnotation("middleware")) > 0 { 45 | middlewares = append(middlewares, strings.Split(group.GetAnnotation("middleware"), ",")...) 46 | } 47 | 48 | middlewares = lo.Map(middlewares, func(item string, index int) string { 49 | res := strings.TrimSuffix(item, "Middleware") + "Middleware" 50 | return cases.Title(language.English, cases.NoLower).String(res) 51 | }) 52 | 53 | // route 54 | var routes []map[string]string 55 | for _, r := range group.Routes { 56 | routes = append(routes, map[string]string{ 57 | "method": strings.ToUpper(r.Method), 58 | "path": r.Path, 59 | "handle": cases.Title(language.English, cases.NoLower).String(r.Handler), 60 | }) 61 | } 62 | 63 | err = GenFile( 64 | "routes.go", 65 | tpl.RoutesTemplate, 66 | WithSubDir(routesPkg), 67 | WithData(map[string]any{ 68 | "rootPkg": prepare.RootPkg, 69 | "pkgName": routesBase, 70 | "handlePkg": handlePkg, 71 | "handleBase": handleBase, 72 | "prefix": prefix, 73 | "hasPrefix": len(prefix) > 0, 74 | "hasMiddleware": len(middlewares) > 0, 75 | "middleware": middlewares, 76 | "funcName": cases.Title(language.English, cases.NoLower).String(group.GetAnnotation(groupProperty)), 77 | "routes": routes, 78 | }), 79 | ) 80 | 81 | if err != nil { 82 | return err 83 | } 84 | } 85 | return genSetup() 86 | } 87 | 88 | func genSetup() error { 89 | os.Remove(path.Join(prepare.OutputDir, "routes/setup.go")) 90 | 91 | var routes []map[string]string 92 | for _, group := range prepare.ApiSpec.Service.Groups { 93 | subDir := group.GetAnnotation(groupProperty) 94 | subDir, err := format.FileNamingFormat(dirStyle, subDir) 95 | if err != nil { 96 | return err 97 | } 98 | 99 | routesPkg := path.Join("routes", subDir) 100 | routesBase := path.Base(routesPkg) 101 | 102 | name := cases.Title(language.English, cases.NoLower).String(group.GetAnnotation(groupProperty)) 103 | routes = append(routes, map[string]string{ 104 | "pkg": routesPkg, 105 | "base": routesBase, 106 | "name": name, 107 | "alias": func() string { 108 | if len(name) == 0 { 109 | return "" 110 | } 111 | return strings.ToLower(string(name[0])) + name[1:] 112 | }(), 113 | }) 114 | 115 | } 116 | 117 | return GenFile( 118 | "setup.go", 119 | tpl.RoutesSetupTemplate, 120 | WithSubDir("routes"), 121 | WithData(map[string]any{ 122 | "rootPkg": prepare.RootPkg, 123 | "routes": routes, 124 | }), 125 | ) 126 | } 127 | -------------------------------------------------------------------------------- /generator/gen_types.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | "strings" 8 | 9 | "github.com/MasterJoyHunan/gengin/prepare" 10 | "github.com/MasterJoyHunan/gengin/tpl" 11 | 12 | "github.com/zeromicro/go-zero/tools/goctl/api/spec" 13 | "github.com/zeromicro/go-zero/tools/goctl/util" 14 | "github.com/zeromicro/go-zero/tools/goctl/util/pathx" 15 | ) 16 | 17 | const labelName = "label" 18 | 19 | var hasFileMember = false 20 | 21 | var requestTypes map[string]any 22 | 23 | func GenTypes() error { 24 | requestTypes = getRequestTypes() 25 | types, err := buildTypes() 26 | if err != nil { 27 | return err 28 | } 29 | 30 | filename := pathx.JoinPackages(prepare.OutputDir, "types/types.go") 31 | os.Remove(filename) 32 | 33 | err = GenFile( 34 | "types.go", 35 | tpl.TypesTemplate, 36 | WithSubDir("types"), 37 | WithData(map[string]any{ 38 | "types": types, 39 | "hasFile": hasFileMember, 40 | }), 41 | ) 42 | if err != nil { 43 | return err 44 | } 45 | return nil 46 | } 47 | 48 | func getRequestTypes() map[string]any { 49 | types := make(map[string]any) 50 | for _, group := range prepare.ApiSpec.Service.Groups { 51 | for _, r := range group.Routes { 52 | types[r.RequestTypeName()] = nil 53 | } 54 | } 55 | return types 56 | } 57 | 58 | // buildTypes gen types to string 59 | func buildTypes() (string, error) { 60 | var builder strings.Builder 61 | first := true 62 | for _, tp := range prepare.ApiSpec.Types { 63 | if first { 64 | first = false 65 | } else { 66 | builder.WriteString("\n\n") 67 | } 68 | if err := writeType(&builder, tp); err != nil { 69 | return "", err 70 | } 71 | } 72 | 73 | return builder.String(), nil 74 | } 75 | 76 | func writeType(writer io.Writer, tp spec.Type) error { 77 | structType, ok := tp.(spec.DefineStruct) 78 | if !ok { 79 | return fmt.Errorf("unspport struct type: %s", tp.Name()) 80 | } 81 | 82 | fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name())) 83 | for _, member := range structType.Members { 84 | if member.IsInline { 85 | if _, err := fmt.Fprintf(writer, "%s\n", util.Title(member.Type.Name())); err != nil { 86 | return err 87 | } 88 | continue 89 | } 90 | 91 | tag := OverrideTag(tp, member) 92 | 93 | if err := writeProperty(writer, member.Name, tag, member.GetComment(), member.Type, member.Tags()); err != nil { 94 | return err 95 | } 96 | } 97 | 98 | fmt.Fprintf(writer, "}") 99 | return nil 100 | } 101 | 102 | func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, tags []*spec.Tag) error { 103 | var err error 104 | tpName := tp.Name() 105 | 106 | hasFileTag := false 107 | for _, v := range tags { 108 | if v.Key == "file" { 109 | hasFileTag = true 110 | hasFileMember = true 111 | break 112 | } 113 | } 114 | 115 | if hasFileTag { 116 | tpName = "*multipart.FileHeader" 117 | } 118 | 119 | if len(comment) > 0 { 120 | comment = strings.TrimPrefix(comment, "//") 121 | comment = "//" + comment 122 | _, err = fmt.Fprintf(writer, "%s %s %s %s\n", util.Title(name), tpName, tag, comment) 123 | } else { 124 | _, err = fmt.Fprintf(writer, "%s %s %s\n", util.Title(name), tpName, tag) 125 | } 126 | return err 127 | } 128 | 129 | func OverrideTag(tp spec.Type, member spec.Member) string { 130 | // 将 path 替换为 uri 131 | tag := member.Tag 132 | before, _, found := strings.Cut(tag, ":") 133 | if found && strings.HasSuffix(before, "path") { 134 | tag = strings.Replace(tag, "path", "uri", 1) 135 | } 136 | 137 | // 将注释加入到 label, 用于 validator 验证时中文返回 see http://github.com/go-playground/validator/v10 138 | // 希望只对 request type 进行处理 139 | _, ok := requestTypes[tp.Name()] 140 | if !ok { 141 | return tag 142 | } 143 | 144 | label := "" 145 | if member.Comment != "" { 146 | label = strings.ReplaceAll(member.Comment, "/", "") 147 | label = strings.Trim(label, " ") 148 | } 149 | if label != "" { 150 | label = fmt.Sprintf("%s:\"%s\"", labelName, label) 151 | tag = fmt.Sprintf("%s %s`", tag[:len(tag)-1], label) 152 | } 153 | return tag 154 | } 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## gengin 一个生成 gin 框架的脚手架 2 | 3 | gengin 基于 go-zero 开发,是一个 go-zero 的插件,只需定义 .api 文件,一行命令就可以生成整个项目的基础文件 4 | 5 | ### 前言 6 | 7 | 正所谓站在巨人的肩膀上,看的比较远。 8 | 9 | 本项目基于 go-zero 开发的插件,只需定义 api 文件,即可生成 gin 框架工程目录,借鉴了 go-zero 的思想, 10 | 配置大于约定。指在提高开发人员的工作效率,减少沟通成本 11 | 12 | 使用本项目生成的代码,只会依赖 gin 框架,其他什么依赖都没有,非常简洁优雅 13 | 14 | ### 为什么需要它 15 | 16 | 你当然可以使用 goctl 生成一个 http 单体服务,但是你可能更习惯使用 gin 框架的老司机, 17 | 在新项目你在纠结如何选型的时,到底是纠结使用 gin 搭建简单的服务,还是使用 go-zero 框架利用其完善的组件的时候, 18 | 希望本项目对你有所帮助 19 | 20 | 以下用户可以考虑使用该项目 21 | 22 | * 习惯使用 gin 框架 23 | * 希望每个项目都是使用一样的规范,一样的依赖,从而减少学习成本 24 | * 项目是一个简单的单体服务 25 | * 项目里面使用自己习惯的第三方库,可能不需要用到 go-zero 的组件如 26 | * mysql 27 | * redis 28 | * logger 29 | * 限流 30 | * 熔断 31 | * ....... 32 | * 希望定义了一个 .api 文件,基础代码自动生成 33 | * 希望用到 go-zero 丰富的生态 34 | 35 | ### 使用方法 36 | 37 | #### 安装 38 | 39 | go 1.16 以下使用 40 | ```sh 41 | go get -u github.com/MasterJoyHunan/gengin 42 | ``` 43 | go 1.16 及以上使用 44 | ```sh 45 | go install github.com/MasterJoyHunan/gengin@v1.7.2 46 | ``` 47 | 48 | #### 初始化一个 GO 项目 49 | 50 | ```sh 51 | mkdir you-application 52 | cd you-application 53 | go mod init you-app-pkg-name 54 | ``` 55 | 56 | #### 在项目下定义 you-app.api 文件 57 | 58 | [api语法指南](https://go-zero.dev/cn/docs/design/grammar) 59 | 60 | you-app.api 文件内容示例 61 | 62 | ```api 63 | syntax = "v1" 64 | 65 | info( 66 | title: "some app" 67 | ) 68 | 69 | type bookRequest { 70 | Name string `json:"name"` // 姓名 71 | Age int `json:"age"` // 年龄 72 | } 73 | 74 | type bookResponse { 75 | Code int `json:"code"` // 业务码 76 | Msg string `json:"msg"` // 业务消息 77 | } 78 | 79 | @server( 80 | jwt: Auth 81 | group: book 82 | middleware: SomeMiddleware,CorsMiddleware 83 | prefix: /v1 84 | ) 85 | 86 | service someapp { 87 | @doc "获取所有书本信息" 88 | @handler getBookList 89 | get /book (bookRequest) returns (bookResponse) 90 | 91 | @doc "获取书本信息" 92 | @handler getBook 93 | get /book/:id (bookRequest) returns (bookResponse) 94 | 95 | @doc "添加书本信息" 96 | @handler addBook 97 | post /book (bookRequest) returns (bookResponse) 98 | 99 | @doc "获取书本信息" 100 | @handler editBook 101 | put /book/:id (bookRequest) returns (bookResponse) 102 | } 103 | ``` 104 | 105 | #### 在项目下生成 gin 项目 106 | 107 | ```sh 108 | gengin xxx.api 109 | ``` 110 | 111 | #### 生成的目录结构如下 112 | 113 | ``` 114 | ├─config # 配置文件对应的 struct 115 | ├─etc # yaml 配置文件 116 | ├─handler # 控制器层 117 | ├─internal # 内部处理逻辑 118 | │ ├─response # 统一返回 119 | │ └─translator # 返回错误国际化 120 | ├─logic # 服务层 121 | ├─middleware # 中间件层 122 | ├─routes # 路由定义 123 | ├─types # 请求与相应的 struct 124 | you-app.go # main 文件 125 | ``` 126 | 127 | ### 重新执行程序那些文件会重新生成 128 | 129 | ``` 130 | ├─config # 如果文件已存在,不会重新生成 131 | ├─etc # 如果文件已存在,不会重新生成 132 | ├─handler # 如果文件已存在,不会重新生成 133 | ├─internal # 如果文件已存在,不会重新生成 134 | │ ├─response # 如果文件已存在,不会重新生成 135 | │ └─translator # 如果文件已存在,不会重新生成 136 | ├─logic # 如果文件已存在,不会重新生成 137 | ├─middleware # 如果文件已存在,不会重新生成 138 | ├─routes # gengin生成的文件会重新生成,请不要修改。手动新增的文件不会 139 | ├─types # gengin生成的文件会重新生成,请不要修改。手动新增的文件不会 140 | you-app.go # 如果文件已存在,不会重新生成 141 | ``` 142 | 143 | ### 注意事项 144 | 145 | * get 和 post 请求都是使用 from 接受参数. 146 | * 在 api 文件中定义 tag 为 path 的 tag 会转换为 uri,方便 gin 框架处理 147 | * 在 api 文件中定义 @server 下的 jwt 会自动转换为一个 middleware,需要手动选择自己的熟悉 jwt 框架自行处理 148 | * 在 api 文件中定义 @server 下的 group 使用驼峰命名,会自动分割文件夹,如:group=helloWord 149 | * logic => logic/hello/word/some_logic.go 150 | * handler => handler/hello/word/some_handle.go 151 | * 在 api 文件中定义 @server 下的 group 如果为空,则会放入对应的根目录,如: 152 | * logic => logic/some_logic.go 153 | * handler => handler/some_handle.go 154 | 155 | ### 其他 156 | 157 | 如果需要对 .api 文件生成 swagger 文档,请参考[https://github.com/zeromicro/goctl-swagger](https://github.com/zeromicro/goctl-swagger) 158 | 159 | 如果觉得该项目对你有所帮助,请不要吝啬你的小手,帮忙点个 stars 160 | 161 | 如果对本项目有更好的建议或意见,欢迎提交 pr / issues,或者联系本人 tanwuyang88@gmail.com 162 | 163 | 再次感谢 [go-zero](https://github.com/zeromicro/go-zero) 164 | 165 | ### 最佳实践 166 | 167 | [go-admin-template](https://github.com/topology-zero/go-admin-template) 168 | 169 | ### 协议 170 | 171 | [MIT](https://github.com/MasterJoyHunan/gengin/blob/master/LICENSE) 172 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 17 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 18 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 19 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 20 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 21 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 22 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 23 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 24 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 25 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 26 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 27 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 28 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 29 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 30 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 31 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 32 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 33 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 34 | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= 35 | github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= 36 | github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= 37 | github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= 38 | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= 39 | github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= 40 | github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= 41 | github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= 42 | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 43 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 44 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 45 | github.com/ClickHouse/clickhouse-go v1.5.1/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= 46 | github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= 47 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= 48 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 49 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 50 | github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs= 51 | github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/cvHQkZ1fst0EmZnA5dFtiQdWCNCFYzb+uE2vqVgvx0= 52 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 53 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 54 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 55 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 56 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 57 | github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= 58 | github.com/alicebob/miniredis/v2 v2.17.0/go.mod h1:gquAfGbzn92jvtrSC69+6zZnwSODVXVpYDRaGhWaL6I= 59 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 60 | github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= 61 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 62 | github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 63 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 64 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 65 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 66 | github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= 67 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 68 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 69 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 70 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 71 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 72 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 73 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 74 | github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= 75 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 76 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 77 | github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= 78 | github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 79 | github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 80 | github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 81 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 82 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 83 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 84 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 85 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 86 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 87 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 88 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 89 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 90 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 91 | github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= 92 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= 93 | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 94 | github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 95 | github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= 96 | github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= 97 | github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= 98 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 99 | github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= 100 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 101 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 102 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 103 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 104 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 105 | github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= 106 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 107 | github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= 108 | github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= 109 | github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= 110 | github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= 111 | github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 112 | github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= 113 | github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 114 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 115 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 116 | github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 117 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 118 | github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= 119 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 120 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 121 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 122 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 123 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 124 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 125 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 126 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 127 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 128 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 129 | github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= 130 | github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 131 | github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 132 | github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 133 | github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= 134 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 135 | github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= 136 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 137 | github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= 138 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= 139 | github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= 140 | github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 141 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 142 | github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= 143 | github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 144 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 145 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 146 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 147 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 148 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 149 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 150 | github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= 151 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 152 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 153 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 154 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 155 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 156 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 157 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 158 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 159 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 160 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 161 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 162 | github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 163 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 164 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 165 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 166 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 167 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 168 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 169 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 170 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 171 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 172 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 173 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 174 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 175 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 176 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 177 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 178 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 179 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 180 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 181 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 182 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 183 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 184 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 185 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 186 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 187 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 188 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 189 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 190 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 191 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 192 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 193 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 194 | github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 195 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 196 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 197 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 198 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 199 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 200 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 201 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 202 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 203 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 204 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 205 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 206 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 207 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 208 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 209 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 210 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 211 | github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= 212 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 213 | github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= 214 | github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= 215 | github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 216 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 217 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 218 | github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= 219 | github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 220 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 221 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 222 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 223 | github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= 224 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 225 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= 226 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 227 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 228 | github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= 229 | github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= 230 | github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= 231 | github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= 232 | github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= 233 | github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= 234 | github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= 235 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 236 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 237 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 238 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 239 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 240 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 241 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 242 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 243 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 244 | github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= 245 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 246 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 247 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 248 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 249 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 250 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 251 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 252 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 253 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 254 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 255 | github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= 256 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 257 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 258 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 259 | github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 260 | github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= 261 | github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= 262 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 263 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 264 | github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 265 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 266 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 267 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 268 | github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 269 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 270 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= 271 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 272 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 273 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 274 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 275 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 276 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 277 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 278 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 279 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 280 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= 281 | github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= 282 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 283 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 284 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 285 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 286 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 287 | github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 288 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 289 | github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= 290 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= 291 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 292 | github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 293 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 294 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 295 | github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= 296 | github.com/openzipkin/zipkin-go v0.3.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= 297 | github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ= 298 | github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 299 | github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 300 | github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 301 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 302 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 303 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 304 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 305 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 306 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 307 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 308 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 309 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 310 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 311 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 312 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 313 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 314 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 315 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 316 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= 317 | github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 318 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 319 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 320 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= 321 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 322 | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 323 | github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM= 324 | github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 325 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 326 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 327 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 328 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 329 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 330 | github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= 331 | github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= 332 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 333 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 334 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 335 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 336 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 337 | github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 338 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 339 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 340 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 341 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 342 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 343 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 344 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 345 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 346 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 347 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 348 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 349 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 350 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 351 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 352 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 353 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 354 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 355 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 356 | github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= 357 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= 358 | github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= 359 | github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= 360 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 361 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 362 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 363 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 364 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 365 | github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= 366 | github.com/zeromicro/antlr v0.0.1 h1:CQpIn/dc0pUjgGQ81y98s/NGOm2Hfru2NNio2I9mQgk= 367 | github.com/zeromicro/antlr v0.0.1/go.mod h1:nfpjEwFR6Q4xGDJMcZnCL9tEfQRgszMwu3rDz2Z+p5M= 368 | github.com/zeromicro/ddl-parser v1.0.3/go.mod h1:ISU/8NuPyEpl9pa17Py9TBPetMjtsiHrb9f5XGiYbo8= 369 | github.com/zeromicro/go-zero v1.3.2 h1:2HcmceZDEGwZWvofCG+0GXyh+Gtz/wKCW4Fq8Mb7KIg= 370 | github.com/zeromicro/go-zero v1.3.2/go.mod h1:DEj3Fwj1Ui1ltsgf6YqwTL9nD4+tYzIRX0c1pWtQo1E= 371 | github.com/zeromicro/go-zero/tools/goctl v1.3.8 h1:lkH39gTAWA2n3HZrHgbv/+YB72UbCvwBMyoyVdRIQ6U= 372 | github.com/zeromicro/go-zero/tools/goctl v1.3.8/go.mod h1:rF2Asf4qi0qvjDk/PHupoUqvwF1HGI97tAtJ1cB8Ggg= 373 | go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= 374 | go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= 375 | go.etcd.io/etcd/client/v3 v3.5.2/go.mod h1:kOOaWFFgHygyT0WlSmL8TJiXmMysO/nNUlEsSsN6W4o= 376 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 377 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 378 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 379 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 380 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 381 | go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= 382 | go.opentelemetry.io/otel/exporters/jaeger v1.3.0/go.mod h1:KoYHi1BtkUPncGSRtCe/eh1ijsnePhSkxwzz07vU0Fc= 383 | go.opentelemetry.io/otel/exporters/zipkin v1.3.0/go.mod h1:LxGGfHIYbvsFnrJtBcazb0yG24xHdDGrT/H6RB9r3+8= 384 | go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= 385 | go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= 386 | go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 387 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 388 | go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 389 | go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= 390 | go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= 391 | go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= 392 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 393 | go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= 394 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= 395 | go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= 396 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 397 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 398 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 399 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 400 | golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 401 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 402 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 403 | golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 404 | golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 405 | golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 406 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 407 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 408 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 409 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 410 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 411 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 412 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 413 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 414 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 415 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 416 | golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= 417 | golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= 418 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 419 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 420 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 421 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 422 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 423 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 424 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 425 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 426 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 427 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 428 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 429 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 430 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 431 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 432 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 433 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 434 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 435 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 436 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 437 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 438 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 439 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 440 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 441 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 442 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 443 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 444 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 445 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 446 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 447 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 448 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 449 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 450 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 451 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 452 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 453 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 454 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 455 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 456 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 457 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 458 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 459 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 460 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 461 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 462 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 463 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 464 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 465 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 466 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 467 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 468 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 469 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 470 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 471 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 472 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 473 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 474 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 475 | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 476 | golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 477 | golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 478 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 479 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 480 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 481 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 482 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 483 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 484 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 485 | golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 486 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 487 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 488 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 489 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 490 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 491 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 492 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 493 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 494 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 495 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 496 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 497 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 498 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 499 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 500 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 501 | golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 502 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 503 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 504 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 505 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 506 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 507 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 508 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 509 | golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 510 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 511 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 512 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 513 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 514 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 515 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 516 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 517 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 518 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 519 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 520 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 521 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 522 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 523 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 524 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 525 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 526 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 527 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 528 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 529 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 530 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 531 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 532 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 533 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 534 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 535 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 536 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 537 | golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 538 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 539 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 540 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 541 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 542 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 543 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 544 | golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 545 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 546 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 547 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 548 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 549 | golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 550 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 551 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 552 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 553 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 554 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 555 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 556 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 557 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 558 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 559 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 560 | golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= 561 | golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 562 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 563 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 564 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 565 | golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 566 | golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 567 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 568 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 569 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 570 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 571 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 572 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 573 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 574 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 575 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 576 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 577 | golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 578 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 579 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 580 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 581 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 582 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 583 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 584 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 585 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 586 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 587 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 588 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 589 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 590 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 591 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 592 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 593 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 594 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 595 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 596 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 597 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 598 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 599 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 600 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 601 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 602 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 603 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 604 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 605 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 606 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 607 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 608 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 609 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 610 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 611 | golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 612 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 613 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 614 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 615 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 616 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 617 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 618 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 619 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 620 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 621 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 622 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 623 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 624 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 625 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 626 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 627 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 628 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 629 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 630 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 631 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 632 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 633 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 634 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 635 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 636 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 637 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 638 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 639 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 640 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 641 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 642 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 643 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 644 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 645 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 646 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 647 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 648 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 649 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 650 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 651 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 652 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 653 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 654 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 655 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 656 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 657 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 658 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 659 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 660 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 661 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 662 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 663 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 664 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 665 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 666 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 667 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 668 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 669 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 670 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 671 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 672 | google.golang.org/genproto v0.0.0-20220228195345-15d65a4533f7/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= 673 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 674 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 675 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 676 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 677 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 678 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 679 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 680 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 681 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 682 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 683 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 684 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 685 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 686 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 687 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 688 | google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= 689 | google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= 690 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 691 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 692 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 693 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 694 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 695 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 696 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 697 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 698 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 699 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 700 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 701 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 702 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 703 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 704 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 705 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 706 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 707 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 708 | gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= 709 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 710 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 711 | gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= 712 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 713 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 714 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 715 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 716 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 717 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 718 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 719 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 720 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 721 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 722 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 723 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 724 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 725 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 726 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 727 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 728 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 729 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 730 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 731 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 732 | k8s.io/api v0.20.12/go.mod h1:A2brwyEkVLM3wQGNnzoAa5JsQRzHK0uoOQ+bsnv7V68= 733 | k8s.io/apimachinery v0.20.12/go.mod h1:uM7hCI0NyBymUwgshMgZyte475lxhr+QH6h3cvdnzEc= 734 | k8s.io/client-go v0.20.12/go.mod h1:NBJj6Evp73Xy/4v/O/RDRaH0+3JoxNfjRxkyRgrdbsA= 735 | k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= 736 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= 737 | k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= 738 | k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= 739 | k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= 740 | k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= 741 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 742 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 743 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 744 | sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= 745 | sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= 746 | sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= 747 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= 748 | --------------------------------------------------------------------------------