diff --git a/tools/goctl/api/apigen/api.tpl b/tools/goctl/api/apigen/api.tpl new file mode 100644 index 00000000..2176441c --- /dev/null +++ b/tools/goctl/api/apigen/api.tpl @@ -0,0 +1,24 @@ +syntax = "v1" + +info ( + title: // TODO: add title + desc: // TODO: add description + author: "{{.gitUser}}" + email: "{{.gitEmail}}" +) + +type request { + // TODO: add members here and delete this comment +} + +type response { + // TODO: add members here and delete this comment +} + +service {{.serviceName}} { + @handler GetUser // TODO: set handler name and delete this comment + get /users/id/:userId(request) returns(response) + + @handler CreateUser // TODO: set handler name and delete this comment + post /users/create(request) +} diff --git a/tools/goctl/api/apigen/gen.go b/tools/goctl/api/apigen/gen.go index afdba15e..e57b603e 100644 --- a/tools/goctl/api/apigen/gen.go +++ b/tools/goctl/api/apigen/gen.go @@ -1,11 +1,12 @@ package apigen import ( + _ "embed" "errors" "fmt" + "html/template" "path/filepath" "strings" - "text/template" "github.com/logrusorgru/aurora" "github.com/urfave/cli" @@ -13,32 +14,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const apiTemplate = ` -syntax = "v1" - -info ( - title: // TODO: add title - desc: // TODO: add description - author: "{{.gitUser}}" - email: "{{.gitEmail}}" -) - -type request { - // TODO: add members here and delete this comment -} - -type response { - // TODO: add members here and delete this comment -} - -service {{.serviceName}} { - @handler GetUser // TODO: set handler name and delete this comment - get /users/id/:userId(request) returns(response) - - @handler CreateUser // TODO: set handler name and delete this comment - post /users/create(request) -} -` +//go:embed api.tpl +var apiTemplate string // ApiCommand create api template file func ApiCommand(c *cli.Context) error { diff --git a/tools/goctl/api/docgen/doc.go b/tools/goctl/api/docgen/doc.go index 7b876e89..6189d5db 100644 --- a/tools/goctl/api/docgen/doc.go +++ b/tools/goctl/api/docgen/doc.go @@ -2,6 +2,7 @@ package docgen import ( "bytes" + _ "embed" "fmt" "html/template" "strconv" @@ -13,25 +14,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/api/util" ) -const ( - markdownTemplate = ` -### {{.index}}. {{.routeComment}} - -1. 路由定义 - -- Url: {{.uri}} -- Method: {{.method}} -- Request: {{.requestType}} -- Response: {{.responseType}} - -2. 请求定义 -{{.requestContent}} - -3. 返回定义 -{{.responseContent}} - -` -) +//go:embed markdown.tpl +var markdownTemplate string func genDoc(api *spec.ApiSpec, dir, filename string) error { fp, _, err := util.MaybeCreateFile(dir, "", filename) diff --git a/tools/goctl/api/docgen/markdown.tpl b/tools/goctl/api/docgen/markdown.tpl new file mode 100644 index 00000000..cc87a2f8 --- /dev/null +++ b/tools/goctl/api/docgen/markdown.tpl @@ -0,0 +1,16 @@ +### {{.index}}. {{.routeComment}} + +1. route definition + +- Url: {{.uri}} +- Method: {{.method}} +- Request: {{.requestType}} +- Response: {{.responseType}} + +2. request definition + +{{.requestContent}} + +3. response definition + +{{.responseContent}} diff --git a/tools/goctl/api/gogen/etc.tpl b/tools/goctl/api/gogen/etc.tpl new file mode 100644 index 00000000..ed55cf1b --- /dev/null +++ b/tools/goctl/api/gogen/etc.tpl @@ -0,0 +1,3 @@ +Name: {{.serviceName}} +Host: {{.host}} +Port: {{.port}} diff --git a/tools/goctl/api/gogen/genetc.go b/tools/goctl/api/gogen/genetc.go index c43f7879..12201372 100644 --- a/tools/goctl/api/gogen/genetc.go +++ b/tools/goctl/api/gogen/genetc.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "strconv" @@ -12,12 +13,11 @@ import ( const ( defaultPort = 8888 etcDir = "etc" - etcTemplate = `Name: {{.serviceName}} -Host: {{.host}} -Port: {{.port}} -` ) +//go:embed etc.tpl +var etcTemplate string + func genEtc(dir string, cfg *config.Config, api *spec.ApiSpec) error { filename, err := format.FileNamingFormat(cfg.NamingFormat, api.Service.Name) if err != nil { diff --git a/tools/goctl/api/gogen/genhandlers.go b/tools/goctl/api/gogen/genhandlers.go index 45b61081..b30494d1 100644 --- a/tools/goctl/api/gogen/genhandlers.go +++ b/tools/goctl/api/gogen/genhandlers.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "path" "strings" @@ -14,36 +15,10 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/vars" ) -const ( - defaultLogicPackage = "logic" - handlerTemplate = `package {{.PkgName}} +const defaultLogicPackage = "logic" -import ( - "net/http" - - {{if .After1_1_10}}"github.com/zeromicro/go-zero/rest/httpx"{{end}} - {{.ImportPackages}} -) - -func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - {{if .HasRequest}}var req types.{{.RequestType}} - if err := httpx.Parse(r, &req); err != nil { - httpx.Error(w, err) - return - } - - {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx) - {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}}) - if err != nil { - httpx.Error(w, err) - } else { - {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}} - } - } -} -` -) +//go:embed handler.tpl +var handlerTemplate string type handlerInfo struct { PkgName string diff --git a/tools/goctl/api/gogen/genlogic.go b/tools/goctl/api/gogen/genlogic.go index 475b941d..28780495 100644 --- a/tools/goctl/api/gogen/genlogic.go +++ b/tools/goctl/api/gogen/genlogic.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "path" "strconv" @@ -14,32 +15,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/vars" ) -const logicTemplate = `package {{.pkgName}} - -import ( - {{.imports}} -) - -type {{.logic}} struct { - logx.Logger - ctx context.Context - svcCtx *svc.ServiceContext -} - -func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} { - return &{{.logic}}{ - Logger: logx.WithContext(ctx), - ctx: ctx, - svcCtx: svcCtx, - } -} - -func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} { - // todo: add your logic here and delete this line - - {{.returnString}} -} -` +//go:embed logic.tpl +var logicTemplate string func genLogic(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error { for _, g := range api.Service.Groups { diff --git a/tools/goctl/api/gogen/genmain.go b/tools/goctl/api/gogen/genmain.go index 3a3269d0..154a7dcc 100644 --- a/tools/goctl/api/gogen/genmain.go +++ b/tools/goctl/api/gogen/genmain.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "strings" @@ -11,33 +12,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/vars" ) -const mainTemplate = `package main - -import ( - "flag" - "fmt" - - {{.importPackages}} -) - -var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file") - -func main() { - flag.Parse() - - var c config.Config - conf.MustLoad(*configFile, &c) - - ctx := svc.NewServiceContext(c) - server := rest.MustNewServer(c.RestConf) - defer server.Stop() - - handler.RegisterHandlers(server, ctx) - - fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) - server.Start() -} -` +//go:embed main.tpl +var mainTemplate string func genMain(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error { name := strings.ToLower(api.Service.Name) diff --git a/tools/goctl/api/gogen/genmiddleware.go b/tools/goctl/api/gogen/genmiddleware.go index c283c008..d302b51c 100644 --- a/tools/goctl/api/gogen/genmiddleware.go +++ b/tools/goctl/api/gogen/genmiddleware.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "strings" "github.com/zeromicro/go-zero/tools/goctl/api/spec" @@ -8,27 +9,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/format" ) -var middlewareImplementCode = ` -package middleware - -import "net/http" - -type {{.name}} struct { -} - -func New{{.name}}() *{{.name}} { - return &{{.name}}{} -} - -func (m *{{.name}})Handle(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // TODO generate middleware implement function, delete after code implementation - - // Passthrough to next handler if need - next(w, r) - } -} -` +//go:embed middleware.tpl +var middlewareImplementCode string func genMiddleware(dir string, cfg *config.Config, api *spec.ApiSpec) error { middlewares := getMiddleware(api) diff --git a/tools/goctl/api/gogen/gensvc.go b/tools/goctl/api/gogen/gensvc.go index 573b8466..1f500a00 100644 --- a/tools/goctl/api/gogen/gensvc.go +++ b/tools/goctl/api/gogen/gensvc.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "strings" @@ -11,27 +12,10 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/vars" ) -const ( - contextFilename = "service_context" - contextTemplate = `package svc +const contextFilename = "service_context" -import ( - {{.configImport}} -) - -type ServiceContext struct { - Config {{.config}} - {{.middleware}} -} - -func NewServiceContext(c {{.config}}) *ServiceContext { - return &ServiceContext{ - Config: c, - {{.middlewareAssignment}} - } -} -` -) +//go:embed svc.tpl +var contextTemplate string func genServiceContext(dir, rootPkg string, cfg *config.Config, api *spec.ApiSpec) error { filename, err := format.FileNamingFormat(cfg.NamingFormat, contextFilename) diff --git a/tools/goctl/api/gogen/gentypes.go b/tools/goctl/api/gogen/gentypes.go index 6dfe9932..9e91735f 100644 --- a/tools/goctl/api/gogen/gentypes.go +++ b/tools/goctl/api/gogen/gentypes.go @@ -1,6 +1,7 @@ package gogen import ( + _ "embed" "fmt" "io" "os" @@ -14,16 +15,10 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/format" ) -const ( - typesFile = "types" - typesTemplate = `// Code generated by goctl. DO NOT EDIT. -package types{{if .containsTime}} -import ( - "time" -){{end}} -{{.types}} -` -) +const typesFile = "types" + +//go:embed types.tpl +var typesTemplate string // BuildTypes gen types to string func BuildTypes(types []spec.Type) (string, error) { diff --git a/tools/goctl/api/gogen/handler.tpl b/tools/goctl/api/gogen/handler.tpl new file mode 100644 index 00000000..0c92b885 --- /dev/null +++ b/tools/goctl/api/gogen/handler.tpl @@ -0,0 +1,26 @@ +package {{.PkgName}} + +import ( + "net/http" + + {{if .After1_1_10}}"github.com/zeromicro/go-zero/rest/httpx"{{end}} + {{.ImportPackages}} +) + +func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + {{if .HasRequest}}var req types.{{.RequestType}} + if err := httpx.Parse(r, &req); err != nil { + httpx.Error(w, err) + return + } + + {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx) + {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}}) + if err != nil { + httpx.Error(w, err) + } else { + {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}} + } + } +} diff --git a/tools/goctl/api/gogen/logic.tpl b/tools/goctl/api/gogen/logic.tpl new file mode 100644 index 00000000..7c043237 --- /dev/null +++ b/tools/goctl/api/gogen/logic.tpl @@ -0,0 +1,25 @@ +package {{.pkgName}} + +import ( + {{.imports}} +) + +type {{.logic}} struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} { + return &{{.logic}}{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} { + // todo: add your logic here and delete this line + + {{.returnString}} +} diff --git a/tools/goctl/api/gogen/main.tpl b/tools/goctl/api/gogen/main.tpl new file mode 100644 index 00000000..a4ab692a --- /dev/null +++ b/tools/goctl/api/gogen/main.tpl @@ -0,0 +1,26 @@ +package main + +import ( + "flag" + "fmt" + + {{.importPackages}} +) + +var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + + ctx := svc.NewServiceContext(c) + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + handler.RegisterHandlers(server, ctx) + + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) + server.Start() +} diff --git a/tools/goctl/api/gogen/middleware.tpl b/tools/goctl/api/gogen/middleware.tpl new file mode 100644 index 00000000..3a9f8e91 --- /dev/null +++ b/tools/goctl/api/gogen/middleware.tpl @@ -0,0 +1,19 @@ +package middleware + +import "net/http" + +type {{.name}} struct { +} + +func New{{.name}}() *{{.name}} { + return &{{.name}}{} +} + +func (m *{{.name}})Handle(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // TODO generate middleware implement function, delete after code implementation + + // Passthrough to next handler if need + next(w, r) + } +} diff --git a/tools/goctl/api/gogen/svc.tpl b/tools/goctl/api/gogen/svc.tpl new file mode 100644 index 00000000..c15c1e45 --- /dev/null +++ b/tools/goctl/api/gogen/svc.tpl @@ -0,0 +1,17 @@ +package svc + +import ( + {{.configImport}} +) + +type ServiceContext struct { + Config {{.config}} + {{.middleware}} +} + +func NewServiceContext(c {{.config}}) *ServiceContext { + return &ServiceContext{ + Config: c, + {{.middlewareAssignment}} + } +} diff --git a/tools/goctl/api/gogen/types.tpl b/tools/goctl/api/gogen/types.tpl new file mode 100644 index 00000000..735ec2da --- /dev/null +++ b/tools/goctl/api/gogen/types.tpl @@ -0,0 +1,6 @@ +// Code generated by goctl. DO NOT EDIT. +package types{{if .containsTime}} +import ( + "time" +){{end}} +{{.types}} diff --git a/tools/goctl/api/javagen/bool.tpl b/tools/goctl/api/javagen/bool.tpl new file mode 100644 index 00000000..ed5c3371 --- /dev/null +++ b/tools/goctl/api/javagen/bool.tpl @@ -0,0 +1,9 @@ + +{{.indent}}{{.decorator}} +{{.indent}}public {{.returnType}} is{{.property}}() { +{{.indent}} return this.{{.tagValue}}; +{{.indent}}} + +{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) { +{{.indent}} this.{{.tagValue}} = {{.propertyValue}}; +{{.indent}}} diff --git a/tools/goctl/api/javagen/component.tpl b/tools/goctl/api/javagen/component.tpl new file mode 100644 index 00000000..0bb309f3 --- /dev/null +++ b/tools/goctl/api/javagen/component.tpl @@ -0,0 +1,22 @@ +// Code generated by goctl. DO NOT EDIT. +package com.xhb.logic.http.packet.{{.packet}}.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +{{.imports}} + +public class {{.className}} extends {{.superClassName}} { + +{{.properties}} +{{if .HasProperty}} + + public {{.className}}() { + } + + public {{.className}}({{.params}}) { +{{.constructorSetter}} + } +{{end}} + +{{.getSet}} +} diff --git a/tools/goctl/api/javagen/gen.go b/tools/goctl/api/javagen/gen.go index e21ffb37..4c99269e 100644 --- a/tools/goctl/api/javagen/gen.go +++ b/tools/goctl/api/javagen/gen.go @@ -12,7 +12,7 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -// JavaCommand the generate java code command entrance +// JavaCommand generates java code command entrance. func JavaCommand(c *cli.Context) error { apiFile := c.String("api") dir := c.String("dir") diff --git a/tools/goctl/api/javagen/gencomponents.go b/tools/goctl/api/javagen/gencomponents.go index f87136ea..a9c5a0e1 100644 --- a/tools/goctl/api/javagen/gencomponents.go +++ b/tools/goctl/api/javagen/gencomponents.go @@ -3,6 +3,7 @@ package javagen import ( "bufio" "bytes" + _ "embed" "errors" "fmt" "io" @@ -18,54 +19,19 @@ import ( ) const ( - componentTemplate = `// Code generated by goctl. DO NOT EDIT. -package com.xhb.logic.http.packet.{{.packet}}.model; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -{{.imports}} - -public class {{.className}} extends {{.superClassName}} { - -{{.properties}} -{{if .HasProperty}} - - public {{.className}}() { - } - - public {{.className}}({{.params}}) { -{{.constructorSetter}} - } -{{end}} - -{{.getSet}} -} -` - getSetTemplate = ` -{{.indent}}{{.decorator}} -{{.indent}}public {{.returnType}} get{{.property}}() { -{{.indent}} return this.{{.tagValue}}; -{{.indent}}} - -{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) { -{{.indent}} this.{{.tagValue}} = {{.propertyValue}}; -{{.indent}}} -` - - boolTemplate = ` -{{.indent}}{{.decorator}} -{{.indent}}public {{.returnType}} is{{.property}}() { -{{.indent}} return this.{{.tagValue}}; -{{.indent}}} - -{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) { -{{.indent}} this.{{.tagValue}} = {{.propertyValue}}; -{{.indent}}} -` httpResponseData = "import com.xhb.core.response.HttpResponseData;" httpData = "import com.xhb.core.packet.HttpData;" ) +var ( + //go:embed component.tpl + componentTemplate string + //go:embed getset.tpl + getSetTemplate string + //go:embed bool.tpl + boolTemplate string +) + type componentsContext struct { api *spec.ApiSpec requestTypes []spec.Type diff --git a/tools/goctl/api/javagen/genpacket.go b/tools/goctl/api/javagen/genpacket.go index 7485a348..b27d5710 100644 --- a/tools/goctl/api/javagen/genpacket.go +++ b/tools/goctl/api/javagen/genpacket.go @@ -2,6 +2,7 @@ package javagen import ( "bytes" + _ "embed" "fmt" "strings" "text/template" @@ -12,32 +13,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util" ) -const packetTemplate = `package com.xhb.logic.http.packet.{{.packet}}; - -import com.xhb.core.packet.HttpPacket; -import com.xhb.core.network.HttpRequestClient; -{{.imports}} - -{{.doc}} -public class {{.packetName}} extends HttpPacket<{{.responseType}}> { - {{.paramsDeclaration}} - - public {{.packetName}}({{.params}}{{if .HasRequestBody}}{{.requestType}} request{{end}}) { - {{if .HasRequestBody}}super(request);{{else}}super(EmptyRequest.instance);{{end}} - {{if .HasRequestBody}}this.request = request;{{end}}{{.paramsSetter}} - } - - @Override - public HttpRequestClient.Method requestMethod() { - return HttpRequestClient.Method.{{.method}}; - } - - @Override - public String requestUri() { - return {{.uri}}; - } -} -` +//go:embed packet.tpl +var packetTemplate string func genPacket(dir, packetName string, api *spec.ApiSpec) error { for _, route := range api.Service.Routes() { diff --git a/tools/goctl/api/javagen/getset.tpl b/tools/goctl/api/javagen/getset.tpl new file mode 100644 index 00000000..c0fac211 --- /dev/null +++ b/tools/goctl/api/javagen/getset.tpl @@ -0,0 +1,9 @@ + +{{.indent}}{{.decorator}} +{{.indent}}public {{.returnType}} get{{.property}}() { +{{.indent}} return this.{{.tagValue}}; +{{.indent}}} + +{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) { +{{.indent}} this.{{.tagValue}} = {{.propertyValue}}; +{{.indent}}} diff --git a/tools/goctl/api/javagen/packet.tpl b/tools/goctl/api/javagen/packet.tpl new file mode 100644 index 00000000..db01bfe3 --- /dev/null +++ b/tools/goctl/api/javagen/packet.tpl @@ -0,0 +1,25 @@ +package com.xhb.logic.http.packet.{{.packet}}; + +import com.xhb.core.packet.HttpPacket; +import com.xhb.core.network.HttpRequestClient; +{{.imports}} + +{{.doc}} +public class {{.packetName}} extends HttpPacket<{{.responseType}}> { + {{.paramsDeclaration}} + + public {{.packetName}}({{.params}}{{if .HasRequestBody}}{{.requestType}} request{{end}}) { + {{if .HasRequestBody}}super(request);{{else}}super(EmptyRequest.instance);{{end}} + {{if .HasRequestBody}}this.request = request;{{end}}{{.paramsSetter}} + } + + @Override + public HttpRequestClient.Method requestMethod() { + return HttpRequestClient.Method.{{.method}}; + } + + @Override + public String requestUri() { + return {{.uri}}; + } +} diff --git a/tools/goctl/api/ktgen/api.tpl b/tools/goctl/api/ktgen/api.tpl new file mode 100644 index 00000000..2ec177a6 --- /dev/null +++ b/tools/goctl/api/ktgen/api.tpl @@ -0,0 +1,22 @@ +package {{with .Info}}{{.Desc}}{{end}} + +import com.google.gson.Gson + +object {{with .Info}}{{.Title}}{{end}}{ + {{range .Types}} + data class {{.Name}}({{$length := (len .Members)}}{{range $i,$item := .Members}} + val {{with $item}}{{lowCamelCase .Name}}: {{parseType .Type.Name}}{{end}}{{if ne $i (add $length -1)}},{{end}}{{end}} + ){{end}} + {{with .Service}} + {{range .Routes}}suspend fun {{routeToFuncName .Method .Path}}({{with .RequestType}}{{if ne .Name ""}} + req:{{.Name}},{{end}}{{end}} + onOk: (({{with .ResponseType}}{{.Name}}{{end}}) -> Unit)? = null, + onFail: ((String) -> Unit)? = null, + eventually: (() -> Unit)? = null + ){ + apiRequest("{{upperCase .Method}}","{{.Path}}",{{with .RequestType}}{{if ne .Name ""}}body=req,{{end}}{{end}} onOk = { {{with .ResponseType}} + onOk?.invoke({{if ne .Name ""}}Gson().fromJson(it,{{.Name}}::class.java){{end}}){{end}} + }, onFail = onFail, eventually =eventually) + } + {{end}}{{end}} +} diff --git a/tools/goctl/api/ktgen/apibase.tpl b/tools/goctl/api/ktgen/apibase.tpl new file mode 100644 index 00000000..4aff68a5 --- /dev/null +++ b/tools/goctl/api/ktgen/apibase.tpl @@ -0,0 +1,61 @@ +package {{.}} + +import com.google.gson.Gson +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.OutputStreamWriter +import java.net.HttpURLConnection +import java.net.URL + +const val SERVER = "http://localhost:8080" + +suspend fun apiRequest( + method: String, + uri: String, + body: Any = "", + onOk: ((String) -> Unit)? = null, + onFail: ((String) -> Unit)? = null, + eventually: (() -> Unit)? = null +) = withContext(Dispatchers.IO) { + val url = URL(SERVER + uri) + with(url.openConnection() as HttpURLConnection) { + connectTimeout = 3000 + requestMethod = method + doInput = true + if (method == "POST" || method == "PUT" || method == "PATCH") { + setRequestProperty("Content-Type", "application/json") + doOutput = true + val data = when (body) { + is String -> { + body + } + else -> { + Gson().toJson(body) + } + } + val wr = OutputStreamWriter(outputStream) + wr.write(data) + wr.flush() + } + + try { + if (responseCode >= 400) { + BufferedReader(InputStreamReader(errorStream)).use { + val response = it.readText() + onFail?.invoke(response) + } + return@with + } + //response + BufferedReader(InputStreamReader(inputStream)).use { + val response = it.readText() + onOk?.invoke(response) + } + } catch (e: Exception) { + e.message?.let { onFail?.invoke(it) } + } + } + eventually?.invoke() +} diff --git a/tools/goctl/api/ktgen/cmd.go b/tools/goctl/api/ktgen/cmd.go index f0168cf4..65a81e0b 100644 --- a/tools/goctl/api/ktgen/cmd.go +++ b/tools/goctl/api/ktgen/cmd.go @@ -7,7 +7,7 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/api/parser" ) -// KtCommand the generate kotlin code command entrance +// KtCommand generates kotlin code command entrance func KtCommand(c *cli.Context) error { apiFile := c.String("api") if apiFile == "" { diff --git a/tools/goctl/api/ktgen/gen.go b/tools/goctl/api/ktgen/gen.go index 73969cf4..b46f4f16 100644 --- a/tools/goctl/api/ktgen/gen.go +++ b/tools/goctl/api/ktgen/gen.go @@ -1,6 +1,7 @@ package ktgen import ( + _ "embed" "fmt" "os" "path/filepath" @@ -10,91 +11,11 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/api/spec" ) -const ( - apiBaseTemplate = `package {{.}} - -import com.google.gson.Gson -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import java.io.BufferedReader -import java.io.InputStreamReader -import java.io.OutputStreamWriter -import java.net.HttpURLConnection -import java.net.URL - -const val SERVER = "http://localhost:8080" - -suspend fun apiRequest( - method: String, - uri: String, - body: Any = "", - onOk: ((String) -> Unit)? = null, - onFail: ((String) -> Unit)? = null, - eventually: (() -> Unit)? = null -) = withContext(Dispatchers.IO) { - val url = URL(SERVER + uri) - with(url.openConnection() as HttpURLConnection) { - connectTimeout = 3000 - requestMethod = method - doInput = true - if (method == "POST" || method == "PUT" || method == "PATCH") { - setRequestProperty("Content-Type", "application/json") - doOutput = true - val data = when (body) { - is String -> { - body - } - else -> { - Gson().toJson(body) - } - } - val wr = OutputStreamWriter(outputStream) - wr.write(data) - wr.flush() - } - - try { - if (responseCode >= 400) { - BufferedReader(InputStreamReader(errorStream)).use { - val response = it.readText() - onFail?.invoke(response) - } - return@with - } - //response - BufferedReader(InputStreamReader(inputStream)).use { - val response = it.readText() - onOk?.invoke(response) - } - } catch (e: Exception) { - e.message?.let { onFail?.invoke(it) } - } - } - eventually?.invoke() -} -` - apiTemplate = `package {{with .Info}}{{.Desc}}{{end}} - -import com.google.gson.Gson - -object {{with .Info}}{{.Title}}{{end}}{ - {{range .Types}} - data class {{.Name}}({{$length := (len .Members)}}{{range $i,$item := .Members}} - val {{with $item}}{{lowCamelCase .Name}}: {{parseType .Type.Name}}{{end}}{{if ne $i (add $length -1)}},{{end}}{{end}} - ){{end}} - {{with .Service}} - {{range .Routes}}suspend fun {{routeToFuncName .Method .Path}}({{with .RequestType}}{{if ne .Name ""}} - req:{{.Name}},{{end}}{{end}} - onOk: (({{with .ResponseType}}{{.Name}}{{end}}) -> Unit)? = null, - onFail: ((String) -> Unit)? = null, - eventually: (() -> Unit)? = null - ){ - apiRequest("{{upperCase .Method}}","{{.Path}}",{{with .RequestType}}{{if ne .Name ""}}body=req,{{end}}{{end}} onOk = { {{with .ResponseType}} - onOk?.invoke({{if ne .Name ""}}Gson().fromJson(it,{{.Name}}::class.java){{end}}){{end}} - }, onFail = onFail, eventually =eventually) - } - {{end}}{{end}} -}` +var ( + //go:embed apibase.tpl + apiBaseTemplate string + //go:embed api.tpl + apiTemplate string ) func genBase(dir, pkg string, api *spec.ApiSpec) error { diff --git a/tools/goctl/api/new/api.tpl b/tools/goctl/api/new/api.tpl new file mode 100644 index 00000000..9d9898f5 --- /dev/null +++ b/tools/goctl/api/new/api.tpl @@ -0,0 +1,12 @@ +type Request { + Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` +} + +type Response { + Message string ` + "`" + `json:"message"` + "`" + ` +} + +service {{.name}}-api { + @handler {{.handler}}Handler + get /from/:name(Request) returns (Response) +} diff --git a/tools/goctl/api/new/newservice.go b/tools/goctl/api/new/newservice.go index 83b6fd20..c215c44e 100644 --- a/tools/goctl/api/new/newservice.go +++ b/tools/goctl/api/new/newservice.go @@ -1,11 +1,12 @@ package new import ( + _ "embed" "errors" + "html/template" "os" "path/filepath" "strings" - "text/template" "github.com/urfave/cli" "github.com/zeromicro/go-zero/tools/goctl/api/gogen" @@ -14,20 +15,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const apiTemplate = ` -type Request { - Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` -} - -type Response { - Message string ` + "`" + `json:"message"` + "`" + ` -} - -service {{.name}}-api { - @handler {{.handler}}Handler - get /from/:name(Request) returns (Response) -} -` +//go:embed api.tpl +var apiTemplate string // CreateServiceCommand fast create service func CreateServiceCommand(c *cli.Context) error { diff --git a/tools/goctl/api/tsgen/components.tpl b/tools/goctl/api/tsgen/components.tpl new file mode 100644 index 00000000..5a0cd9dd --- /dev/null +++ b/tools/goctl/api/tsgen/components.tpl @@ -0,0 +1,3 @@ +/ Code generated by goctl. DO NOT EDIT. + +{{.componentTypes}} diff --git a/tools/goctl/api/tsgen/gencomponents.go b/tools/goctl/api/tsgen/gencomponents.go index ce08280d..aabd704f 100644 --- a/tools/goctl/api/tsgen/gencomponents.go +++ b/tools/goctl/api/tsgen/gencomponents.go @@ -1,6 +1,7 @@ package tsgen import ( + _ "embed" "path" "strings" "text/template" @@ -10,12 +11,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const ( - componentsTemplate = `// Code generated by goctl. DO NOT EDIT. - -{{.componentTypes}} -` -) +//go:embed components.tpl +var componentsTemplate string func genComponents(dir string, api *spec.ApiSpec) error { types := api.Types diff --git a/tools/goctl/api/tsgen/genpacket.go b/tools/goctl/api/tsgen/genpacket.go index f8d66d05..99296ad4 100644 --- a/tools/goctl/api/tsgen/genpacket.go +++ b/tools/goctl/api/tsgen/genpacket.go @@ -1,6 +1,7 @@ package tsgen import ( + _ "embed" "fmt" "path" "strings" @@ -12,12 +13,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const ( - handlerTemplate = `{{.imports}} - -{{.apis}} -` -) +//go:embed handler.tpl +var handlerTemplate string func genHandler(dir, webAPI, caller string, api *spec.ApiSpec, unwrapAPI bool) error { filename := strings.Replace(api.Service.Name, "-api", "", 1) + ".ts" diff --git a/tools/goctl/api/tsgen/handler.tpl b/tools/goctl/api/tsgen/handler.tpl new file mode 100644 index 00000000..bd09f79c --- /dev/null +++ b/tools/goctl/api/tsgen/handler.tpl @@ -0,0 +1,3 @@ +{{.imports}} + +{{.apis}} diff --git a/tools/goctl/docker/docker.tpl b/tools/goctl/docker/docker.tpl new file mode 100644 index 00000000..40ef371d --- /dev/null +++ b/tools/goctl/docker/docker.tpl @@ -0,0 +1,32 @@ +FROM golang:{{.Version}}alpine AS builder + +LABEL stage=gobuilder + +ENV CGO_ENABLED 0 +{{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct +{{end}}{{if .HasTimezone}} +RUN apk update --no-cache && apk add --no-cache tzdata +{{end}} +WORKDIR /build + +ADD go.mod . +ADD go.sum . +RUN go mod download +COPY . . +{{if .Argument}}COPY {{.GoRelPath}}/etc /app/etc +{{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoRelPath}}/{{.GoFile}} + + +FROM {{.BaseImage}} + +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +{{if .HasTimezone}}COPY --from=builder /usr/share/zoneinfo/{{.Timezone}} /usr/share/zoneinfo/{{.Timezone}} +ENV TZ {{.Timezone}} +{{end}} +WORKDIR /app +COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}} +COPY --from=builder /app/etc /app/etc{{end}} +{{if .HasPort}} +EXPOSE {{.Port}} +{{end}} +CMD ["./{{.ExeFile}}"{{.Argument}}] diff --git a/tools/goctl/docker/template.go b/tools/goctl/docker/template.go index 8c1b6ab7..c18eab37 100644 --- a/tools/goctl/docker/template.go +++ b/tools/goctl/docker/template.go @@ -1,6 +1,8 @@ package docker import ( + _ "embed" + "github.com/urfave/cli" "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) @@ -8,41 +10,11 @@ import ( const ( category = "docker" dockerTemplateFile = "docker.tpl" - dockerTemplate = `FROM golang:{{.Version}}alpine AS builder - -LABEL stage=gobuilder - -ENV CGO_ENABLED 0 -{{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct -{{end}}{{if .HasTimezone}} -RUN apk update --no-cache && apk add --no-cache tzdata -{{end}} -WORKDIR /build - -ADD go.mod . -ADD go.sum . -RUN go mod download -COPY . . -{{if .Argument}}COPY {{.GoRelPath}}/etc /app/etc -{{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoRelPath}}/{{.GoFile}} - - -FROM {{.BaseImage}} - -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -{{if .HasTimezone}}COPY --from=builder /usr/share/zoneinfo/{{.Timezone}} /usr/share/zoneinfo/{{.Timezone}} -ENV TZ {{.Timezone}} -{{end}} -WORKDIR /app -COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}} -COPY --from=builder /app/etc /app/etc{{end}} -{{if .HasPort}} -EXPOSE {{.Port}} -{{end}} -CMD ["./{{.ExeFile}}"{{.Argument}}] -` ) +//go:embed docker.tpl +var dockerTemplate string + // Clean deletes all templates files func Clean() error { return pathx.Clean(category) diff --git a/tools/goctl/internal/version/version.go b/tools/goctl/internal/version/version.go index ff9e96ba..1bbbe76e 100644 --- a/tools/goctl/internal/version/version.go +++ b/tools/goctl/internal/version/version.go @@ -6,7 +6,7 @@ import ( ) // BuildVersion is the version of goctl. -const BuildVersion = "1.3.4" +const BuildVersion = "1.3.5" var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5} diff --git a/tools/goctl/kube/deployment.go b/tools/goctl/kube/deployment.tpl similarity index 97% rename from tools/goctl/kube/deployment.go rename to tools/goctl/kube/deployment.tpl index 0e493445..7b81d609 100644 --- a/tools/goctl/kube/deployment.go +++ b/tools/goctl/kube/deployment.tpl @@ -1,6 +1,4 @@ -package kube - -var deploymentTemplate = `apiVersion: apps/v1 +apiVersion: apps/v1 kind: Deployment metadata: name: {{.Name}} @@ -115,4 +113,3 @@ spec: resource: name: memory targetAverageUtilization: 80 -` diff --git a/tools/goctl/kube/job.go b/tools/goctl/kube/job.tpl similarity index 94% rename from tools/goctl/kube/job.go rename to tools/goctl/kube/job.tpl index a114fe79..0da72ede 100644 --- a/tools/goctl/kube/job.go +++ b/tools/goctl/kube/job.tpl @@ -1,6 +1,4 @@ -package kube - -var jobTmeplate = `apiVersion: batch/v1 +apiVersion: batch/v1 kind: CronJob metadata: name: {{.Name}} @@ -37,4 +35,3 @@ spec: - name: timezone hostPath: path: /usr/share/zoneinfo/Asia/Shanghai -` diff --git a/tools/goctl/kube/kube.go b/tools/goctl/kube/kube.go index 79575bff..060ce652 100644 --- a/tools/goctl/kube/kube.go +++ b/tools/goctl/kube/kube.go @@ -1,6 +1,7 @@ package kube import ( + _ "embed" "errors" "fmt" "text/template" @@ -19,6 +20,13 @@ const ( portLimit = 32767 ) +var ( + //go:embed deployment.tpl + deploymentTemplate string + //go:embed job.tpl + jobTemplate string +) + // Deployment describes the k8s deployment yaml type Deployment struct { Name string @@ -113,7 +121,7 @@ func Clean() error { func GenTemplates(_ *cli.Context) error { return pathx.InitTemplates(category, map[string]string{ deployTemplateFile: deploymentTemplate, - jobTemplateFile: jobTmeplate, + jobTemplateFile: jobTemplate, }) } @@ -131,6 +139,6 @@ func Update() error { return pathx.InitTemplates(category, map[string]string{ deployTemplateFile: deploymentTemplate, - jobTemplateFile: jobTmeplate, + jobTemplateFile: jobTemplate, }) } diff --git a/tools/goctl/model/mongo/template/error.tpl b/tools/goctl/model/mongo/template/error.tpl new file mode 100644 index 00000000..cb8be412 --- /dev/null +++ b/tools/goctl/model/mongo/template/error.tpl @@ -0,0 +1,6 @@ +package model + +import "errors" + +var ErrNotFound = errors.New("not found") +var ErrInvalidObjectId = errors.New("invalid objectId") diff --git a/tools/goctl/model/mongo/template/model.tpl b/tools/goctl/model/mongo/template/model.tpl new file mode 100644 index 00000000..bf807d01 --- /dev/null +++ b/tools/goctl/model/mongo/template/model.tpl @@ -0,0 +1,98 @@ +package model + +import ( + "context" + + "github.com/globalsign/mgo/bson" + {{if .Cache}}cachec "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/mongoc"{{else}}"github.com/zeromicro/go-zero/core/stores/mongo"{{end}} +) + +{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.Type}}:"{{end}} + +type {{.Type}}Model interface{ + Insert(ctx context.Context,data *{{.Type}}) error + FindOne(ctx context.Context,id string) (*{{.Type}}, error) + Update(ctx context.Context,data *{{.Type}}) error + Delete(ctx context.Context,id string) error +} + +type default{{.Type}}Model struct { + {{if .Cache}}*mongoc.Model{{else}}*mongo.Model{{end}} +} + +func New{{.Type}}Model(url, collection string{{if .Cache}}, c cachec.CacheConf{{end}}) {{.Type}}Model { + return &default{{.Type}}Model{ + Model: {{if .Cache}}mongoc.MustNewModel(url, collection, c){{else}}mongo.MustNewModel(url, collection){{end}}, + } +} + + +func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error { + if !data.ID.Valid() { + data.ID = bson.NewObjectId() + } + + session, err := m.TakeSession() + if err != nil { + return err + } + + defer m.PutSession(session) + return m.GetCollection(session).Insert(data) +} + +func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) { + if !bson.IsObjectIdHex(id) { + return nil, ErrInvalidObjectId + } + + session, err := m.TakeSession() + if err != nil { + return nil, err + } + + defer m.PutSession(session) + var data {{.Type}} + {{if .Cache}}key := prefix{{.Type}}CacheKey + id + err = m.GetCollection(session).FindOneId(&data, key, bson.ObjectIdHex(id)) + {{- else}} + err = m.GetCollection(session).FindId(bson.ObjectIdHex(id)).One(&data) + {{- end}} + switch err { + case nil: + return &data,nil + case {{if .Cache}}mongoc.ErrNotFound{{else}}mongo.ErrNotFound{{end}}: + return nil,ErrNotFound + default: + return nil,err + } +} + +func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) error { + session, err := m.TakeSession() + if err != nil { + return err + } + + defer m.PutSession(session) + {{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex() + return m.GetCollection(session).UpdateId(data.ID, data, key) + {{- else}} + return m.GetCollection(session).UpdateId(data.ID, data) + {{- end}} +} + +func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) error { + session, err := m.TakeSession() + if err != nil { + return err + } + + defer m.PutSession(session) + {{if .Cache}}key := prefix{{.Type}}CacheKey + id + return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id), key) + {{- else}} + return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id)) + {{- end}} +} diff --git a/tools/goctl/model/mongo/template/template.go b/tools/goctl/model/mongo/template/template.go index 5ab4865a..9477f5f2 100644 --- a/tools/goctl/model/mongo/template/template.go +++ b/tools/goctl/model/mongo/template/template.go @@ -1,112 +1,11 @@ package template -// Text provides the default template for model to generate -var Text = `package model +import _ "embed" -import ( - "context" - - "github.com/globalsign/mgo/bson" - {{if .Cache}}cachec "github.com/zeromicro/go-zero/core/stores/cache" - "github.com/zeromicro/go-zero/core/stores/mongoc"{{else}}"github.com/zeromicro/go-zero/core/stores/mongo"{{end}} -) - -{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.Type}}:"{{end}} - -type {{.Type}}Model interface{ - Insert(ctx context.Context,data *{{.Type}}) error - FindOne(ctx context.Context,id string) (*{{.Type}}, error) - Update(ctx context.Context,data *{{.Type}}) error - Delete(ctx context.Context,id string) error -} - -type default{{.Type}}Model struct { - {{if .Cache}}*mongoc.Model{{else}}*mongo.Model{{end}} -} - -func New{{.Type}}Model(url, collection string{{if .Cache}}, c cachec.CacheConf{{end}}) {{.Type}}Model { - return &default{{.Type}}Model{ - Model: {{if .Cache}}mongoc.MustNewModel(url, collection, c){{else}}mongo.MustNewModel(url, collection){{end}}, - } -} - - -func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error { - if !data.ID.Valid() { - data.ID = bson.NewObjectId() - } - - session, err := m.TakeSession() - if err != nil { - return err - } - - defer m.PutSession(session) - return m.GetCollection(session).Insert(data) -} - -func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) { - if !bson.IsObjectIdHex(id) { - return nil, ErrInvalidObjectId - } - - session, err := m.TakeSession() - if err != nil { - return nil, err - } - - defer m.PutSession(session) - var data {{.Type}} - {{if .Cache}}key := prefix{{.Type}}CacheKey + id - err = m.GetCollection(session).FindOneId(&data, key, bson.ObjectIdHex(id)) - {{- else}} - err = m.GetCollection(session).FindId(bson.ObjectIdHex(id)).One(&data) - {{- end}} - switch err { - case nil: - return &data,nil - case {{if .Cache}}mongoc.ErrNotFound{{else}}mongo.ErrNotFound{{end}}: - return nil,ErrNotFound - default: - return nil,err - } -} - -func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) error { - session, err := m.TakeSession() - if err != nil { - return err - } - - defer m.PutSession(session) - {{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex() - return m.GetCollection(session).UpdateId(data.ID, data, key) - {{- else}} - return m.GetCollection(session).UpdateId(data.ID, data) - {{- end}} -} - -func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) error { - session, err := m.TakeSession() - if err != nil { - return err - } - - defer m.PutSession(session) - {{if .Cache}}key := prefix{{.Type}}CacheKey + id - return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id), key) - {{- else}} - return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id)) - {{- end}} -} -` +// Text provides the default template for model to generate. +//go:embed model.tpl +var Text string // Error provides the default template for error definition in mongo code generation. -var Error = ` -package model - -import "errors" - -var ErrNotFound = errors.New("not found") -var ErrInvalidObjectId = errors.New("invalid objectId") -` +//go:embed error.tpl +var Error string diff --git a/tools/goctl/rpc/generator/call.tpl b/tools/goctl/rpc/generator/call.tpl new file mode 100644 index 00000000..27b48796 --- /dev/null +++ b/tools/goctl/rpc/generator/call.tpl @@ -0,0 +1,33 @@ +{{.head}} + +package {{.filePackage}} + +import ( + "context" + + {{.pbPackage}} + {{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}} + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + {{.alias}} + + {{.serviceName}} interface { + {{.interface}} + } + + default{{.serviceName}} struct { + cli zrpc.Client + } +) + +func New{{.serviceName}}(cli zrpc.Client) {{.serviceName}} { + return &default{{.serviceName}}{ + cli: cli, + } +} + +{{.functions}} diff --git a/tools/goctl/rpc/generator/config.tpl b/tools/goctl/rpc/generator/config.tpl new file mode 100644 index 00000000..c1f85b99 --- /dev/null +++ b/tools/goctl/rpc/generator/config.tpl @@ -0,0 +1,7 @@ +package config + +import "github.com/zeromicro/go-zero/zrpc" + +type Config struct { + zrpc.RpcServerConf +} diff --git a/tools/goctl/rpc/generator/etc.tpl b/tools/goctl/rpc/generator/etc.tpl new file mode 100644 index 00000000..cea664b6 --- /dev/null +++ b/tools/goctl/rpc/generator/etc.tpl @@ -0,0 +1,6 @@ +Name: {{.serviceName}}.rpc +ListenOn: 127.0.0.1:8080 +Etcd: + Hosts: + - 127.0.0.1:2379 + Key: {{.serviceName}}.rpc diff --git a/tools/goctl/rpc/generator/gencall.go b/tools/goctl/rpc/generator/gencall.go index f8258a3f..86706761 100644 --- a/tools/goctl/rpc/generator/gencall.go +++ b/tools/goctl/rpc/generator/gencall.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" "sort" @@ -17,41 +18,6 @@ import ( ) const ( - callTemplateText = `{{.head}} - -package {{.filePackage}} - -import ( - "context" - - {{.pbPackage}} - {{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}} - - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" -) - -type ( - {{.alias}} - - {{.serviceName}} interface { - {{.interface}} - } - - default{{.serviceName}} struct { - cli zrpc.Client - } -) - -func New{{.serviceName}}(cli zrpc.Client) {{.serviceName}} { - return &default{{.serviceName}}{ - cli: cli, - } -} - -{{.functions}} -` - callInterfaceFunctionTemplate = `{{if .hasComment}}{{.comment}} {{end}}{{.method}}(ctx context.Context{{if .hasReq}}, in *{{.pbRequest}}{{end}}, opts ...grpc.CallOption) ({{if .notStream}}*{{.pbResponse}}, {{else}}{{.streamBody}},{{end}} error)` @@ -64,6 +30,9 @@ func (m *default{{.serviceName}}) {{.method}}(ctx context.Context{{if .hasReq}}, ` ) +//go:embed call.tpl +var callTemplateText string + // GenCall generates the rpc client code, which is the entry point for the rpc service call. // It is a layer of encapsulation for the rpc client and shields the details in the pb. func (g *Generator) GenCall(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { diff --git a/tools/goctl/rpc/generator/genconfig.go b/tools/goctl/rpc/generator/genconfig.go index 46567a5a..a81a07a8 100644 --- a/tools/goctl/rpc/generator/genconfig.go +++ b/tools/goctl/rpc/generator/genconfig.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "io/ioutil" "os" "path/filepath" @@ -11,14 +12,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const configTemplate = `package config - -import "github.com/zeromicro/go-zero/zrpc" - -type Config struct { - zrpc.RpcServerConf -} -` +//go:embed config.tpl +var configTemplate string // GenConfig generates the configuration structure definition file of the rpc service, // which contains the zrpc.RpcServerConf configuration item by default. diff --git a/tools/goctl/rpc/generator/genetc.go b/tools/goctl/rpc/generator/genetc.go index 4b9fb6fe..a5d92e0c 100644 --- a/tools/goctl/rpc/generator/genetc.go +++ b/tools/goctl/rpc/generator/genetc.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" "strings" @@ -13,13 +14,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/stringx" ) -const etcTemplate = `Name: {{.serviceName}}.rpc -ListenOn: 127.0.0.1:8080 -Etcd: - Hosts: - - 127.0.0.1:2379 - Key: {{.serviceName}}.rpc -` +//go:embed etc.tpl +var etcTemplate string // GenEtc generates the yaml configuration file of the rpc service, // including host, port monitoring configuration items and etcd configuration diff --git a/tools/goctl/rpc/generator/genlogic.go b/tools/goctl/rpc/generator/genlogic.go index 968c3720..9cbc9670 100644 --- a/tools/goctl/rpc/generator/genlogic.go +++ b/tools/goctl/rpc/generator/genlogic.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" "strings" @@ -14,40 +15,16 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/stringx" ) -const ( - logicTemplate = `package logic - -import ( - "context" - - {{.imports}} - - "github.com/zeromicro/go-zero/core/logx" -) - -type {{.logicName}} struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func New{{.logicName}}(ctx context.Context,svcCtx *svc.ServiceContext) *{{.logicName}} { - return &{{.logicName}}{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} -{{.functions}} -` - logicFunctionTemplate = `{{if .hasComment}}{{.comment}}{{end}} +const logicFunctionTemplate = `{{if .hasComment}}{{.comment}}{{end}} func (l *{{.logicName}}) {{.method}} ({{if .hasReq}}in {{.request}}{{if .stream}},stream {{.streamBody}}{{end}}{{else}}stream {{.streamBody}}{{end}}) ({{if .hasReply}}{{.response}},{{end}} error) { // todo: add your logic here and delete this line return {{if .hasReply}}&{{.responseType}}{},{{end}} nil } ` -) + +//go:embed logic.tpl +var logicTemplate string // GenLogic generates the logic file of the rpc service, which corresponds to the RPC definition items in proto. func (g *Generator) GenLogic(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { diff --git a/tools/goctl/rpc/generator/genmain.go b/tools/goctl/rpc/generator/genmain.go index 91bfae85..c5ca2aff 100644 --- a/tools/goctl/rpc/generator/genmain.go +++ b/tools/goctl/rpc/generator/genmain.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" "strings" @@ -13,44 +14,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/stringx" ) -const mainTemplate = `package main - -import ( - "flag" - "fmt" - - {{.imports}} - - "github.com/zeromicro/go-zero/core/conf" - "github.com/zeromicro/go-zero/core/service" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file") - -func main() { - flag.Parse() - - var c config.Config - conf.MustLoad(*configFile, &c) - ctx := svc.NewServiceContext(c) - svr := server.New{{.serviceNew}}Server(ctx) - - s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { - {{.pkg}}.Register{{.service}}Server(grpcServer, svr) - - if c.Mode == service.DevMode || c.Mode == service.TestMode { - reflection.Register(grpcServer) - } - }) - defer s.Stop() - - fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) - s.Start() -} -` +//go:embed main.tpl +var mainTemplate string // GenMain generates the main file of the rpc service, which is an rpc service program call entry func (g *Generator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { diff --git a/tools/goctl/rpc/generator/genserver.go b/tools/goctl/rpc/generator/genserver.go index 587a04e6..2a327ec5 100644 --- a/tools/goctl/rpc/generator/genserver.go +++ b/tools/goctl/rpc/generator/genserver.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" "strings" @@ -14,38 +15,16 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/stringx" ) -const ( - serverTemplate = `{{.head}} - -package server - -import ( - {{if .notStream}}"context"{{end}} - - {{.imports}} -) - -type {{.server}}Server struct { - svcCtx *svc.ServiceContext - {{.unimplementedServer}} -} - -func New{{.server}}Server(svcCtx *svc.ServiceContext) *{{.server}}Server { - return &{{.server}}Server{ - svcCtx: svcCtx, - } -} - -{{.funcs}} -` - functionTemplate = ` +const functionTemplate = ` {{if .hasComment}}{{.comment}}{{end}} func (s *{{.server}}Server) {{.method}} ({{if .notStream}}ctx context.Context,{{if .hasReq}} in {{.request}}{{end}}{{else}}{{if .hasReq}} in {{.request}},{{end}}stream {{.streamBody}}{{end}}) ({{if .notStream}}{{.response}},{{end}}error) { l := logic.New{{.logicName}}({{if .notStream}}ctx,{{else}}stream.Context(),{{end}}s.svcCtx) return l.{{.method}}({{if .hasReq}}in{{if .stream}} ,stream{{end}}{{else}}{{if .stream}}stream{{end}}{{end}}) } ` -) + +//go:embed server.tpl +var serverTemplate string // GenServer generates rpc server file, which is an implementation of rpc server func (g *Generator) GenServer(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { diff --git a/tools/goctl/rpc/generator/gensvc.go b/tools/goctl/rpc/generator/gensvc.go index c96726fd..fcad078a 100644 --- a/tools/goctl/rpc/generator/gensvc.go +++ b/tools/goctl/rpc/generator/gensvc.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "fmt" "path/filepath" @@ -11,20 +12,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) -const svcTemplate = `package svc - -import {{.imports}} - -type ServiceContext struct { - Config config.Config -} - -func NewServiceContext(c config.Config) *ServiceContext { - return &ServiceContext{ - Config:c, - } -} -` +//go:embed svc.tpl +var svcTemplate string // GenSvc generates the servicecontext.go file, which is the resource dependency of a service, // such as rpc dependency, model dependency, etc. diff --git a/tools/goctl/rpc/generator/logic.tpl b/tools/goctl/rpc/generator/logic.tpl new file mode 100644 index 00000000..b4ca2a1b --- /dev/null +++ b/tools/goctl/rpc/generator/logic.tpl @@ -0,0 +1,24 @@ +package logic + +import ( + "context" + + {{.imports}} + + "github.com/zeromicro/go-zero/core/logx" +) + +type {{.logicName}} struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func New{{.logicName}}(ctx context.Context,svcCtx *svc.ServiceContext) *{{.logicName}} { + return &{{.logicName}}{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} +{{.functions}} diff --git a/tools/goctl/rpc/generator/main.tpl b/tools/goctl/rpc/generator/main.tpl new file mode 100644 index 00000000..4e13a7c5 --- /dev/null +++ b/tools/goctl/rpc/generator/main.tpl @@ -0,0 +1,37 @@ +package main + +import ( + "flag" + "fmt" + + {{.imports}} + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/service" + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file") + +func main() { + flag.Parse() + + var c config.Config + conf.MustLoad(*configFile, &c) + ctx := svc.NewServiceContext(c) + svr := server.New{{.serviceNew}}Server(ctx) + + s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { + {{.pkg}}.Register{{.service}}Server(grpcServer, svr) + + if c.Mode == service.DevMode || c.Mode == service.TestMode { + reflection.Register(grpcServer) + } + }) + defer s.Stop() + + fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) + s.Start() +} diff --git a/tools/goctl/rpc/generator/prototmpl.go b/tools/goctl/rpc/generator/prototmpl.go index e858e9d8..f60aa031 100644 --- a/tools/goctl/rpc/generator/prototmpl.go +++ b/tools/goctl/rpc/generator/prototmpl.go @@ -1,6 +1,7 @@ package generator import ( + _ "embed" "path/filepath" "strings" @@ -9,23 +10,8 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util/stringx" ) -const rpcTemplateText = `syntax = "proto3"; - -package {{.package}}; -option go_package="./{{.package}}"; - -message Request { - string ping = 1; -} - -message Response { - string pong = 1; -} - -service {{.serviceName}} { - rpc Ping(Request) returns(Response); -} -` +//go:embed rpc.tpl +var rpcTemplateText string // ProtoTmpl returns a sample of a proto file func ProtoTmpl(out string) error { diff --git a/tools/goctl/rpc/generator/rpc.tpl b/tools/goctl/rpc/generator/rpc.tpl new file mode 100644 index 00000000..76daa944 --- /dev/null +++ b/tools/goctl/rpc/generator/rpc.tpl @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package {{.package}}; +option go_package="./{{.package}}"; + +message Request { + string ping = 1; +} + +message Response { + string pong = 1; +} + +service {{.serviceName}} { + rpc Ping(Request) returns(Response); +} diff --git a/tools/goctl/rpc/generator/server.tpl b/tools/goctl/rpc/generator/server.tpl new file mode 100644 index 00000000..84a2f9c1 --- /dev/null +++ b/tools/goctl/rpc/generator/server.tpl @@ -0,0 +1,22 @@ +{{.head}} + +package server + +import ( + {{if .notStream}}"context"{{end}} + + {{.imports}} +) + +type {{.server}}Server struct { + svcCtx *svc.ServiceContext + {{.unimplementedServer}} +} + +func New{{.server}}Server(svcCtx *svc.ServiceContext) *{{.server}}Server { + return &{{.server}}Server{ + svcCtx: svcCtx, + } +} + +{{.funcs}} diff --git a/tools/goctl/rpc/generator/svc.tpl b/tools/goctl/rpc/generator/svc.tpl new file mode 100644 index 00000000..cf2b47af --- /dev/null +++ b/tools/goctl/rpc/generator/svc.tpl @@ -0,0 +1,13 @@ +package svc + +import {{.imports}} + +type ServiceContext struct { + Config config.Config +} + +func NewServiceContext(c config.Config) *ServiceContext { + return &ServiceContext{ + Config:c, + } +}