From e6ef1fca1282c1c93305f76da7c37f76c65e9577 Mon Sep 17 00:00:00 2001 From: kingxt Date: Fri, 26 Feb 2021 16:11:47 +0800 Subject: [PATCH] Code optimized (#523) * optimized markdown generator * optimized markdown generator * optimized markdown generator * add more comment * add comment * add comment * add comments for rpc tool * add comments for model tool * add comments for model tool * add comments for model tool * add comments for config tool * add comments for config tool * add comments * add comments * add comments * add comments * add comment * remove rpc main head info * add comment * optimized Co-authored-by: anqiansong --- tools/goctl/api/docgen/gen.go | 2 +- tools/goctl/api/format/format.go | 12 +- tools/goctl/api/gogen/gen.go | 2 + tools/goctl/api/gogen/genhandlers.go | 6 +- tools/goctl/api/gogen/gentypes.go | 1 + tools/goctl/api/javagen/gen.go | 1 + tools/goctl/api/ktgen/cmd.go | 1 + tools/goctl/api/new/newservice.go | 3 +- tools/goctl/api/parser/g4/ast/api.go | 5 + tools/goctl/api/parser/g4/ast/apiparser.go | 6 + tools/goctl/api/parser/g4/ast/ast.go | 12 ++ tools/goctl/api/parser/g4/ast/import.go | 10 ++ tools/goctl/api/parser/g4/ast/info.go | 4 + tools/goctl/api/parser/g4/ast/kv.go | 6 + tools/goctl/api/parser/g4/ast/placeholder.go | 2 + tools/goctl/api/parser/g4/ast/service.go | 42 ++++++- tools/goctl/api/parser/g4/ast/syntax.go | 6 + tools/goctl/api/parser/g4/ast/type.go | 68 +++++++++++- .../api/parser/g4/gen/api/apiparser_parser.go | 2 +- .../goctl/api/parser/g4/gen/api/baseparser.go | 5 +- .../api/parser/g4/test/apiparser_test.go | 26 ++--- tools/goctl/api/parser/parser.go | 2 + tools/goctl/api/spec/fn.go | 32 +++--- tools/goctl/api/spec/name.go | 6 + tools/goctl/api/spec/spec.go | 19 +++- tools/goctl/api/spec/tags.go | 6 + tools/goctl/api/tsgen/gen.go | 7 +- tools/goctl/api/tsgen/genpacket.go | 14 +-- tools/goctl/api/tsgen/util.go | 2 +- tools/goctl/api/util/case.go | 18 +-- tools/goctl/api/util/util.go | 6 + tools/goctl/api/validate/validate.go | 1 + tools/goctl/config/config.go | 87 +-------------- tools/goctl/configgen/genconfig.go | 1 + tools/goctl/docker/docker.go | 2 + tools/goctl/docker/template.go | 5 + tools/goctl/goctl.go | 8 +- tools/goctl/kube/kube.go | 1 + tools/goctl/model/sql/builderx/builder.go | 4 + .../goctl/model/sql/builderx/builder_test.go | 28 ++--- tools/goctl/model/sql/command/command.go | 6 +- tools/goctl/model/sql/converter/types.go | 1 + tools/goctl/model/sql/gen/error.go | 5 - tools/goctl/model/sql/gen/gen.go | 4 + tools/goctl/model/sql/gen/gen_test.go | 2 +- tools/goctl/model/sql/gen/keys.go | 25 +++-- tools/goctl/model/sql/gen/template.go | 5 + .../model/sql/model/informationschemamodel.go | 9 +- tools/goctl/model/sql/parser/parser.go | 7 ++ tools/goctl/model/sql/template/delete.go | 2 + tools/goctl/model/sql/template/errors.go | 1 + tools/goctl/model/sql/template/field.go | 1 + tools/goctl/model/sql/template/import.go | 2 + tools/goctl/model/sql/template/insert.go | 2 + tools/goctl/model/sql/template/model.go | 1 + tools/goctl/model/sql/template/new.go | 1 + tools/goctl/model/sql/template/tag.go | 1 + tools/goctl/model/sql/template/types.go | 1 + tools/goctl/model/sql/template/update.go | 2 + tools/goctl/model/sql/template/vars.go | 1 + .../goctl/model/sql/test/model/model_test.go | 56 +++++----- .../model/sql/test/model/studentmodel.go | 23 ++-- tools/goctl/model/sql/test/model/usermodel.go | 7 +- tools/goctl/model/sql/test/model/vars.go | 1 + tools/goctl/model/sql/test/orm.go | 10 +- tools/goctl/model/sql/test/sqlconn.go | 9 ++ tools/goctl/model/sql/test/utils.go | 5 - tools/goctl/model/sql/util/matcher.go | 2 +- tools/goctl/model/sql/util/slice.go | 1 + tools/goctl/plugin/plugin.go | 3 + tools/goctl/rpc/cli/cli.go | 15 +-- tools/goctl/rpc/execx/execx.go | 3 + tools/goctl/rpc/generator/defaultgenerator.go | 12 +- tools/goctl/rpc/generator/gen.go | 18 ++- tools/goctl/rpc/generator/gen_test.go | 2 +- tools/goctl/rpc/generator/gencall.go | 8 +- tools/goctl/rpc/generator/genconfig.go | 6 +- tools/goctl/rpc/generator/generator.go | 1 + tools/goctl/rpc/generator/genetc.go | 4 +- tools/goctl/rpc/generator/genlogic.go | 5 +- tools/goctl/rpc/generator/genmain.go | 9 +- tools/goctl/rpc/generator/genpb.go | 4 +- tools/goctl/rpc/generator/genserver.go | 5 +- tools/goctl/rpc/generator/gensvc.go | 4 +- tools/goctl/rpc/generator/mkdir.go | 4 + tools/goctl/rpc/generator/prototmpl.go | 1 + tools/goctl/rpc/generator/template.go | 7 ++ tools/goctl/rpc/parser/comment.go | 1 + tools/goctl/rpc/parser/import.go | 1 + tools/goctl/rpc/parser/message.go | 5 +- tools/goctl/rpc/parser/option.go | 1 + tools/goctl/rpc/parser/parser.go | 16 ++- tools/goctl/rpc/parser/proto.go | 1 + tools/goctl/rpc/parser/rpc.go | 1 + tools/goctl/rpc/parser/service.go | 2 + tools/goctl/tpl/templates.go | 5 + tools/goctl/update/config/config.go | 1 + tools/goctl/upgrade/upgrade.go | 2 + tools/goctl/util/console/console.go | 4 +- tools/goctl/util/file.go | 104 +++++++++++++++++- tools/goctl/util/files.go | 95 ---------------- tools/goctl/util/head.go | 1 + tools/goctl/util/path.go | 6 + tools/goctl/util/string.go | 5 + 104 files changed, 651 insertions(+), 375 deletions(-) delete mode 100644 tools/goctl/model/sql/gen/error.go delete mode 100644 tools/goctl/util/files.go diff --git a/tools/goctl/api/docgen/gen.go b/tools/goctl/api/docgen/gen.go index b3c6e250..f8ca43e8 100644 --- a/tools/goctl/api/docgen/gen.go +++ b/tools/goctl/api/docgen/gen.go @@ -29,7 +29,7 @@ func DocCommand(c *cli.Context) error { } if !util.FileExists(dir) { - return errors.New(fmt.Sprintf("dir %s not exsit", dir)) + return fmt.Errorf("dir %s not exsit", dir) } dir, err := filepath.Abs(dir) diff --git a/tools/goctl/api/format/format.go b/tools/goctl/api/format/format.go index 923401d3..7e944da5 100644 --- a/tools/goctl/api/format/format.go +++ b/tools/goctl/api/format/format.go @@ -25,12 +25,13 @@ const ( rightBrace = "}" ) +// GoFormatApi format api file func GoFormatApi(c *cli.Context) error { useStdin := c.Bool("stdin") var be errorx.BatchError if useStdin { - if err := ApiFormatByStdin(); err != nil { + if err := apiFormatByStdin(); err != nil { be.Add(err) } } else { @@ -63,7 +64,7 @@ func GoFormatApi(c *cli.Context) error { return be.Err() } -func ApiFormatByStdin() error { +func apiFormatByStdin() error { data, err := ioutil.ReadAll(os.Stdin) if err != nil { return err @@ -78,6 +79,7 @@ func ApiFormatByStdin() error { return err } +// ApiFormatByPath format api from file path func ApiFormatByPath(apiFilePath string) error { data, err := ioutil.ReadFile(apiFilePath) if err != nil { @@ -135,19 +137,19 @@ func apiFormat(data string) (string, error) { noCommentLine := util.RemoveComment(line) if noCommentLine == rightParenthesis || noCommentLine == rightBrace { - tapCount -= 1 + tapCount-- } if tapCount < 0 { line := strings.TrimSuffix(noCommentLine, rightBrace) line = strings.TrimSpace(line) if strings.HasSuffix(line, leftBrace) { - tapCount += 1 + tapCount++ } } util.WriteIndent(&builder, tapCount) builder.WriteString(line + ctlutil.NL) if strings.HasSuffix(noCommentLine, leftParenthesis) || strings.HasSuffix(noCommentLine, leftBrace) { - tapCount += 1 + tapCount++ } preLine = line } diff --git a/tools/goctl/api/gogen/gen.go b/tools/goctl/api/gogen/gen.go index 161c5c94..025d0007 100644 --- a/tools/goctl/api/gogen/gen.go +++ b/tools/goctl/api/gogen/gen.go @@ -25,6 +25,7 @@ const tmpFile = "%s-%d" var tmpDir = path.Join(os.TempDir(), "goctl") +// GoCommand gen go project files from command line func GoCommand(c *cli.Context) error { apiFile := c.String("api") dir := c.String("dir") @@ -40,6 +41,7 @@ func GoCommand(c *cli.Context) error { return DoGenProject(apiFile, dir, namingStyle) } +// DoGenProject gen go project files with api file func DoGenProject(apiFile, dir, style string) error { api, err := parser.Parse(apiFile) if err != nil { diff --git a/tools/goctl/api/gogen/genhandlers.go b/tools/goctl/api/gogen/genhandlers.go index 5a3a49bd..d82dc14c 100644 --- a/tools/goctl/api/gogen/genhandlers.go +++ b/tools/goctl/api/gogen/genhandlers.go @@ -39,7 +39,7 @@ func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc { } ` -type Handler struct { +type handlerInfo struct { ImportPackages string HandlerName string RequestType string @@ -59,7 +59,7 @@ func genHandler(dir string, cfg *config.Config, group spec.Group, route spec.Rou return err } - return doGenToFile(dir, handler, cfg, group, route, Handler{ + return doGenToFile(dir, handler, cfg, group, route, handlerInfo{ ImportPackages: genHandlerImports(group, route, parentPkg), HandlerName: handler, RequestType: util.Title(route.RequestTypeName()), @@ -71,7 +71,7 @@ func genHandler(dir string, cfg *config.Config, group spec.Group, route spec.Rou } func doGenToFile(dir, handler string, cfg *config.Config, group spec.Group, - route spec.Route, handleObj Handler) error { + route spec.Route, handleObj handlerInfo) error { filename, err := format.FileNamingFormat(cfg.NamingFormat, handler) if err != nil { return err diff --git a/tools/goctl/api/gogen/gentypes.go b/tools/goctl/api/gogen/gentypes.go index b4a123fc..ae4dc4d1 100644 --- a/tools/goctl/api/gogen/gentypes.go +++ b/tools/goctl/api/gogen/gentypes.go @@ -25,6 +25,7 @@ import ( ` ) +// BuildTypes gen types to string func BuildTypes(types []spec.Type) (string, error) { var builder strings.Builder first := true diff --git a/tools/goctl/api/javagen/gen.go b/tools/goctl/api/javagen/gen.go index ec687e43..fd88087e 100644 --- a/tools/goctl/api/javagen/gen.go +++ b/tools/goctl/api/javagen/gen.go @@ -12,6 +12,7 @@ import ( "github.com/urfave/cli" ) +// JavaCommand the generate java code command entrance func JavaCommand(c *cli.Context) error { apiFile := c.String("api") dir := c.String("dir") diff --git a/tools/goctl/api/ktgen/cmd.go b/tools/goctl/api/ktgen/cmd.go index 2a845898..88adeb7c 100644 --- a/tools/goctl/api/ktgen/cmd.go +++ b/tools/goctl/api/ktgen/cmd.go @@ -7,6 +7,7 @@ import ( "github.com/urfave/cli" ) +// KtCommand the generate kotlin code command entrance func KtCommand(c *cli.Context) error { apiFile := c.String("api") if apiFile == "" { diff --git a/tools/goctl/api/new/newservice.go b/tools/goctl/api/new/newservice.go index 8d19c4c7..2be81233 100644 --- a/tools/goctl/api/new/newservice.go +++ b/tools/goctl/api/new/newservice.go @@ -27,7 +27,8 @@ service {{.name}}-api { } ` -func NewService(c *cli.Context) error { +// CreateServiceCommand fast create service +func CreateServiceCommand(c *cli.Context) error { args := c.Args() dirName := args.First() if len(dirName) == 0 { diff --git a/tools/goctl/api/parser/g4/ast/api.go b/tools/goctl/api/parser/g4/ast/api.go index 9c12f91d..3b95a694 100644 --- a/tools/goctl/api/parser/g4/ast/api.go +++ b/tools/goctl/api/parser/g4/ast/api.go @@ -7,6 +7,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// Api describes syntax for api type Api struct { LinePrefix string Syntax *SyntaxExpr @@ -21,6 +22,7 @@ type Api struct { routeM map[string]PlaceHolder } +// VisitApi implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitApi(ctx *api.ApiContext) interface{} { var final Api final.importM = map[string]PlaceHolder{} @@ -152,6 +154,7 @@ func (v *ApiVisitor) acceptSyntax(root *Api, final *Api) { } } +// VisitSpec implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitSpec(ctx *api.SpecContext) interface{} { var root Api if ctx.SyntaxLit() != nil { @@ -178,11 +181,13 @@ func (v *ApiVisitor) VisitSpec(ctx *api.SpecContext) interface{} { return &root } +// Format provides a formatter for api command, now nothing to do func (a *Api) Format() error { // todo return nil } +// Equal compares whether the element literals in two Api are equal func (a *Api) Equal(v interface{}) bool { if v == nil { return false diff --git a/tools/goctl/api/parser/g4/ast/apiparser.go b/tools/goctl/api/parser/g4/ast/apiparser.go index 3b0042eb..2edeaec2 100644 --- a/tools/goctl/api/parser/g4/ast/apiparser.go +++ b/tools/goctl/api/parser/g4/ast/apiparser.go @@ -12,6 +12,7 @@ import ( ) type ( + // Parser provides api parsing capabilities Parser struct { linePrefix string debug bool @@ -19,9 +20,11 @@ type ( antlr.DefaultErrorListener } + // ParserOption defines an function with argument Parser ParserOption func(p *Parser) ) +// NewParser creates an instance for Parser func NewParser(options ...ParserOption) *Parser { p := &Parser{ log: console.NewColorConsole(), @@ -425,6 +428,7 @@ func (p *Parser) readContent(filename string) (string, error) { return string(data), nil } +// SyntaxError accepts errors and panic it func (p *Parser) SyntaxError(_ antlr.Recognizer, _ interface{}, line, column int, msg string, _ antlr.RecognitionException) { str := fmt.Sprintf(`%s line %d:%d %s`, p.linePrefix, line, column, msg) if p.debug { @@ -433,12 +437,14 @@ func (p *Parser) SyntaxError(_ antlr.Recognizer, _ interface{}, line, column int panic(str) } +// WithParserDebug returns a debug ParserOption func WithParserDebug() ParserOption { return func(p *Parser) { p.debug = true } } +// WithParserPrefix returns a prefix ParserOption func WithParserPrefix(prefix string) ParserOption { return func(p *Parser) { p.linePrefix = prefix diff --git a/tools/goctl/api/parser/g4/ast/ast.go b/tools/goctl/api/parser/g4/ast/ast.go index 217eb600..97e25b3f 100644 --- a/tools/goctl/api/parser/g4/ast/ast.go +++ b/tools/goctl/api/parser/g4/ast/ast.go @@ -12,11 +12,15 @@ import ( ) type ( + // TokenStream defines a token TokenStream interface { GetStart() antlr.Token GetStop() antlr.Token GetParser() antlr.Parser } + + // ApiVisitor wraps api.BaseApiParserVisitor to call methods which has prefix Visit to + // visit node from the api syntax ApiVisitor struct { api.BaseApiParserVisitor debug bool @@ -25,8 +29,10 @@ type ( infoFlag bool } + // VisitorOption defines a function with argument ApiVisitor VisitorOption func(v *ApiVisitor) + // Spec describes api spec Spec interface { Doc() []Expr Comment() Expr @@ -34,6 +40,7 @@ type ( Equal(v interface{}) bool } + // Expr describes ast expression Expr interface { Prefix() string Line() int @@ -47,6 +54,7 @@ type ( } ) +// NewApiVisitor creates an instance for ApiVisitor func NewApiVisitor(options ...VisitorOption) *ApiVisitor { v := &ApiVisitor{ log: console.NewColorConsole(), @@ -66,12 +74,14 @@ func (v *ApiVisitor) panic(expr Expr, msg string) { panic(errString) } +// WithVisitorPrefix returns a VisitorOption wrap with specified prefix func WithVisitorPrefix(prefix string) VisitorOption { return func(v *ApiVisitor) { v.prefix = prefix } } +// WithVisitorDebug returns a debug VisitorOption func WithVisitorDebug() VisitorOption { return func(v *ApiVisitor) { v.debug = true @@ -84,6 +94,7 @@ type defaultExpr struct { start, stop int } +// NewTextExpr creates a default instance for Expr func NewTextExpr(v string) *defaultExpr { return &defaultExpr{ v: v, @@ -201,6 +212,7 @@ func (e *defaultExpr) IsNotNil() bool { return e != nil } +// EqualDoc compares whether the element literals in two Spec are equal func EqualDoc(spec1, spec2 Spec) bool { if spec1 == nil { return spec2 == nil diff --git a/tools/goctl/api/parser/g4/ast/import.go b/tools/goctl/api/parser/g4/ast/import.go index 24b9027a..d32c046d 100644 --- a/tools/goctl/api/parser/g4/ast/import.go +++ b/tools/goctl/api/parser/g4/ast/import.go @@ -4,6 +4,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// ImportExpr defines import syntax for api type ImportExpr struct { Import Expr Value Expr @@ -11,6 +12,7 @@ type ImportExpr struct { CommentExpr Expr } +// VisitImportSpec implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitImportSpec(ctx *api.ImportSpecContext) interface{} { var list []*ImportExpr if ctx.ImportLit() != nil { @@ -25,6 +27,7 @@ func (v *ApiVisitor) VisitImportSpec(ctx *api.ImportSpecContext) interface{} { return list } +// VisitImportLit implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitImportLit(ctx *api.ImportLitContext) interface{} { importToken := v.newExprWithToken(ctx.GetImportToken()) valueExpr := ctx.ImportValue().Accept(v).(Expr) @@ -38,6 +41,7 @@ func (v *ApiVisitor) VisitImportLit(ctx *api.ImportLitContext) interface{} { } } +// VisitImportBlock implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitImportBlock(ctx *api.ImportBlockContext) interface{} { importToken := v.newExprWithToken(ctx.GetImportToken()) values := ctx.AllImportBlockValue() @@ -52,6 +56,7 @@ func (v *ApiVisitor) VisitImportBlock(ctx *api.ImportBlockContext) interface{} { return list } +// VisitImportBlockValue implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitImportBlockValue(ctx *api.ImportBlockValueContext) interface{} { value := ctx.ImportValue().Accept(v).(Expr) return &ImportExpr{ @@ -61,15 +66,18 @@ func (v *ApiVisitor) VisitImportBlockValue(ctx *api.ImportBlockValueContext) int } } +// VisitImportValue implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitImportValue(ctx *api.ImportValueContext) interface{} { return v.newExprWithTerminalNode(ctx.STRING()) } +// Format provides a formatter for api command, now nothing to do func (i *ImportExpr) Format() error { // todo return nil } +// Equal compares whether the element literals in two ImportExpr are equal func (i *ImportExpr) Equal(v interface{}) bool { if v == nil { return false @@ -87,10 +95,12 @@ func (i *ImportExpr) Equal(v interface{}) bool { return i.Import.Equal(imp.Import) && i.Value.Equal(imp.Value) } +// Doc returns the document of ImportExpr, like // some text func (i *ImportExpr) Doc() []Expr { return i.DocExpr } +// Comment returns the comment of ImportExpr, like // some text func (i *ImportExpr) Comment() Expr { return i.CommentExpr } diff --git a/tools/goctl/api/parser/g4/ast/info.go b/tools/goctl/api/parser/g4/ast/info.go index 293d253c..359a650b 100644 --- a/tools/goctl/api/parser/g4/ast/info.go +++ b/tools/goctl/api/parser/g4/ast/info.go @@ -4,6 +4,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// InfoExpr defines info syntax for api type InfoExpr struct { Info Expr Lp Expr @@ -11,6 +12,7 @@ type InfoExpr struct { Kvs []*KvExpr } +// VisitInfoSpec implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitInfoSpec(ctx *api.InfoSpecContext) interface{} { var expr InfoExpr expr.Info = v.newExprWithToken(ctx.GetInfoToken()) @@ -29,11 +31,13 @@ func (v *ApiVisitor) VisitInfoSpec(ctx *api.InfoSpecContext) interface{} { return &expr } +// Format provides a formatter for api command, now nothing to do func (i *InfoExpr) Format() error { // todo return nil } +// Equal compares whether the element literals in two InfoExpr are equal func (i *InfoExpr) Equal(v interface{}) bool { if v == nil { return false diff --git a/tools/goctl/api/parser/g4/ast/kv.go b/tools/goctl/api/parser/g4/ast/kv.go index 00331fbd..951dee60 100644 --- a/tools/goctl/api/parser/g4/ast/kv.go +++ b/tools/goctl/api/parser/g4/ast/kv.go @@ -6,6 +6,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// KvExpr describes key-value for api type KvExpr struct { Key Expr Value Expr @@ -13,6 +14,7 @@ type KvExpr struct { CommentExpr Expr } +// VisitKvLit implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitKvLit(ctx *api.KvLitContext) interface{} { var kvExpr KvExpr kvExpr.Key = v.newExprWithToken(ctx.GetKey()) @@ -48,11 +50,13 @@ func (v *ApiVisitor) VisitKvLit(ctx *api.KvLitContext) interface{} { return &kvExpr } +// Format provides a formatter for api command, now nothing to do func (k *KvExpr) Format() error { // todo return nil } +// Equal compares whether the element literals in two KvExpr are equal func (k *KvExpr) Equal(v interface{}) bool { if v == nil { return false @@ -70,10 +74,12 @@ func (k *KvExpr) Equal(v interface{}) bool { return k.Key.Equal(kv.Key) && k.Value.Equal(kv.Value) } +// Doc returns the document of KvExpr, like // some text func (k *KvExpr) Doc() []Expr { return k.DocExpr } +// Comment returns the comment of KvExpr, like // some text func (k *KvExpr) Comment() Expr { return k.CommentExpr } diff --git a/tools/goctl/api/parser/g4/ast/placeholder.go b/tools/goctl/api/parser/g4/ast/placeholder.go index 0217a043..4d010df5 100644 --- a/tools/goctl/api/parser/g4/ast/placeholder.go +++ b/tools/goctl/api/parser/g4/ast/placeholder.go @@ -1,5 +1,7 @@ package ast +// Holder defines a default instance for PlaceHolder var Holder PlaceHolder +// PlaceHolder defines an empty struct type PlaceHolder struct{} diff --git a/tools/goctl/api/parser/g4/ast/service.go b/tools/goctl/api/parser/g4/ast/service.go index 3795191d..d248ee9c 100644 --- a/tools/goctl/api/parser/g4/ast/service.go +++ b/tools/goctl/api/parser/g4/ast/service.go @@ -7,13 +7,16 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// Service describes service for api syntax type Service struct { AtServer *AtServer ServiceApi *ServiceApi } +// KV defines a slice for KvExpr type KV []*KvExpr +// AtServer describes server metadata for api syntax type AtServer struct { AtServerToken Expr Lp Expr @@ -21,6 +24,7 @@ type AtServer struct { Kv KV } +// ServiceApi describes service ast for api syntax type ServiceApi struct { ServiceToken Expr Name Expr @@ -29,6 +33,7 @@ type ServiceApi struct { ServiceRoute []*ServiceRoute } +// ServiceRoute describes service route ast for api syntax type ServiceRoute struct { AtDoc *AtDoc AtServer *AtServer @@ -36,6 +41,7 @@ type ServiceRoute struct { Route *Route } +// AtDoc describes service comments ast for api syntax type AtDoc struct { AtDocToken Expr Lp Expr @@ -44,6 +50,7 @@ type AtDoc struct { Kv []*KvExpr } +// AtHandler describes service hander ast for api syntax type AtHandler struct { AtHandlerToken Expr Name Expr @@ -51,6 +58,7 @@ type AtHandler struct { CommentExpr Expr } +// Route describes route ast for api syntax type Route struct { Method Expr Path Expr @@ -61,12 +69,14 @@ type Route struct { CommentExpr Expr } +// Body describes request,response body ast for api syntax type Body struct { Lp Expr Rp Expr Name DataType } +// VisitServiceSpec implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitServiceSpec(ctx *api.ServiceSpecContext) interface{} { var serviceSpec Service if ctx.AtServer() != nil { @@ -77,6 +87,7 @@ func (v *ApiVisitor) VisitServiceSpec(ctx *api.ServiceSpecContext) interface{} { return &serviceSpec } +// VisitAtServer implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitAtServer(ctx *api.AtServerContext) interface{} { var atServer AtServer atServer.AtServerToken = v.newExprWithTerminalNode(ctx.ATSERVER()) @@ -90,6 +101,7 @@ func (v *ApiVisitor) VisitAtServer(ctx *api.AtServerContext) interface{} { return &atServer } +// VisitServiceApi implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitServiceApi(ctx *api.ServiceApiContext) interface{} { var serviceApi ServiceApi serviceApi.ServiceToken = v.newExprWithToken(ctx.GetServiceToken()) @@ -105,6 +117,7 @@ func (v *ApiVisitor) VisitServiceApi(ctx *api.ServiceApiContext) interface{} { return &serviceApi } +// VisitServiceRoute implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitServiceRoute(ctx *api.ServiceRouteContext) interface{} { var serviceRoute ServiceRoute if ctx.AtDoc() != nil { @@ -121,6 +134,7 @@ func (v *ApiVisitor) VisitServiceRoute(ctx *api.ServiceRouteContext) interface{} return &serviceRoute } +// VisitAtDoc implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitAtDoc(ctx *api.AtDocContext) interface{} { var atDoc AtDoc atDoc.AtDocToken = v.newExprWithTerminalNode(ctx.ATDOC()) @@ -150,6 +164,7 @@ func (v *ApiVisitor) VisitAtDoc(ctx *api.AtDocContext) interface{} { return &atDoc } +// VisitAtHandler implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitAtHandler(ctx *api.AtHandlerContext) interface{} { var atHandler AtHandler astHandlerExpr := v.newExprWithTerminalNode(ctx.ATHANDLER()) @@ -160,6 +175,7 @@ func (v *ApiVisitor) VisitAtHandler(ctx *api.AtHandlerContext) interface{} { return &atHandler } +// VisitRoute implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitRoute(ctx *api.RouteContext) interface{} { var route Route path := ctx.Path() @@ -193,6 +209,7 @@ func (v *ApiVisitor) VisitRoute(ctx *api.RouteContext) interface{} { return &route } +// VisitBody implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitBody(ctx *api.BodyContext) interface{} { if ctx.ID() == nil { return nil @@ -211,7 +228,7 @@ func (v *ApiVisitor) VisitBody(ctx *api.BodyContext) interface{} { } } -// note: forward compatible +// VisitReplybody implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitReplybody(ctx *api.ReplybodyContext) interface{} { if ctx.DataType() == nil { return nil @@ -253,10 +270,13 @@ func (v *ApiVisitor) VisitReplybody(ctx *api.ReplybodyContext) interface{} { } } +// Format provides a formatter for api command, now nothing to do func (b *Body) Format() error { // todo return nil } + +// Equal compares whether the element literals in two Body are equal func (b *Body) Equal(v interface{}) bool { if v == nil { return false @@ -278,19 +298,23 @@ func (b *Body) Equal(v interface{}) bool { return b.Name.Equal(body.Name) } +// Format provides a formatter for api command, now nothing to do func (r *Route) Format() error { // todo return nil } +// Doc returns the document of Route, like // some text func (r *Route) Doc() []Expr { return r.DocExpr } +// Comment returns the comment of Route, like // some text func (r *Route) Comment() Expr { return r.CommentExpr } +// Equal compares whether the element literals in two Route are equal func (r *Route) Equal(v interface{}) bool { if v == nil { return false @@ -330,19 +354,23 @@ func (r *Route) Equal(v interface{}) bool { return EqualDoc(r, route) } +// Doc returns the document of AtHandler, like // some text func (a *AtHandler) Doc() []Expr { return a.DocExpr } +// Comment returns the comment of AtHandler, like // some text func (a *AtHandler) Comment() Expr { return a.CommentExpr } +// Format provides a formatter for api command, now nothing to do func (a *AtHandler) Format() error { // todo return nil } +// Equal compares whether the element literals in two AtHandler are equal func (a *AtHandler) Equal(v interface{}) bool { if v == nil { return false @@ -364,11 +392,13 @@ func (a *AtHandler) Equal(v interface{}) bool { return EqualDoc(a, atHandler) } +// Format provides a formatter for api command, now nothing to do func (a *AtDoc) Format() error { // todo return nil } +// Equal compares whether the element literals in two AtDoc are equal func (a *AtDoc) Equal(v interface{}) bool { if v == nil { return false @@ -419,11 +449,13 @@ func (a *AtDoc) Equal(v interface{}) bool { return true } +// Format provides a formatter for api command, now nothing to do func (a *AtServer) Format() error { // todo return nil } +// Equal compares whether the element literals in two AtServer are equal func (a *AtServer) Equal(v interface{}) bool { if v == nil { return false @@ -471,6 +503,7 @@ func (a *AtServer) Equal(v interface{}) bool { return true } +// Equal compares whether the element literals in two ServiceRoute are equal func (s *ServiceRoute) Equal(v interface{}) bool { if v == nil { return false @@ -500,11 +533,13 @@ func (s *ServiceRoute) Equal(v interface{}) bool { return s.Route.Equal(sr.Route) } +// Format provides a formatter for api command, now nothing to do func (s *ServiceRoute) Format() error { // todo return nil } +// GetHandler returns handler name of api route func (s *ServiceRoute) GetHandler() Expr { if s.AtHandler != nil { return s.AtHandler.Name @@ -513,11 +548,13 @@ func (s *ServiceRoute) GetHandler() Expr { return s.AtServer.Kv.Get("handler") } +// Format provides a formatter for api command, now nothing to do func (a *ServiceApi) Format() error { // todo return nil } +// Equal compares whether the element literals in two ServiceApi are equal func (a *ServiceApi) Equal(v interface{}) bool { if v == nil { return false @@ -569,11 +606,13 @@ func (a *ServiceApi) Equal(v interface{}) bool { return true } +// Format provides a formatter for api command, now nothing to do func (s *Service) Format() error { // todo return nil } +// Equal compares whether the element literals in two Service are equal func (s *Service) Equal(v interface{}) bool { if v == nil { return false @@ -593,6 +632,7 @@ func (s *Service) Equal(v interface{}) bool { return s.ServiceApi.Equal(service.ServiceApi) } +// Get returns the tergate KV by specified key func (kv KV) Get(key string) Expr { for _, each := range kv { if each.Key.Text() == key { diff --git a/tools/goctl/api/parser/g4/ast/syntax.go b/tools/goctl/api/parser/g4/ast/syntax.go index 55b3e57f..6eb38b34 100644 --- a/tools/goctl/api/parser/g4/ast/syntax.go +++ b/tools/goctl/api/parser/g4/ast/syntax.go @@ -4,6 +4,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api" ) +// SyntaxExpr describes syntax for api type SyntaxExpr struct { Syntax Expr Assign Expr @@ -12,6 +13,7 @@ type SyntaxExpr struct { CommentExpr Expr } +// VisitSyntaxLit implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitSyntaxLit(ctx *api.SyntaxLitContext) interface{} { syntax := v.newExprWithToken(ctx.GetSyntaxToken()) assign := v.newExprWithToken(ctx.GetAssign()) @@ -25,11 +27,13 @@ func (v *ApiVisitor) VisitSyntaxLit(ctx *api.SyntaxLitContext) interface{} { } } +// Format provides a formatter for api command, now nothing to do func (s *SyntaxExpr) Format() error { // todo return nil } +// Equal compares whether the element literals in two SyntaxExpr are equal func (s *SyntaxExpr) Equal(v interface{}) bool { if v == nil { return false @@ -49,10 +53,12 @@ func (s *SyntaxExpr) Equal(v interface{}) bool { s.Version.Equal(syntax.Version) } +// Doc returns the document of SyntaxExpr, like // some text func (s *SyntaxExpr) Doc() []Expr { return s.DocExpr } +// Comment returns the comment of SyntaxExpr, like // some text func (s *SyntaxExpr) Comment() Expr { return s.CommentExpr } diff --git a/tools/goctl/api/parser/g4/ast/type.go b/tools/goctl/api/parser/g4/ast/type.go index 2e644723..72eeeeac 100644 --- a/tools/goctl/api/parser/g4/ast/type.go +++ b/tools/goctl/api/parser/g4/ast/type.go @@ -9,13 +9,15 @@ import ( ) type ( - // TypeAlias、 TypeStruct + // TypeExpr describes an expression for TypeAlias and TypeStruct TypeExpr interface { Doc() []Expr Format() error Equal(v interface{}) bool NameExpr() Expr } + + // TypeAlias describes alias ast for api syatax TypeAlias struct { Name Expr Assign Expr @@ -24,6 +26,7 @@ type ( CommentExpr Expr } + // TypeStruct describes structure ast for api syatax TypeStruct struct { Name Expr Struct Expr @@ -33,6 +36,7 @@ type ( Fields []*TypeField } + // TypeField describes field ast for api syntax TypeField struct { IsAnonymous bool // Name is nil if IsAnonymous @@ -43,6 +47,7 @@ type ( CommentExpr Expr } + // DataType describes datatype for api syntax, the default implementation expressions are // Literal, Interface, Map, Array, Time, Pointer DataType interface { Expr() Expr @@ -51,15 +56,18 @@ type ( IsNotNil() bool } - // int, bool, Foo,... + // Literal describes the basic types of golang, non-reference types, + // such as int, bool, Foo,... Literal struct { Literal Expr } + // Interface describes the interface type of golang,Its fixed value is interface{} Interface struct { Literal Expr } + // Map describes the map ast for api syntax Map struct { MapExpr Expr Map Expr @@ -69,6 +77,7 @@ type ( Value DataType } + // Array describes the slice ast for api syntax Array struct { ArrayExpr Expr LBrack Expr @@ -76,10 +85,12 @@ type ( Literal DataType } + // Time describes the time ast for api syntax Time struct { Literal Expr } + // Pointer describes the pointer ast for api syntax Pointer struct { PointerExpr Expr Star Expr @@ -87,6 +98,7 @@ type ( } ) +// VisitTypeSpec implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeSpec(ctx *api.TypeSpecContext) interface{} { if ctx.TypeLit() != nil { return []TypeExpr{ctx.TypeLit().Accept(v).(TypeExpr)} @@ -94,6 +106,7 @@ func (v *ApiVisitor) VisitTypeSpec(ctx *api.TypeSpecContext) interface{} { return ctx.TypeBlock().Accept(v) } +// VisitTypeLit implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeLit(ctx *api.TypeLitContext) interface{} { typeLit := ctx.TypeLitBody().Accept(v) alias, ok := typeLit.(*TypeAlias) @@ -109,6 +122,7 @@ func (v *ApiVisitor) VisitTypeLit(ctx *api.TypeLitContext) interface{} { return typeLit } +// VisitTypeBlock implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeBlock(ctx *api.TypeBlockContext) interface{} { list := ctx.AllTypeBlockBody() var types []TypeExpr @@ -119,6 +133,7 @@ func (v *ApiVisitor) VisitTypeBlock(ctx *api.TypeBlockContext) interface{} { return types } +// VisitTypeLitBody implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeLitBody(ctx *api.TypeLitBodyContext) interface{} { if ctx.TypeAlias() != nil { return ctx.TypeAlias().Accept(v) @@ -126,6 +141,7 @@ func (v *ApiVisitor) VisitTypeLitBody(ctx *api.TypeLitBodyContext) interface{} { return ctx.TypeStruct().Accept(v) } +// VisitTypeBlockBody implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeBlockBody(ctx *api.TypeBlockBodyContext) interface{} { if ctx.TypeBlockAlias() != nil { return ctx.TypeBlockAlias().Accept(v).(*TypeAlias) @@ -133,6 +149,7 @@ func (v *ApiVisitor) VisitTypeBlockBody(ctx *api.TypeBlockBodyContext) interface return ctx.TypeBlockStruct().Accept(v).(*TypeStruct) } +// VisitTypeStruct implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeStruct(ctx *api.TypeStructContext) interface{} { var st TypeStruct st.Name = v.newExprWithToken(ctx.GetStructName()) @@ -168,6 +185,7 @@ func (v *ApiVisitor) VisitTypeStruct(ctx *api.TypeStructContext) interface{} { return &st } +// VisitTypeBlockStruct implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeBlockStruct(ctx *api.TypeBlockStructContext) interface{} { var st TypeStruct st.Name = v.newExprWithToken(ctx.GetStructName()) @@ -200,6 +218,7 @@ func (v *ApiVisitor) VisitTypeBlockStruct(ctx *api.TypeBlockStructContext) inter return &st } +// VisitTypeBlockAlias implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeBlockAlias(ctx *api.TypeBlockAliasContext) interface{} { var alias TypeAlias alias.Name = v.newExprWithToken(ctx.GetAlias()) @@ -212,6 +231,7 @@ func (v *ApiVisitor) VisitTypeBlockAlias(ctx *api.TypeBlockAliasContext) interfa return &alias } +// VisitTypeAlias implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitTypeAlias(ctx *api.TypeAliasContext) interface{} { var alias TypeAlias alias.Name = v.newExprWithToken(ctx.GetAlias()) @@ -224,6 +244,7 @@ func (v *ApiVisitor) VisitTypeAlias(ctx *api.TypeAliasContext) interface{} { return &alias } +// VisitField implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitField(ctx *api.FieldContext) interface{} { iAnonymousFiled := ctx.AnonymousFiled() iNormalFieldContext := ctx.NormalField() @@ -236,6 +257,7 @@ func (v *ApiVisitor) VisitField(ctx *api.FieldContext) interface{} { return nil } +// VisitNormalField implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitNormalField(ctx *api.NormalFieldContext) interface{} { var field TypeField field.Name = v.newExprWithToken(ctx.GetFieldName()) @@ -259,6 +281,7 @@ func (v *ApiVisitor) VisitNormalField(ctx *api.NormalFieldContext) interface{} { return &field } +// VisitAnonymousFiled implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitAnonymousFiled(ctx *api.AnonymousFiledContext) interface{} { start := ctx.GetStart() stop := ctx.GetStop() @@ -282,6 +305,7 @@ func (v *ApiVisitor) VisitAnonymousFiled(ctx *api.AnonymousFiledContext) interfa return &field } +// VisitDataType implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitDataType(ctx *api.DataTypeContext) interface{} { if ctx.ID() != nil { idExpr := v.newExprWithTerminalNode(ctx.ID()) @@ -310,6 +334,7 @@ func (v *ApiVisitor) VisitDataType(ctx *api.DataTypeContext) interface{} { return ctx.TypeStruct().Accept(v) } +// VisitPointerType implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitPointerType(ctx *api.PointerTypeContext) interface{} { nameExpr := v.newExprWithTerminalNode(ctx.ID()) v.exportCheck(nameExpr) @@ -320,6 +345,7 @@ func (v *ApiVisitor) VisitPointerType(ctx *api.PointerTypeContext) interface{} { } } +// VisitMapType implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitMapType(ctx *api.MapTypeContext) interface{} { return &Map{ MapExpr: v.newExprWithText(ctx.GetText(), ctx.GetMapToken().GetLine(), ctx.GetMapToken().GetColumn(), @@ -332,6 +358,7 @@ func (v *ApiVisitor) VisitMapType(ctx *api.MapTypeContext) interface{} { } } +// VisitArrayType implements from api.BaseApiParserVisitor func (v *ApiVisitor) VisitArrayType(ctx *api.ArrayTypeContext) interface{} { return &Array{ ArrayExpr: v.newExprWithText(ctx.GetText(), ctx.GetLbrack().GetLine(), ctx.GetLbrack().GetColumn(), ctx.GetLbrack().GetStart(), ctx.DataType().GetStop().GetStop()), @@ -341,22 +368,27 @@ func (v *ApiVisitor) VisitArrayType(ctx *api.ArrayTypeContext) interface{} { } } +// NameExpr returns the expression string of TypeAlias func (a *TypeAlias) NameExpr() Expr { return a.Name } +// Doc returns the document of TypeAlias, like // some text func (a *TypeAlias) Doc() []Expr { return a.DocExpr } +// Comment returns the comment of TypeAlias, like // some text func (a *TypeAlias) Comment() Expr { return a.CommentExpr } +// Format provides a formatter for api command, now nothing to do func (a *TypeAlias) Format() error { return nil } +// Equal compares whether the element literals in two TypeAlias are equal func (a *TypeAlias) Equal(v interface{}) bool { if v == nil { return false @@ -378,15 +410,18 @@ func (a *TypeAlias) Equal(v interface{}) bool { return EqualDoc(a, alias) } +// Expr returns the expression string of Literal func (l *Literal) Expr() Expr { return l.Literal } +// Format provides a formatter for api command, now nothing to do func (l *Literal) Format() error { // todo return nil } +// Equal compares whether the element literals in two Literal are equal func (l *Literal) Equal(dt DataType) bool { if dt == nil { return false @@ -400,19 +435,23 @@ func (l *Literal) Equal(dt DataType) bool { return l.Literal.Equal(v.Literal) } +// IsNotNil returns whether the instance is nil or not func (l *Literal) IsNotNil() bool { return l != nil } +// Expr returns the expression string of Interface func (i *Interface) Expr() Expr { return i.Literal } +// Format provides a formatter for api command, now nothing to do func (i *Interface) Format() error { // todo return nil } +// Equal compares whether the element literals in two Interface are equal func (i *Interface) Equal(dt DataType) bool { if dt == nil { return false @@ -426,19 +465,23 @@ func (i *Interface) Equal(dt DataType) bool { return i.Literal.Equal(v.Literal) } +// IsNotNil returns whether the instance is nil or not func (i *Interface) IsNotNil() bool { return i != nil } +// Expr returns the expression string of Map func (m *Map) Expr() Expr { return m.MapExpr } +// Format provides a formatter for api command, now nothing to do func (m *Map) Format() error { // todo return nil } +// Equal compares whether the element literals in two Map are equal func (m *Map) Equal(dt DataType) bool { if dt == nil { return false @@ -464,19 +507,23 @@ func (m *Map) Equal(dt DataType) bool { return m.Map.Equal(v.Map) } +// IsNotNil returns whether the instance is nil or not func (m *Map) IsNotNil() bool { return m != nil } +// Expr returns the expression string of Array func (a *Array) Expr() Expr { return a.ArrayExpr } +// Format provides a formatter for api command, now nothing to do func (a *Array) Format() error { // todo return nil } +// Equal compares whether the element literals in two Array are equal func (a *Array) Equal(dt DataType) bool { if dt == nil { return false @@ -494,19 +541,23 @@ func (a *Array) Equal(dt DataType) bool { return a.Literal.Equal(v.Literal) } +// IsNotNil returns whether the instance is nil or not func (a *Array) IsNotNil() bool { return a != nil } +// Expr returns the expression string of Time func (t *Time) Expr() Expr { return t.Literal } +// Format provides a formatter for api command, now nothing to do func (t *Time) Format() error { // todo return nil } +// Equal compares whether the element literals in two Time are equal func (t *Time) Equal(dt DataType) bool { if dt == nil { return false @@ -520,18 +571,22 @@ func (t *Time) Equal(dt DataType) bool { return t.Literal.Equal(v.Literal) } +// IsNotNil returns whether the instance is nil or not func (t *Time) IsNotNil() bool { return t != nil } +// Expr returns the expression string of Pointer func (p *Pointer) Expr() Expr { return p.PointerExpr } +// Format provides a formatter for api command, now nothing to do func (p *Pointer) Format() error { return nil } +// Equal compares whether the element literals in two Pointer are equal func (p *Pointer) Equal(dt DataType) bool { if dt == nil { return false @@ -553,14 +608,17 @@ func (p *Pointer) Equal(dt DataType) bool { return p.Name.Equal(v.Name) } +// IsNotNil returns whether the instance is nil or not func (p *Pointer) IsNotNil() bool { return p != nil } +// NameExpr returns the expression string of TypeStruct func (s *TypeStruct) NameExpr() Expr { return s.Name } +// Equal compares whether the element literals in two TypeStruct are equal func (s *TypeStruct) Equal(dt interface{}) bool { if dt == nil { return false @@ -621,15 +679,18 @@ func (s *TypeStruct) Equal(dt interface{}) bool { return true } +// Doc returns the document of TypeStruct, like // some text func (s *TypeStruct) Doc() []Expr { return s.DocExpr } +// Format provides a formatter for api command, now nothing to do func (s *TypeStruct) Format() error { // todo return nil } +// Equal compares whether the element literals in two TypeField are equal func (t *TypeField) Equal(v interface{}) bool { if v == nil { return false @@ -663,14 +724,17 @@ func (t *TypeField) Equal(v interface{}) bool { return EqualDoc(t, f) } +// Doc returns the document of TypeField, like // some text func (t *TypeField) Doc() []Expr { return t.DocExpr } +// Comment returns the comment of TypeField, like // some text func (t *TypeField) Comment() Expr { return t.CommentExpr } +// Format provides a formatter for api command, now nothing to do func (t *TypeField) Format() error { // todo return nil diff --git a/tools/goctl/api/parser/g4/gen/api/apiparser_parser.go b/tools/goctl/api/parser/g4/gen/api/apiparser_parser.go index d8d896b6..106fef5f 100644 --- a/tools/goctl/api/parser/g4/gen/api/apiparser_parser.go +++ b/tools/goctl/api/parser/g4/gen/api/apiparser_parser.go @@ -4931,7 +4931,7 @@ func (p *ApiParserParser) Route() (localctx IRouteContext) { }() p.EnterOuterAlt(localctx, 1) - checkHttpMethod(p) + checkHTTPMethod(p) { p.SetState(291) diff --git a/tools/goctl/api/parser/g4/gen/api/baseparser.go b/tools/goctl/api/parser/g4/gen/api/baseparser.go index e5040987..6738fadc 100644 --- a/tools/goctl/api/parser/g4/gen/api/baseparser.go +++ b/tools/goctl/api/parser/g4/gen/api/baseparser.go @@ -74,7 +74,7 @@ func checkKeyValue(p *ApiParserParser) { setCurrentTokenText(p, v) } -func checkHttpMethod(p *ApiParserParser) { +func checkHTTPMethod(p *ApiParserParser) { method := getCurrentTokenText(p) uppler := strings.ToUpper(method) switch uppler { @@ -107,11 +107,13 @@ func checkKey(p *ApiParserParser) { } } +// IsBasicType returns true if the input argument is basic golang type func IsBasicType(text string) bool { _, ok := kind[text] return ok } +// IsGolangKeyWord returns true if input argument is golang keyword, but it will be ignored which in excepts func IsGolangKeyWord(text string, excepts ...string) bool { for _, each := range excepts { if text == each { @@ -171,6 +173,7 @@ func isNormal(p *ApiParserParser) bool { return len(list) > 1 } +// MatchTag returns a Boolean value, which returns true if it does matched, otherwise returns fase func MatchTag(v string) bool { return matchRegex(v, tagRegex) } diff --git a/tools/goctl/api/parser/g4/test/apiparser_test.go b/tools/goctl/api/parser/g4/test/apiparser_test.go index f23f8d69..03cd4cb1 100644 --- a/tools/goctl/api/parser/g4/test/apiparser_test.go +++ b/tools/goctl/api/parser/g4/test/apiparser_test.go @@ -12,7 +12,7 @@ import ( ) var ( - normalApi = ` + normalAPI = ` syntax="v1" info ( @@ -32,7 +32,7 @@ var ( post /foo (Foo) returns ([]int) } ` - missDeclarationApi = ` + missDeclarationAPI = ` @server( foo: bar ) @@ -43,7 +43,7 @@ var ( } ` - missDeclarationInArrayApi = ` + missDeclarationInArrayAPI = ` @server( foo: bar ) @@ -54,7 +54,7 @@ var ( } ` - missDeclarationInArrayApi2 = ` + missDeclarationInArrayAPI2 = ` @server( foo: bar ) @@ -65,7 +65,7 @@ var ( } ` - nestedApiImport = ` + nestedAPIImport = ` import "foo.api" ` @@ -99,27 +99,27 @@ var ( ) func TestApiParser(t *testing.T) { - t.Run("missDeclarationApi", func(t *testing.T) { - _, err := parser.ParseContent(missDeclarationApi) + t.Run("missDeclarationAPI", func(t *testing.T) { + _, err := parser.ParseContent(missDeclarationAPI) assert.Error(t, err) fmt.Printf("%+v\n", err) }) - t.Run("missDeclarationApi", func(t *testing.T) { - _, err := parser.ParseContent(missDeclarationInArrayApi) + t.Run("missDeclarationAPI", func(t *testing.T) { + _, err := parser.ParseContent(missDeclarationInArrayAPI) assert.Error(t, err) fmt.Printf("%+v\n", err) }) - t.Run("missDeclarationApi", func(t *testing.T) { - _, err := parser.ParseContent(missDeclarationInArrayApi2) + t.Run("missDeclarationAPI", func(t *testing.T) { + _, err := parser.ParseContent(missDeclarationInArrayAPI2) assert.Error(t, err) fmt.Printf("%+v\n", err) }) t.Run("nestedImport", func(t *testing.T) { file := filepath.Join(t.TempDir(), "foo.api") - err := ioutil.WriteFile(file, []byte(nestedApiImport), os.ModePerm) + err := ioutil.WriteFile(file, []byte(nestedAPIImport), os.ModePerm) if err != nil { return } @@ -275,7 +275,7 @@ func TestApiParser(t *testing.T) { }) t.Run("normal", func(t *testing.T) { - v, err := parser.ParseContent(normalApi) + v, err := parser.ParseContent(normalAPI) assert.Nil(t, err) body := &ast.Body{ Lp: ast.NewTextExpr("("), diff --git a/tools/goctl/api/parser/parser.go b/tools/goctl/api/parser/parser.go index 7fc41793..da1fbb97 100644 --- a/tools/goctl/api/parser/parser.go +++ b/tools/goctl/api/parser/parser.go @@ -15,6 +15,7 @@ type parser struct { spec *spec.ApiSpec } +// Parse parses the api file func Parse(filename string) (*spec.ApiSpec, error) { astParser := ast.NewParser(ast.WithParserPrefix(filepath.Base(filename))) ast, err := astParser.Parse(filename) @@ -32,6 +33,7 @@ func Parse(filename string) (*spec.ApiSpec, error) { return spec, nil } +// ParseContent parses the api content func ParseContent(content string) (*spec.ApiSpec, error) { astParser := ast.NewParser() ast, err := astParser.ParseContent(content) diff --git a/tools/goctl/api/spec/fn.go b/tools/goctl/api/spec/fn.go index c5c7a8c8..5c0c9c0c 100644 --- a/tools/goctl/api/spec/fn.go +++ b/tools/goctl/api/spec/fn.go @@ -16,6 +16,7 @@ const ( var definedKeys = []string{bodyTagKey, formTagKey, "path"} +// Routes returns all routes in api service func (s Service) Routes() []Route { var result []Route for _, group := range s.Groups { @@ -24,6 +25,7 @@ func (s Service) Routes() []Route { return result } +// Tags retuens all tags in Member func (m Member) Tags() []*Tag { tags, err := Parse(m.Tag) if err != nil { @@ -33,6 +35,7 @@ func (m Member) Tags() []*Tag { return tags.Tags() } +// IsOptional returns true if tag is optional func (m Member) IsOptional() bool { if !m.IsBodyMember() { return false @@ -49,6 +52,7 @@ func (m Member) IsOptional() bool { return false } +// IsOmitEmpty returns true if tag contains omitempty func (m Member) IsOmitEmpty() bool { if !m.IsBodyMember() { return false @@ -65,22 +69,7 @@ func (m Member) IsOmitEmpty() bool { return false } -func (m Member) IsOmitempty() bool { - if !m.IsBodyMember() { - return false - } - - tag := m.Tags() - for _, item := range tag { - if item.Key == bodyTagKey { - if stringx.Contains(item.Options, "omitempty") { - return true - } - } - } - return false -} - +// GetPropertyName returns json tag value func (m Member) GetPropertyName() (string, error) { tags := m.Tags() for _, tag := range tags { @@ -95,10 +84,12 @@ func (m Member) GetPropertyName() (string, error) { return "", errors.New("json property name not exist, member: " + m.Name) } +// GetComment returns comment value of Member func (m Member) GetComment() string { return strings.TrimSpace(m.Comment) } +// IsBodyMember returns true if contains json tag func (m Member) IsBodyMember() bool { if m.IsInline { return true @@ -113,6 +104,7 @@ func (m Member) IsBodyMember() bool { return false } +// IsFormMember returns true if contains form tag func (m Member) IsFormMember() bool { if m.IsInline { return false @@ -127,6 +119,7 @@ func (m Member) IsFormMember() bool { return false } +// GetBodyMembers returns all json fields func (t DefineStruct) GetBodyMembers() []Member { var result []Member for _, member := range t.Members { @@ -137,6 +130,7 @@ func (t DefineStruct) GetBodyMembers() []Member { return result } +// GetFormMembers returns all form fields func (t DefineStruct) GetFormMembers() []Member { var result []Member for _, member := range t.Members { @@ -147,6 +141,7 @@ func (t DefineStruct) GetFormMembers() []Member { return result } +// GetNonBodyMembers retruns all have no tag fields func (t DefineStruct) GetNonBodyMembers() []Member { var result []Member for _, member := range t.Members { @@ -157,6 +152,7 @@ func (t DefineStruct) GetNonBodyMembers() []Member { return result } +// JoinedDoc joins comments and summary value in AtDoc func (r Route) JoinedDoc() string { doc := r.AtDoc.Text if r.AtDoc.Properties != nil { @@ -166,6 +162,7 @@ func (r Route) JoinedDoc() string { return strings.TrimSpace(doc) } +// GetAnnotation returns the value by specified key func (r Route) GetAnnotation(key string) string { if r.Annotation.Properties == nil { return "" @@ -174,6 +171,7 @@ func (r Route) GetAnnotation(key string) string { return r.Annotation.Properties[key] } +// GetAnnotation returns the value by specified key func (g Group) GetAnnotation(key string) string { if g.Annotation.Properties == nil { return "" @@ -182,6 +180,7 @@ func (g Group) GetAnnotation(key string) string { return g.Annotation.Properties[key] } +// ResponseTypeName returns response type name of route func (r Route) ResponseTypeName() string { if r.ResponseType == nil { return "" @@ -190,6 +189,7 @@ func (r Route) ResponseTypeName() string { return r.ResponseType.Name() } +// RequestTypeName returns request type name of route func (r Route) RequestTypeName() string { if r.RequestType == nil { return "" diff --git a/tools/goctl/api/spec/name.go b/tools/goctl/api/spec/name.go index 0f0a53c5..eea0d558 100644 --- a/tools/goctl/api/spec/name.go +++ b/tools/goctl/api/spec/name.go @@ -1,25 +1,31 @@ package spec +// Name returns a basic string, such as int32,int64 func (t PrimitiveType) Name() string { return t.RawName } +// Name returns a structure string, such as User func (t DefineStruct) Name() string { return t.RawName } +// Name returns a map string, such as map[string]int func (t MapType) Name() string { return t.RawName } +// Name returns a slice string, such as []int func (t ArrayType) Name() string { return t.RawName } +// Name returns a pointer string, such as *User func (t PointerType) Name() string { return t.RawName } +// Name returns a interface string, Its fixed value is interface{} func (t InterfaceType) Name() string { return t.RawName } diff --git a/tools/goctl/api/spec/spec.go b/tools/goctl/api/spec/spec.go index 3c93db0d..50955074 100644 --- a/tools/goctl/api/spec/spec.go +++ b/tools/goctl/api/spec/spec.go @@ -1,16 +1,20 @@ package spec type ( + // Doc describes document Doc []string + // Annotation defines key-value Annotation struct { Properties map[string]string } + // ApiSyntax describes the syntax grammar ApiSyntax struct { Version string } + // ApiSpec describes a api file ApiSpec struct { Info Info Syntax ApiSyntax @@ -19,15 +23,18 @@ type ( Service Service } + // Import describes api import Import struct { Value string } + // Group defines a set of routing information Group struct { Annotation Annotation Routes []Route } + // Info describes info grammar block Info struct { // Deprecated: use Properties instead Title string @@ -42,6 +49,7 @@ type ( Properties map[string]string } + // Member describes the field of a structure Member struct { Name string // 数据类型字面值,如:string、map[int]string、[]int64、[]*User @@ -53,6 +61,7 @@ type ( IsInline bool } + // Route describes api route Route struct { Annotation Annotation Method string @@ -64,26 +73,30 @@ type ( AtDoc AtDoc } + // Service describes api service Service struct { Name string Groups []Group } + // Type defines api type Type interface { Name() string } + // DefineStruct describes api structure DefineStruct struct { RawName string Members []Member Docs Doc } - // 系统预设基本数据类型 bool int32 int64 float32 + // PrimitiveType describes the basic golang type, such as bool,int32,int64, ... PrimitiveType struct { RawName string } + // MapType describes a map for api MapType struct { RawName string // only support the PrimitiveType @@ -97,20 +110,24 @@ type ( Value Type } + // ArrayType describes a slice for api ArrayType struct { RawName string Value Type } + // InterfaceType describes a interface for api InterfaceType struct { RawName string } + // PointerType describes a pointer for api PointerType struct { RawName string Type Type } + // AtDoc describes a metadata for api grammar: @doc(...) AtDoc struct { Properties map[string]string Text string diff --git a/tools/goctl/api/spec/tags.go b/tools/goctl/api/spec/tags.go index 9c5b0bd7..312772d3 100644 --- a/tools/goctl/api/spec/tags.go +++ b/tools/goctl/api/spec/tags.go @@ -10,6 +10,7 @@ import ( var errTagNotExist = errors.New("tag does not exist") type ( + // Tag defines a tag for structure filed Tag struct { // Key is the tag key, such as json, xml, etc.. // i.e: `json:"foo,omitempty". Here key is: "json" @@ -24,11 +25,13 @@ type ( Options []string } + // Tags defines a slice for Tag Tags struct { tags []*Tag } ) +// Parse converts tag string into Tag func Parse(tag string) (*Tags, error) { tag = strings.TrimPrefix(tag, "`") tag = strings.TrimSuffix(tag, "`") @@ -44,6 +47,7 @@ func Parse(tag string) (*Tags, error) { return &result, nil } +// Get gets tag value by specified key func (t *Tags) Get(key string) (*Tag, error) { for _, tag := range t.tags { if tag.Key == key { @@ -54,6 +58,7 @@ func (t *Tags) Get(key string) (*Tag, error) { return nil, errTagNotExist } +// Keys returns all keys in Tags func (t *Tags) Keys() []string { var keys []string for _, tag := range t.tags { @@ -62,6 +67,7 @@ func (t *Tags) Keys() []string { return keys } +// Tags returns all tags in Tags func (t *Tags) Tags() []*Tag { return t.tags } diff --git a/tools/goctl/api/tsgen/gen.go b/tools/goctl/api/tsgen/gen.go index 3b341e3b..7fbb2a30 100644 --- a/tools/goctl/api/tsgen/gen.go +++ b/tools/goctl/api/tsgen/gen.go @@ -11,12 +11,13 @@ import ( "github.com/urfave/cli" ) +// TsCommand provides the entry to generting typescript codes func TsCommand(c *cli.Context) error { apiFile := c.String("api") dir := c.String("dir") - webApi := c.String("webapi") + webAPI := c.String("webapi") caller := c.String("caller") - unwrapApi := c.Bool("unwrap") + unwrapAPI := c.Bool("unwrap") if len(apiFile) == 0 { return errors.New("missing -api") } @@ -32,7 +33,7 @@ func TsCommand(c *cli.Context) error { } logx.Must(util.MkdirIfNotExist(dir)) - logx.Must(genHandler(dir, webApi, caller, api, unwrapApi)) + logx.Must(genHandler(dir, webAPI, caller, api, unwrapAPI)) logx.Must(genComponents(dir, api)) fmt.Println(aurora.Green("Done.")) diff --git a/tools/goctl/api/tsgen/genpacket.go b/tools/goctl/api/tsgen/genpacket.go index 2965a922..6ffee466 100644 --- a/tools/goctl/api/tsgen/genpacket.go +++ b/tools/goctl/api/tsgen/genpacket.go @@ -18,7 +18,7 @@ const ( ` ) -func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) error { +func genHandler(dir, webAPI, caller string, api *spec.ApiSpec, unwrapAPI bool) error { filename := strings.Replace(api.Service.Name, "-api", "", 1) + ".ts" if err := util.RemoveIfExist(path.Join(dir, filename)); err != nil { return err @@ -37,11 +37,11 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e caller = "webapi" } importCaller := caller - if unwrapApi { + if unwrapAPI { importCaller = "{ " + importCaller + " }" } - if len(webApi) > 0 { - imports += `import ` + importCaller + ` from ` + "\"" + webApi + "\"" + if len(webAPI) > 0 { + imports += `import ` + importCaller + ` from ` + "\"" + webAPI + "\"" } if len(api.Types) != 0 { @@ -53,7 +53,7 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e imports += fmt.Sprintf(`%sexport * from "%s"`, util.NL, "./"+outputFile) } - apis, err := genApi(api, caller) + apis, err := genAPI(api, caller) if err != nil { return err } @@ -65,7 +65,7 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e }) } -func genApi(api *spec.ApiSpec, caller string) (string, error) { +func genAPI(api *spec.ApiSpec, caller string) (string, error) { var builder strings.Builder for _, group := range api.Service.Groups { for _, route := range group.Routes { @@ -157,7 +157,7 @@ func callParamsForRoute(route spec.Route, group spec.Group) string { } func pathForRoute(route spec.Route, group spec.Group) string { - prefix := group.GetAnnotation("pathPrefix") + prefix := group.GetAnnotation(pathPrefix) if len(prefix) == 0 { return "\"" + route.Path + "\"" } diff --git a/tools/goctl/api/tsgen/util.go b/tools/goctl/api/tsgen/util.go index 8e01498c..f9f9634b 100644 --- a/tools/goctl/api/tsgen/util.go +++ b/tools/goctl/api/tsgen/util.go @@ -19,7 +19,7 @@ func writeProperty(writer io.Writer, member spec.Member, indent int) error { } optionalTag := "" - if member.IsOptional() || member.IsOmitempty() { + if member.IsOptional() || member.IsOmitEmpty() { optionalTag = "?" } name, err := member.GetPropertyName() diff --git a/tools/goctl/api/util/case.go b/tools/goctl/api/util/case.go index 64c330c2..b48f7357 100644 --- a/tools/goctl/api/util/case.go +++ b/tools/goctl/api/util/case.go @@ -5,6 +5,7 @@ import ( "unicode" ) +// IsUpperCase returns true if the rune in A-Z func IsUpperCase(r rune) bool { if r >= 'A' && r <= 'Z' { return true @@ -12,6 +13,7 @@ func IsUpperCase(r rune) bool { return false } +// IsLowerCase returns true if the rune in a-z func IsLowerCase(r rune) bool { if r >= 'a' && r <= 'z' { return true @@ -19,6 +21,7 @@ func IsLowerCase(r rune) bool { return false } +// ToSnakeCase returns a copy string by converting camel case into snake case func ToSnakeCase(s string) string { var out []rune for index, r := range s { @@ -44,6 +47,7 @@ func ToSnakeCase(s string) string { return string(out) } +// ToCamelCase returns a copy string by converting snake case into camel case func ToCamelCase(s string) string { s = ToLower(s) out := []rune{} @@ -66,6 +70,7 @@ func ToCamelCase(s string) string { return string(out) } +// ToLowerCase converts rune into lower case func ToLowerCase(r rune) rune { dx := 'A' - 'a' if IsUpperCase(r) { @@ -73,6 +78,8 @@ func ToLowerCase(r rune) rune { } return r } + +// ToUpperCase converts rune into upper case func ToUpperCase(r rune) rune { dx := 'A' - 'a' if IsLowerCase(r) { @@ -81,6 +88,7 @@ func ToUpperCase(r rune) rune { return r } +// ToLower returns a copy string by converting it into lower func ToLower(s string) string { var out []rune for _, r := range s { @@ -89,6 +97,7 @@ func ToLower(s string) string { return string(out) } +// ToUpper returns a copy string by converting it into upper func ToUpper(s string) string { var out []rune for _, r := range s { @@ -97,13 +106,7 @@ func ToUpper(s string) string { return string(out) } -func LowerFirst(s string) string { - if len(s) == 0 { - return s - } - return ToLower(s[:1]) + s[1:] -} - +// UpperFirst converts s[0] into upper case func UpperFirst(s string) string { if len(s) == 0 { return s @@ -111,6 +114,7 @@ func UpperFirst(s string) string { return ToUpper(s[:1]) + s[1:] } +// UnExport converts the first letter into lower case func UnExport(text string) bool { var flag bool str := strings.Map(func(r rune) rune { diff --git a/tools/goctl/api/util/util.go b/tools/goctl/api/util/util.go index 2377ef5e..13cbcdcb 100644 --- a/tools/goctl/api/util/util.go +++ b/tools/goctl/api/util/util.go @@ -13,6 +13,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util" ) +// MaybeCreateFile creates file if not exists func MaybeCreateFile(dir, subdir, file string) (fp *os.File, created bool, err error) { logx.Must(util.MkdirIfNotExist(path.Join(dir, subdir))) fpath := path.Join(dir, subdir, file) @@ -26,10 +27,12 @@ func MaybeCreateFile(dir, subdir, file string) (fp *os.File, created bool, err e return } +// WrapErr wraps an error with message func WrapErr(err error, message string) error { return errors.New(message + ", " + err.Error()) } +// Copy calls io.Copy if the source file and destination file exists func Copy(src, dst string) (int64, error) { sourceFileStat, err := os.Stat(src) if err != nil { @@ -55,6 +58,7 @@ func Copy(src, dst string) (int64, error) { return nBytes, err } +// ComponentName returns component name for typescript func ComponentName(api *spec.ApiSpec) string { name := api.Service.Name if strings.HasSuffix(name, "-api") { @@ -63,12 +67,14 @@ func ComponentName(api *spec.ApiSpec) string { return name + "Components" } +// WriteIndent writes tab spaces func WriteIndent(writer io.Writer, indent int) { for i := 0; i < indent; i++ { fmt.Fprint(writer, "\t") } } +// RemoveComment filters comment content func RemoveComment(line string) string { var commentIdx = strings.Index(line, "//") if commentIdx >= 0 { diff --git a/tools/goctl/api/validate/validate.go b/tools/goctl/api/validate/validate.go index 1f1769ef..c40f3a5c 100644 --- a/tools/goctl/api/validate/validate.go +++ b/tools/goctl/api/validate/validate.go @@ -9,6 +9,7 @@ import ( "github.com/urfave/cli" ) +// GoValidateApi verifies whether the api has a syntax error func GoValidateApi(c *cli.Context) error { apiFile := c.String("api") diff --git a/tools/goctl/config/config.go b/tools/goctl/config/config.go index f87d8c24..fdc61f50 100644 --- a/tools/goctl/config/config.go +++ b/tools/goctl/config/config.go @@ -2,35 +2,15 @@ package config import ( "errors" - "io/ioutil" - "os" - "path/filepath" "strings" - - "github.com/tal-tech/go-zero/tools/goctl/util" - "gopkg.in/yaml.v2" ) const ( - configFile = "config.yaml" - configFolder = "config" + // DefaultFormat defines a default naming style DefaultFormat = "gozero" ) -const defaultYaml = `# namingFormat is used to define the naming format of the generated file name. -# just like time formatting, you can specify the formatting style through the -# two format characters go, and zero. for example: snake format you can -# define as go_zero, camel case format you can it is defined as goZero, -# and even split characters can be specified, such as go#zero. in theory, -# any combination can be used, but the prerequisite must meet the naming conventions -# of each operating system file name. if you want to independently control the file -# naming style of the api, rpc, and model layers, you can set it through apiNamingFormat, -# rpcNamingFormat, modelNamingFormat, and independent control is not enabled by default. -# for more information, please see #{apiNamingFormat},#{rpcNamingFormat},#{modelNamingFormat} -# Note: namingFormat is based on snake or camel string -namingFormat: gozero -` - +// Config defines the file naming style type Config struct { // NamingFormat is used to define the naming format of the generated file name. // just like time formatting, you can specify the formatting style through the @@ -43,6 +23,7 @@ type Config struct { NamingFormat string `yaml:"namingFormat"` } +// NewConfig creates an instance for Config func NewConfig(format string) (*Config, error) { if len(format) == 0 { format = DefaultFormat @@ -52,68 +33,6 @@ func NewConfig(format string) (*Config, error) { return cfg, err } -func InitOrGetConfig() (*Config, error) { - var ( - defaultConfig Config - ) - err := yaml.Unmarshal([]byte(defaultYaml), &defaultConfig) - if err != nil { - return nil, err - } - - goctlHome, err := util.GetGoctlHome() - if err != nil { - return nil, err - } - - configDir := filepath.Join(goctlHome, configFolder) - configFilename := filepath.Join(configDir, configFile) - if util.FileExists(configFilename) { - data, err := ioutil.ReadFile(configFilename) - if err != nil { - return nil, err - } - - err = yaml.Unmarshal(data, &defaultConfig) - if err != nil { - return nil, err - } - - err = validate(&defaultConfig) - if err != nil { - return nil, err - } - - return &defaultConfig, nil - } - - err = util.MkdirIfNotExist(configDir) - if err != nil { - return nil, err - } - - f, err := os.Create(configFilename) - if err != nil { - return nil, err - } - - defer func() { - _ = f.Close() - }() - - _, err = f.WriteString(defaultYaml) - if err != nil { - return nil, err - } - - err = validate(&defaultConfig) - if err != nil { - return nil, err - } - - return &defaultConfig, nil -} - func validate(cfg *Config) error { if len(strings.TrimSpace(cfg.NamingFormat)) == 0 { return errors.New("missing namingFormat") diff --git a/tools/goctl/configgen/genconfig.go b/tools/goctl/configgen/genconfig.go index b768d8c3..7d477ca8 100644 --- a/tools/goctl/configgen/genconfig.go +++ b/tools/goctl/configgen/genconfig.go @@ -37,6 +37,7 @@ func main() { } ` +// GenConfigCommand provides the entry of goctl config func GenConfigCommand(c *cli.Context) error { path, err := filepath.Abs(c.String("path")) if err != nil { diff --git a/tools/goctl/docker/docker.go b/tools/goctl/docker/docker.go index 066cce5f..32d6dbf3 100644 --- a/tools/goctl/docker/docker.go +++ b/tools/goctl/docker/docker.go @@ -22,6 +22,7 @@ const ( cstOffset = 60 * 60 * 8 // 8 hours offset for Chinese Standard Time ) +// Docker describes a dockerfile type Docker struct { Chinese bool GoRelPath string @@ -32,6 +33,7 @@ type Docker struct { Argument string } +// DockerCommand provides the entry for goctl docker func DockerCommand(c *cli.Context) (err error) { defer func() { if err == nil { diff --git a/tools/goctl/docker/template.go b/tools/goctl/docker/template.go index fedc82a7..b21e2666 100644 --- a/tools/goctl/docker/template.go +++ b/tools/goctl/docker/template.go @@ -41,22 +41,27 @@ CMD ["./{{.ExeFile}}"{{.Argument}}] ` ) +// Clean deletes all templates files func Clean() error { return util.Clean(category) } +// GenTemplates creates docker template files func GenTemplates(_ *cli.Context) error { return initTemplate() } +// Category returns the const string of docker category func Category() string { return category } +// RevertTemplate recovers the deleted template files func RevertTemplate(name string) error { return util.CreateTemplate(category, name, dockerTemplate) } +// Update deletes and creates new template files func Update() error { err := Clean() if err != nil { diff --git a/tools/goctl/goctl.go b/tools/goctl/goctl.go index 3f9130b4..da1fa19c 100644 --- a/tools/goctl/goctl.go +++ b/tools/goctl/goctl.go @@ -49,7 +49,7 @@ var ( { Name: "new", Usage: "fast create api service", - Action: new.NewService, + Action: new.CreateServiceCommand, }, { Name: "format", @@ -337,7 +337,7 @@ var ( Usage: "whether the command execution environment is from idea plugin. [optional]", }, }, - Action: rpc.RpcNew, + Action: rpc.RPCNew, }, { Name: "template", @@ -348,7 +348,7 @@ var ( Usage: "the target path of proto", }, }, - Action: rpc.RpcTemplate, + Action: rpc.RPCTemplate, }, { Name: "proto", @@ -375,7 +375,7 @@ var ( Usage: "whether the command execution environment is from idea plugin. [optional]", }, }, - Action: rpc.Rpc, + Action: rpc.RPC, }, }, }, diff --git a/tools/goctl/kube/kube.go b/tools/goctl/kube/kube.go index b1ddec95..9417031c 100644 --- a/tools/goctl/kube/kube.go +++ b/tools/goctl/kube/kube.go @@ -18,6 +18,7 @@ const ( portLimit = 32767 ) +// Deployment describes the k8s deployment yaml type Deployment struct { Name string Namespace string diff --git a/tools/goctl/model/sql/builderx/builder.go b/tools/goctl/model/sql/builderx/builder.go index 1c72e6d9..d790fb83 100644 --- a/tools/goctl/model/sql/builderx/builder.go +++ b/tools/goctl/model/sql/builderx/builder.go @@ -9,14 +9,17 @@ import ( const dbTag = "db" +// NewEq wraps builder.Eq func NewEq(in interface{}) builder.Eq { return builder.Eq(ToMap(in)) } +// NewGt wraps builder.Gt func NewGt(in interface{}) builder.Gt { return builder.Gt(ToMap(in)) } +// ToMap converts interface into map func ToMap(in interface{}) map[string]interface{} { out := make(map[string]interface{}) v := reflect.ValueOf(in) @@ -76,6 +79,7 @@ func FieldNames(in interface{}) []string { return out } +// RawFieldNames converts golang struct field into slice string func RawFieldNames(in interface{}) []string { out := make([]string, 0) v := reflect.ValueOf(in) diff --git a/tools/goctl/model/sql/builderx/builder_test.go b/tools/goctl/model/sql/builderx/builder_test.go index 5b21136a..28141f6f 100644 --- a/tools/goctl/model/sql/builderx/builder_test.go +++ b/tools/goctl/model/sql/builderx/builder_test.go @@ -10,12 +10,12 @@ import ( type mockedUser struct { // 自增id - Id string `db:"id" json:"id,omitempty"` + ID string `db:"id" json:"id,omitempty"` // 姓名 UserName string `db:"user_name" json:"userName,omitempty"` // 1男,2女 Sex int `db:"sex" json:"sex,omitempty"` - Uuid string `db:"uuid" uuid:"uuid,omitempty"` + UUID string `db:"uuid" uuid:"uuid,omitempty"` Age int `db:"age" json:"age"` } @@ -42,7 +42,7 @@ func TestFieldNames(t *testing.T) { func TestNewEq(t *testing.T) { u := &mockedUser{ - Id: "123456", + ID: "123456", UserName: "wahaha", } out := NewEq(u) @@ -54,16 +54,16 @@ func TestNewEq(t *testing.T) { // @see https://github.com/go-xorm/builder func TestBuilderSql(t *testing.T) { u := &mockedUser{ - Id: "123123", + ID: "123123", } fields := RawFieldNames(u) eq := NewEq(u) sql, args, err := builder.Select(fields...).From("user").Where(eq).ToSQL() fmt.Println(sql, args, err) - actualSql := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id=?" + actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id=?" actualArgs := []interface{}{"123123"} - assert.Equal(t, sql, actualSql) + assert.Equal(t, sql, actualSQL) assert.Equal(t, args, actualArgs) } @@ -76,9 +76,9 @@ func TestBuildSqlDefaultValue(t *testing.T) { sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(eq).ToSQL() fmt.Println(sql, args, err) - actualSql := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE age=? AND user_name=?" + actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE age=? AND user_name=?" actualArgs := []interface{}{0, ""} - assert.Equal(t, sql, actualSql) + assert.Equal(t, sql, actualSQL) assert.Equal(t, args, actualArgs) }) @@ -86,9 +86,9 @@ func TestBuildSqlDefaultValue(t *testing.T) { sql, args, err := builder.Select(userFieldsWithoutRawStringQuote...).From("user").Where(eq).ToSQL() fmt.Println(sql, args, err) - actualSql := "SELECT id,user_name,sex,uuid,age FROM user WHERE age=? AND user_name=?" + actualSQL := "SELECT id,user_name,sex,uuid,age FROM user WHERE age=? AND user_name=?" actualArgs := []interface{}{0, ""} - assert.Equal(t, sql, actualSql) + assert.Equal(t, sql, actualSQL) assert.Equal(t, args, actualArgs) }) } @@ -102,9 +102,9 @@ func TestBuilderSqlIn(t *testing.T) { sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(in).And(gtU).ToSQL() fmt.Println(sql, args, err) - actualSql := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id IN (?,?,?) AND age>?" + actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE id IN (?,?,?) AND age>?" actualArgs := []interface{}{"1", "2", "3", 18} - assert.Equal(t, sql, actualSql) + assert.Equal(t, sql, actualSQL) assert.Equal(t, args, actualArgs) } @@ -113,8 +113,8 @@ func TestBuildSqlLike(t *testing.T) { sql, args, err := builder.Select(userFieldsWithRawStringQuote...).From("user").Where(like).ToSQL() fmt.Println(sql, args, err) - actualSql := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE name LIKE ?" + actualSQL := "SELECT `id`,`user_name`,`sex`,`uuid`,`age` FROM user WHERE name LIKE ?" actualArgs := []interface{}{"%wang%"} - assert.Equal(t, sql, actualSql) + assert.Equal(t, sql, actualSQL) assert.Equal(t, args, actualArgs) } diff --git a/tools/goctl/model/sql/command/command.go b/tools/goctl/model/sql/command/command.go index 6a94ad3f..183b92e1 100644 --- a/tools/goctl/model/sql/command/command.go +++ b/tools/goctl/model/sql/command/command.go @@ -22,13 +22,14 @@ const ( flagDir = "dir" flagCache = "cache" flagIdea = "idea" - flagUrl = "url" + flagURL = "url" flagTable = "table" flagStyle = "style" ) var errNotMatched = errors.New("sql not matched") +// MysqlDDL generates model code from ddl func MysqlDDL(ctx *cli.Context) error { src := ctx.String(flagSrc) dir := ctx.String(flagDir) @@ -43,8 +44,9 @@ func MysqlDDL(ctx *cli.Context) error { return fromDDl(src, dir, cfg, cache, idea) } +// MyDataSource generates model code from datasource func MyDataSource(ctx *cli.Context) error { - url := strings.TrimSpace(ctx.String(flagUrl)) + url := strings.TrimSpace(ctx.String(flagURL)) dir := strings.TrimSpace(ctx.String(flagDir)) cache := ctx.Bool(flagCache) idea := ctx.Bool(flagIdea) diff --git a/tools/goctl/model/sql/converter/types.go b/tools/goctl/model/sql/converter/types.go index d0718362..cf6fb3ea 100644 --- a/tools/goctl/model/sql/converter/types.go +++ b/tools/goctl/model/sql/converter/types.go @@ -39,6 +39,7 @@ var commonMysqlDataTypeMap = map[string]string{ "json": "string", } +// ConvertDataType converts mysql column type into golang type func ConvertDataType(dataBaseType string, isDefaultNull bool) (string, error) { tp, ok := commonMysqlDataTypeMap[strings.ToLower(dataBaseType)] if !ok { diff --git a/tools/goctl/model/sql/gen/error.go b/tools/goctl/model/sql/gen/error.go deleted file mode 100644 index be9cf947..00000000 --- a/tools/goctl/model/sql/gen/error.go +++ /dev/null @@ -1,5 +0,0 @@ -package gen - -import "errors" - -var ErrCircleQuery = errors.New("circle query with other fields") diff --git a/tools/goctl/model/sql/gen/gen.go b/tools/goctl/model/sql/gen/gen.go index 2973a50e..0968ace6 100644 --- a/tools/goctl/model/sql/gen/gen.go +++ b/tools/goctl/model/sql/gen/gen.go @@ -33,6 +33,7 @@ type ( cfg *config.Config } + // Option defines a function with argument defaultGenerator Option func(generator *defaultGenerator) code struct { @@ -48,6 +49,7 @@ type ( } ) +// NewDefaultGenerator creates an instance for defaultGenerator func NewDefaultGenerator(dir string, cfg *config.Config, opt ...Option) (*defaultGenerator, error) { if dir == "" { dir = pwd @@ -75,6 +77,7 @@ func NewDefaultGenerator(dir string, cfg *config.Config, opt ...Option) (*defaul return generator, nil } +// WithConsoleOption creates a console option func WithConsoleOption(c console.Console) Option { return func(generator *defaultGenerator) { generator.Console = c @@ -189,6 +192,7 @@ func (g *defaultGenerator) genFromDDL(source string, withCache bool) (map[string return m, nil } +// Table defines mysql table type Table struct { parser.Table CacheKey map[string]Key diff --git a/tools/goctl/model/sql/gen/gen_test.go b/tools/goctl/model/sql/gen/gen_test.go index 89e0e198..b32f2300 100644 --- a/tools/goctl/model/sql/gen/gen_test.go +++ b/tools/goctl/model/sql/gen/gen_test.go @@ -94,7 +94,7 @@ func TestWrapWithRawString(t *testing.T) { func TestFields(t *testing.T) { type Student struct { - Id int64 `db:"id"` + ID int64 `db:"id"` Name string `db:"name"` Age sql.NullInt64 `db:"age"` Score sql.NullFloat64 `db:"score"` diff --git a/tools/goctl/model/sql/gen/keys.go b/tools/goctl/model/sql/gen/keys.go index e77c59eb..04220bcc 100644 --- a/tools/goctl/model/sql/gen/keys.go +++ b/tools/goctl/model/sql/gen/keys.go @@ -8,17 +8,22 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util/stringx" ) -// tableName:user -// {{prefix}}=cache -// key:id +// Key defines cache key variable for generating code type Key struct { - VarExpression string // cacheUserIdPrefix = "cache#User#id#" - Left string // cacheUserIdPrefix - Right string // cache#user#id# - Variable string // userIdKey - KeyExpression string // userIdKey: = fmt.Sprintf("cache#user#id#%v", userId) - DataKeyExpression string // userIdKey: = fmt.Sprintf("cache#user#id#%v", data.userId) - RespKeyExpression string // userIdKey: = fmt.Sprintf("cache#user#id#%v", resp.userId) + // VarExpression likes cacheUserIdPrefix = "cache#User#id#" + VarExpression string + // Left likes cacheUserIdPrefix + Left string + // Right likes cache#user#id# + Right string + // Variable likes userIdKey + Variable string + // KeyExpression likes userIdKey: = fmt.Sprintf("cache#user#id#%v", userId) + KeyExpression string + // DataKeyExpression likes userIdKey: = fmt.Sprintf("cache#user#id#%v", data.userId) + DataKeyExpression string + // RespKeyExpression likes userIdKey: = fmt.Sprintf("cache#user#id#%v", resp.userId) + RespKeyExpression string } // key-数据库原始字段名,value-缓存key相关数据 diff --git a/tools/goctl/model/sql/gen/template.go b/tools/goctl/model/sql/gen/template.go index c9078e6b..7c26afb5 100644 --- a/tools/goctl/model/sql/gen/template.go +++ b/tools/goctl/model/sql/gen/template.go @@ -54,18 +54,22 @@ var templates = map[string]string{ errTemplateFile: template.Error, } +// Category returns model const value func Category() string { return category } +// Clean deletes all template files func Clean() error { return util.Clean(category) } +// GenTemplates creates template files if not exists func GenTemplates(_ *cli.Context) error { return util.InitTemplates(category, templates) } +// RevertTemplate recovers the delete template files func RevertTemplate(name string) error { content, ok := templates[name] if !ok { @@ -75,6 +79,7 @@ func RevertTemplate(name string) error { return util.CreateTemplate(category, name, content) } +// Update provides template clean and init func Update() error { err := Clean() if err != nil { diff --git a/tools/goctl/model/sql/model/informationschemamodel.go b/tools/goctl/model/sql/model/informationschemamodel.go index 2f9375b8..2b7b1ba7 100644 --- a/tools/goctl/model/sql/model/informationschemamodel.go +++ b/tools/goctl/model/sql/model/informationschemamodel.go @@ -3,10 +3,12 @@ package model import "github.com/tal-tech/go-zero/core/stores/sqlx" type ( + // InformationSchemaModel defines information schema model InformationSchemaModel struct { conn sqlx.SqlConn } + // Column defines column in table Column struct { Name string `db:"COLUMN_NAME"` DataType string `db:"DATA_TYPE"` @@ -18,10 +20,12 @@ type ( } ) +// NewInformationSchemaModel creates an instance for InformationSchemaModel func NewInformationSchemaModel(conn sqlx.SqlConn) *InformationSchemaModel { return &InformationSchemaModel{conn: conn} } +// GetAllTables selects all tables from TABLE_SCHEMA func (m *InformationSchemaModel) GetAllTables(database string) ([]string, error) { query := `select TABLE_NAME from TABLES where TABLE_SCHEMA = ?` var tables []string @@ -33,9 +37,10 @@ func (m *InformationSchemaModel) GetAllTables(database string) ([]string, error) return tables, nil } +// FindByTableName finds out the target table by name func (m *InformationSchemaModel) FindByTableName(db, table string) ([]*Column, error) { - querySql := `select COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE,COLUMN_KEY,EXTRA,COLUMN_COMMENT from COLUMNS where TABLE_SCHEMA = ? and TABLE_NAME = ?` + querySQL := `select COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE,COLUMN_KEY,EXTRA,COLUMN_COMMENT from COLUMNS where TABLE_SCHEMA = ? and TABLE_NAME = ?` var reply []*Column - err := m.conn.QueryRows(&reply, querySql, db, table) + err := m.conn.QueryRows(&reply, querySQL, db, table) return reply, err } diff --git a/tools/goctl/model/sql/parser/parser.go b/tools/goctl/model/sql/parser/parser.go index 6b5338f2..e8c24327 100644 --- a/tools/goctl/model/sql/parser/parser.go +++ b/tools/goctl/model/sql/parser/parser.go @@ -21,17 +21,20 @@ const ( const timeImport = "time.Time" type ( + // Table describes a mysql table Table struct { Name stringx.String PrimaryKey Primary Fields []Field } + // Primary describes a primary key Primary struct { Field AutoIncrement bool } + // Field describes a table field Field struct { Name stringx.String DataBaseType string @@ -41,9 +44,11 @@ type ( Comment string } + // KeyType types alias of int KeyType int ) +// Parse parses ddl into golang structure func Parse(ddl string) (*Table, error) { stmt, err := sqlparser.ParseStrictDDL(ddl) if err != nil { @@ -169,6 +174,7 @@ func getIndexKeyType(indexes []*sqlparser.IndexDefinition) (map[string]KeyType, return keyMap, nil } +// ContainsTime determines whether the table field contains time.Time func (t *Table) ContainsTime() bool { for _, item := range t.Fields { if item.DataType == timeImport { @@ -178,6 +184,7 @@ func (t *Table) ContainsTime() bool { return false } +// ConvertColumn provides type conversion for mysql clolumn, primary key lookup func ConvertColumn(db, table string, in []*model.Column) (*Table, error) { var reply Table reply.Name = stringx.From(table) diff --git a/tools/goctl/model/sql/template/delete.go b/tools/goctl/model/sql/template/delete.go index 4632f2a5..4bb6bc76 100644 --- a/tools/goctl/model/sql/template/delete.go +++ b/tools/goctl/model/sql/template/delete.go @@ -1,5 +1,6 @@ package template +// Delete defines a delete template var Delete = ` func (m *default{{.upperStartCamelObject}}Model) Delete({{.lowerStartCamelPrimaryKey}} {{.dataType}}) error { {{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne({{.lowerStartCamelPrimaryKey}}) @@ -17,4 +18,5 @@ func (m *default{{.upperStartCamelObject}}Model) Delete({{.lowerStartCamelPrimar } ` +// DeleteMethod defines a delete template for interface method var DeleteMethod = `Delete({{.lowerStartCamelPrimaryKey}} {{.dataType}}) error` diff --git a/tools/goctl/model/sql/template/errors.go b/tools/goctl/model/sql/template/errors.go index eab19d9b..06fd6415 100644 --- a/tools/goctl/model/sql/template/errors.go +++ b/tools/goctl/model/sql/template/errors.go @@ -1,5 +1,6 @@ package template +// Error defines an error template var Error = `package {{.pkg}} import "github.com/tal-tech/go-zero/core/stores/sqlx" diff --git a/tools/goctl/model/sql/template/field.go b/tools/goctl/model/sql/template/field.go index 493091cc..bf927e24 100644 --- a/tools/goctl/model/sql/template/field.go +++ b/tools/goctl/model/sql/template/field.go @@ -1,3 +1,4 @@ package template +// Field defines a filed template for types var Field = `{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}` diff --git a/tools/goctl/model/sql/template/import.go b/tools/goctl/model/sql/template/import.go index 63bf1527..bbc677e7 100644 --- a/tools/goctl/model/sql/template/import.go +++ b/tools/goctl/model/sql/template/import.go @@ -1,6 +1,7 @@ package template var ( + // Imports defines a import template for model in cache case Imports = `import ( "database/sql" "fmt" @@ -14,6 +15,7 @@ var ( "github.com/tal-tech/go-zero/tools/goctl/model/sql/builderx" ) ` + // ImportsNoCache defines a import template for model in normal case ImportsNoCache = `import ( "database/sql" "fmt" diff --git a/tools/goctl/model/sql/template/insert.go b/tools/goctl/model/sql/template/insert.go index b074c816..67757f86 100644 --- a/tools/goctl/model/sql/template/insert.go +++ b/tools/goctl/model/sql/template/insert.go @@ -1,5 +1,6 @@ package template +// Insert defines a template for insert code in model var Insert = ` func (m *default{{.upperStartCamelObject}}Model) Insert(data {{.upperStartCamelObject}}) (sql.Result,error) { {{if .withCache}}{{if .containsIndexCache}}{{.keys}} @@ -14,4 +15,5 @@ func (m *default{{.upperStartCamelObject}}Model) Insert(data {{.upperStartCamelO } ` +// InsertMethod defines a interface method template for insert code in model var InsertMethod = `Insert(data {{.upperStartCamelObject}}) (sql.Result,error)` diff --git a/tools/goctl/model/sql/template/model.go b/tools/goctl/model/sql/template/model.go index 4fdb0e00..939f3347 100644 --- a/tools/goctl/model/sql/template/model.go +++ b/tools/goctl/model/sql/template/model.go @@ -1,5 +1,6 @@ package template +// Model defines a template for model var Model = `package {{.pkg}} {{.imports}} {{.vars}} diff --git a/tools/goctl/model/sql/template/new.go b/tools/goctl/model/sql/template/new.go index 484cd3dd..77ada32e 100644 --- a/tools/goctl/model/sql/template/new.go +++ b/tools/goctl/model/sql/template/new.go @@ -1,5 +1,6 @@ package template +// New defines an template for creating model instance var New = ` func New{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) {{.upperStartCamelObject}}Model { return &default{{.upperStartCamelObject}}Model{ diff --git a/tools/goctl/model/sql/template/tag.go b/tools/goctl/model/sql/template/tag.go index 2491b23f..c04baaaf 100644 --- a/tools/goctl/model/sql/template/tag.go +++ b/tools/goctl/model/sql/template/tag.go @@ -1,3 +1,4 @@ package template +// Tag defines a tag template text var Tag = "`db:\"{{.field}}\"`" diff --git a/tools/goctl/model/sql/template/types.go b/tools/goctl/model/sql/template/types.go index a66c8501..bb752378 100644 --- a/tools/goctl/model/sql/template/types.go +++ b/tools/goctl/model/sql/template/types.go @@ -1,5 +1,6 @@ package template +// Types defines a template for types in model var Types = ` type ( {{.upperStartCamelObject}}Model interface{ diff --git a/tools/goctl/model/sql/template/update.go b/tools/goctl/model/sql/template/update.go index eedcb735..530f008f 100644 --- a/tools/goctl/model/sql/template/update.go +++ b/tools/goctl/model/sql/template/update.go @@ -1,5 +1,6 @@ package template +// Update defines a template for generating update codes var Update = ` func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelObject}}) error { {{if .withCache}}{{.primaryCacheKey}} @@ -12,4 +13,5 @@ func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelO } ` +// UpdateMethod defines an interface method template for generating update codes var UpdateMethod = `Update(data {{.upperStartCamelObject}}) error` diff --git a/tools/goctl/model/sql/template/vars.go b/tools/goctl/model/sql/template/vars.go index f40bf325..af36e0f4 100644 --- a/tools/goctl/model/sql/template/vars.go +++ b/tools/goctl/model/sql/template/vars.go @@ -2,6 +2,7 @@ package template import "fmt" +// Vars defines a template for var block in model var Vars = fmt.Sprintf(` var ( {{.lowerStartCamelObject}}FieldNames = builderx.RawFieldNames(&{{.upperStartCamelObject}}{}) diff --git a/tools/goctl/model/sql/test/model/model_test.go b/tools/goctl/model/sql/test/model/model_test.go index 9542c429..4f043f49 100644 --- a/tools/goctl/model/sql/test/model/model_test.go +++ b/tools/goctl/model/sql/test/model/model_test.go @@ -20,11 +20,11 @@ func TestStudentModel(t *testing.T) { testTable = "`student`" testUpdateName = "gozero1" testRowsAffected int64 = 1 - testInsertId int64 = 1 + testInsertID int64 = 1 ) var data Student - data.Id = testInsertId + data.ID = testInsertID data.Name = "gozero" data.Age = sql.NullInt64{ Int64: 1, @@ -43,14 +43,14 @@ func TestStudentModel(t *testing.T) { err := mockStudent(func(mock sqlmock.Sqlmock) { mock.ExpectExec(fmt.Sprintf("insert into %s", testTable)). WithArgs(data.Name, data.Age, data.Score). - WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m StudentModel) { r, err := m.Insert(data) assert.Nil(t, err) - lastInsertId, err := r.LastInsertId() + lastInsertID, err := r.LastInsertId() assert.Nil(t, err) - assert.Equal(t, testInsertId, lastInsertId) + assert.Equal(t, testInsertID, lastInsertID) rowsAffected, err := r.RowsAffected() assert.Nil(t, err) @@ -60,17 +60,17 @@ func TestStudentModel(t *testing.T) { err = mockStudent(func(mock sqlmock.Sqlmock) { mock.ExpectQuery(fmt.Sprintf("select (.+) from %s", testTable)). - WithArgs(testInsertId). - WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertId, data.Name, data.Age, data.Score, testTimeValue, testTimeValue)) + WithArgs(testInsertID). + WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertID, data.Name, data.Age, data.Score, testTimeValue, testTimeValue)) }, func(m StudentModel) { - result, err := m.FindOne(testInsertId) + result, err := m.FindOne(testInsertID) assert.Nil(t, err) assert.Equal(t, *result, data) }) assert.Nil(t, err) err = mockStudent(func(mock sqlmock.Sqlmock) { - mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(testUpdateName, data.Age, data.Score, testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(testUpdateName, data.Age, data.Score, testInsertID).WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m StudentModel) { data.Name = testUpdateName err := m.Update(data) @@ -80,19 +80,19 @@ func TestStudentModel(t *testing.T) { err = mockStudent(func(mock sqlmock.Sqlmock) { mock.ExpectQuery(fmt.Sprintf("select (.+) from %s ", testTable)). - WithArgs(testInsertId). - WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertId, data.Name, data.Age, data.Score, testTimeValue, testTimeValue)) + WithArgs(testInsertID). + WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age", "score", "create_time", "update_time"}).AddRow(testInsertID, data.Name, data.Age, data.Score, testTimeValue, testTimeValue)) }, func(m StudentModel) { - result, err := m.FindOne(testInsertId) + result, err := m.FindOne(testInsertID) assert.Nil(t, err) assert.Equal(t, *result, data) }) assert.Nil(t, err) err = mockStudent(func(mock sqlmock.Sqlmock) { - mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertID).WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m StudentModel) { - err := m.Delete(testInsertId) + err := m.Delete(testInsertID) assert.Nil(t, err) }) assert.Nil(t, err) @@ -109,11 +109,11 @@ func TestUserModel(t *testing.T) { testGender = "男" testNickname = "test_nickname" testRowsAffected int64 = 1 - testInsertId int64 = 1 + testInsertID int64 = 1 ) var data User - data.Id = testInsertId + data.ID = testInsertID data.User = testUser data.Name = "gozero" data.Password = testPassword @@ -126,14 +126,14 @@ func TestUserModel(t *testing.T) { err := mockUser(func(mock sqlmock.Sqlmock) { mock.ExpectExec(fmt.Sprintf("insert into %s", testTable)). WithArgs(data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname). - WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m UserModel) { r, err := m.Insert(data) assert.Nil(t, err) - lastInsertId, err := r.LastInsertId() + lastInsertID, err := r.LastInsertId() assert.Nil(t, err) - assert.Equal(t, testInsertId, lastInsertId) + assert.Equal(t, testInsertID, lastInsertID) rowsAffected, err := r.RowsAffected() assert.Nil(t, err) @@ -143,17 +143,17 @@ func TestUserModel(t *testing.T) { err = mockUser(func(mock sqlmock.Sqlmock) { mock.ExpectQuery(fmt.Sprintf("select (.+) from %s", testTable)). - WithArgs(testInsertId). - WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertId, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue)) + WithArgs(testInsertID). + WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertID, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue)) }, func(m UserModel) { - result, err := m.FindOne(testInsertId) + result, err := m.FindOne(testInsertID) assert.Nil(t, err) assert.Equal(t, *result, data) }) assert.Nil(t, err) err = mockUser(func(mock sqlmock.Sqlmock) { - mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(data.User, testUpdateName, data.Password, data.Mobile, data.Gender, data.Nickname, testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + mock.ExpectExec(fmt.Sprintf("update %s", testTable)).WithArgs(data.User, testUpdateName, data.Password, data.Mobile, data.Gender, data.Nickname, testInsertID).WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m UserModel) { data.Name = testUpdateName err := m.Update(data) @@ -163,19 +163,19 @@ func TestUserModel(t *testing.T) { err = mockUser(func(mock sqlmock.Sqlmock) { mock.ExpectQuery(fmt.Sprintf("select (.+) from %s ", testTable)). - WithArgs(testInsertId). - WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertId, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue)) + WithArgs(testInsertID). + WillReturnRows(sqlmock.NewRows([]string{"id", "user", "name", "password", "mobile", "gender", "nickname", "create_time", "update_time"}).AddRow(testInsertID, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, testTimeValue, testTimeValue)) }, func(m UserModel) { - result, err := m.FindOne(testInsertId) + result, err := m.FindOne(testInsertID) assert.Nil(t, err) assert.Equal(t, *result, data) }) assert.Nil(t, err) err = mockUser(func(mock sqlmock.Sqlmock) { - mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertId).WillReturnResult(sqlmock.NewResult(testInsertId, testRowsAffected)) + mock.ExpectExec(fmt.Sprintf("delete from %s where `id` = ?", testTable)).WithArgs(testInsertID).WillReturnResult(sqlmock.NewResult(testInsertID, testRowsAffected)) }, func(m UserModel) { - err := m.Delete(testInsertId) + err := m.Delete(testInsertID) assert.Nil(t, err) }) assert.Nil(t, err) diff --git a/tools/goctl/model/sql/test/model/studentmodel.go b/tools/goctl/model/sql/test/model/studentmodel.go index 01ee76f7..f8aaeeec 100755 --- a/tools/goctl/model/sql/test/model/studentmodel.go +++ b/tools/goctl/model/sql/test/model/studentmodel.go @@ -19,10 +19,11 @@ var ( studentRowsExpectAutoSet = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), ",") studentRowsWithPlaceHolder = strings.Join(stringx.Remove(studentFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?" - cacheStudentIdPrefix = "cache#Student#id#" + cacheStudentIDPrefix = "cache#Student#id#" ) type ( + // StudentModel defines a model for Student StudentModel interface { Insert(data Student) (sql.Result, error) FindOne(id int64) (*Student, error) @@ -35,8 +36,9 @@ type ( table string } + // Student defines an data structure for mysql Student struct { - Id int64 `db:"id"` + ID int64 `db:"id"` Name string `db:"name"` Age sql.NullInt64 `db:"age"` Score sql.NullFloat64 `db:"score"` @@ -45,6 +47,7 @@ type ( } ) +// NewStudentModel creates an instance for StudentModel func NewStudentModel(conn sqlx.SqlConn, c cache.CacheConf) StudentModel { return &defaultStudentModel{ CachedConn: sqlc.NewConn(conn, c), @@ -60,9 +63,9 @@ func (m *defaultStudentModel) Insert(data Student) (sql.Result, error) { } func (m *defaultStudentModel) FindOne(id int64) (*Student, error) { - studentIdKey := fmt.Sprintf("%s%v", cacheStudentIdPrefix, id) + studentIDKey := fmt.Sprintf("%s%v", cacheStudentIDPrefix, id) var resp Student - err := m.QueryRow(&resp, studentIdKey, func(conn sqlx.SqlConn, v interface{}) error { + err := m.QueryRow(&resp, studentIDKey, func(conn sqlx.SqlConn, v interface{}) error { query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", studentRows, m.table) return conn.QueryRow(v, query, id) }) @@ -77,26 +80,26 @@ func (m *defaultStudentModel) FindOne(id int64) (*Student, error) { } func (m *defaultStudentModel) Update(data Student) error { - studentIdKey := fmt.Sprintf("%s%v", cacheStudentIdPrefix, data.Id) + studentIDKey := fmt.Sprintf("%s%v", cacheStudentIDPrefix, data.ID) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, studentRowsWithPlaceHolder) - return conn.Exec(query, data.Name, data.Age, data.Score, data.Id) - }, studentIdKey) + return conn.Exec(query, data.Name, data.Age, data.Score, data.ID) + }, studentIDKey) return err } func (m *defaultStudentModel) Delete(id int64) error { - studentIdKey := fmt.Sprintf("%s%v", cacheStudentIdPrefix, id) + studentIDKey := fmt.Sprintf("%s%v", cacheStudentIDPrefix, id) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("delete from %s where `id` = ?", m.table) return conn.Exec(query, id) - }, studentIdKey) + }, studentIDKey) return err } func (m *defaultStudentModel) formatPrimary(primary interface{}) string { - return fmt.Sprintf("%s%v", cacheStudentIdPrefix, primary) + return fmt.Sprintf("%s%v", cacheStudentIDPrefix, primary) } func (m *defaultStudentModel) queryPrimary(conn sqlx.SqlConn, v, primary interface{}) error { diff --git a/tools/goctl/model/sql/test/model/usermodel.go b/tools/goctl/model/sql/test/model/usermodel.go index bcef7843..b3f773fe 100755 --- a/tools/goctl/model/sql/test/model/usermodel.go +++ b/tools/goctl/model/sql/test/model/usermodel.go @@ -20,6 +20,7 @@ var ( ) type ( + // UserModel defines a model for user UserModel interface { Insert(data User) (sql.Result, error) FindOne(id int64) (*User, error) @@ -35,8 +36,9 @@ type ( table string } + // User defines an data structure for mysql User struct { - Id int64 `db:"id"` + ID int64 `db:"id"` User string `db:"user"` // 用户 Name string `db:"name"` // 用户名称 Password string `db:"password"` // 用户密码 @@ -48,6 +50,7 @@ type ( } ) +// NewUserModel creates an instance for UserModel func NewUserModel(conn sqlx.SqlConn) UserModel { return &defaultUserModel{ conn: conn, @@ -119,7 +122,7 @@ func (m *defaultUserModel) FindOneByMobile(mobile string) (*User, error) { func (m *defaultUserModel) Update(data User) error { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userRowsWithPlaceHolder) - _, err := m.conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) + _, err := m.conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.ID) return err } diff --git a/tools/goctl/model/sql/test/model/vars.go b/tools/goctl/model/sql/test/model/vars.go index b7a5e88f..b1a15608 100644 --- a/tools/goctl/model/sql/test/model/vars.go +++ b/tools/goctl/model/sql/test/model/vars.go @@ -2,4 +2,5 @@ package model import "github.com/tal-tech/go-zero/core/stores/sqlx" +// ErrNotFound types an alias for sqlx.ErrNotFound var ErrNotFound = sqlx.ErrNotFound diff --git a/tools/goctl/model/sql/test/orm.go b/tools/goctl/model/sql/test/orm.go index 26729993..b4d09bfc 100644 --- a/tools/goctl/model/sql/test/orm.go +++ b/tools/goctl/model/sql/test/orm.go @@ -13,9 +13,13 @@ import ( const tagName = "db" var ( - ErrNotMatchDestination = errors.New("not matching destination to scan") - ErrNotReadableValue = errors.New("value not addressable or interfaceable") - ErrNotSettable = errors.New("passed in variable is not settable") + // ErrNotMatchDestination defines an error for mismatching case + ErrNotMatchDestination = errors.New("not matching destination to scan") + // ErrNotReadableValue defines an error for the value is not addressable or interfaceable + ErrNotReadableValue = errors.New("value not addressable or interfaceable") + // ErrNotSettable defines an error for the variable is not settable + ErrNotSettable = errors.New("passed in variable is not settable") + // ErrUnsupportedValueType deinfes an error for unsupported unmarshal type ErrUnsupportedValueType = errors.New("unsupported unmarshal type") ) diff --git a/tools/goctl/model/sql/test/sqlconn.go b/tools/goctl/model/sql/test/sqlconn.go index 5ecc5b62..164dedfc 100644 --- a/tools/goctl/model/sql/test/sqlconn.go +++ b/tools/goctl/model/sql/test/sqlconn.go @@ -9,6 +9,7 @@ import ( ) type ( + // MockConn defines a mock connection instance for mysql MockConn struct { db *sql.DB } @@ -17,43 +18,51 @@ type ( } ) +// NewMockConn creates an instance for MockConn func NewMockConn(db *sql.DB) *MockConn { return &MockConn{db: db} } +// Exec executes sql and returns the result func (conn *MockConn) Exec(query string, args ...interface{}) (sql.Result, error) { return exec(conn.db, query, args...) } +// Prepare executes sql by sql.DB func (conn *MockConn) Prepare(query string) (sqlx.StmtSession, error) { st, err := conn.db.Prepare(query) return statement{stmt: st}, err } +// QueryRow executes sql and returns a query row func (conn *MockConn) QueryRow(v interface{}, q string, args ...interface{}) error { return query(conn.db, func(rows *sql.Rows) error { return unmarshalRow(v, rows, true) }, q, args...) } +// QueryRowPartial executes sql and returns a partial query row func (conn *MockConn) QueryRowPartial(v interface{}, q string, args ...interface{}) error { return query(conn.db, func(rows *sql.Rows) error { return unmarshalRow(v, rows, false) }, q, args...) } +// QueryRows executes sql and returns query rows func (conn *MockConn) QueryRows(v interface{}, q string, args ...interface{}) error { return query(conn.db, func(rows *sql.Rows) error { return unmarshalRows(v, rows, true) }, q, args...) } +// QueryRowsPartial executes sql and returns partial query rows func (conn *MockConn) QueryRowsPartial(v interface{}, q string, args ...interface{}) error { return query(conn.db, func(rows *sql.Rows) error { return unmarshalRows(v, rows, false) }, q, args...) } +// Transact is the implemention of sqlx.SqlConn, nothing to do func (conn *MockConn) Transact(func(session sqlx.Session) error) error { return nil } diff --git a/tools/goctl/model/sql/test/utils.go b/tools/goctl/model/sql/test/utils.go index c646a5ff..2ca42ec5 100644 --- a/tools/goctl/model/sql/test/utils.go +++ b/tools/goctl/model/sql/test/utils.go @@ -94,11 +94,6 @@ func format(query string, args ...interface{}) (string, error) { return b.String(), nil } -func logInstanceError(datasource string, err error) { - datasource = desensitize(datasource) - logx.Errorf("Error on getting sql instance of %s: %v", datasource, err) -} - func logSqlError(stmt string, err error) { if err != nil && err != ErrNotFound { logx.Errorf("stmt: %s, error: %s", stmt, err.Error()) diff --git a/tools/goctl/model/sql/util/matcher.go b/tools/goctl/model/sql/util/matcher.go index fd123927..b7e84e05 100644 --- a/tools/goctl/model/sql/util/matcher.go +++ b/tools/goctl/model/sql/util/matcher.go @@ -5,7 +5,7 @@ import ( "path/filepath" ) -// expression: globbing patterns +// MatchFiles returns the match values by globbing patterns func MatchFiles(in string) ([]string, error) { dir, pattern := filepath.Split(in) abs, err := filepath.Abs(dir) diff --git a/tools/goctl/model/sql/util/slice.go b/tools/goctl/model/sql/util/slice.go index 307f567a..6ffc4129 100644 --- a/tools/goctl/model/sql/util/slice.go +++ b/tools/goctl/model/sql/util/slice.go @@ -1,5 +1,6 @@ package util +// TrimStringSlice returns a copy slice without empty string item func TrimStringSlice(list []string) []string { var out []string for _, item := range list { diff --git a/tools/goctl/plugin/plugin.go b/tools/goctl/plugin/plugin.go index 5a7515e3..a87fcb0b 100644 --- a/tools/goctl/plugin/plugin.go +++ b/tools/goctl/plugin/plugin.go @@ -22,6 +22,7 @@ import ( const pluginArg = "_plugin" +// Plugin defines an api plugin type Plugin struct { Api *spec.ApiSpec ApiFilePath string @@ -29,6 +30,7 @@ type Plugin struct { Dir string } +// PluginCommand is the entry of goctl api plugin func PluginCommand(c *cli.Context) error { ex, err := os.Executable() if err != nil { @@ -155,6 +157,7 @@ func downloadFile(filepath string, url string) error { return err } +// NewPlugin returns contextual resources when written in other languages func NewPlugin() (*Plugin, error) { var plugin Plugin content, err := ioutil.ReadAll(os.Stdin) diff --git a/tools/goctl/rpc/cli/cli.go b/tools/goctl/rpc/cli/cli.go index ba7bf657..f9d42d38 100644 --- a/tools/goctl/rpc/cli/cli.go +++ b/tools/goctl/rpc/cli/cli.go @@ -9,10 +9,10 @@ import ( "github.com/urfave/cli" ) -// Rpc is to generate rpc service code from a proto file by specifying a proto file using flag src, +// RPC is to generate rpc service code from a proto file by specifying a proto file using flag src, // you can specify a target folder for code generation, when the proto file has import, you can specify // the import search directory through the proto_path command, for specific usage, please refer to protoc -h -func Rpc(c *cli.Context) error { +func RPC(c *cli.Context) error { src := c.String("src") out := c.String("dir") style := c.String("style") @@ -24,7 +24,7 @@ func Rpc(c *cli.Context) error { return errors.New("missing -dir") } - g, err := generator.NewDefaultRpcGenerator(style) + g, err := generator.NewDefaultRPCGenerator(style) if err != nil { return err } @@ -32,9 +32,9 @@ func Rpc(c *cli.Context) error { return g.Generate(src, out, protoImportPath) } -// RpcNew is to generate rpc greet service, this greet service can speed +// RPCNew is to generate rpc greet service, this greet service can speed // up your understanding of the zrpc service structure -func RpcNew(c *cli.Context) error { +func RPCNew(c *cli.Context) error { rpcname := c.Args().First() ext := filepath.Ext(rpcname) if len(ext) > 0 { @@ -54,7 +54,7 @@ func RpcNew(c *cli.Context) error { return err } - g, err := generator.NewDefaultRpcGenerator(style) + g, err := generator.NewDefaultRPCGenerator(style) if err != nil { return err } @@ -62,7 +62,8 @@ func RpcNew(c *cli.Context) error { return g.Generate(src, filepath.Dir(src), nil) } -func RpcTemplate(c *cli.Context) error { +// RPCTemplate is the entry for generate rpc template +func RPCTemplate(c *cli.Context) error { protoFile := c.String("o") if len(protoFile) == 0 { return errors.New("missing -o") diff --git a/tools/goctl/rpc/execx/execx.go b/tools/goctl/rpc/execx/execx.go index 9ce67305..e7536935 100644 --- a/tools/goctl/rpc/execx/execx.go +++ b/tools/goctl/rpc/execx/execx.go @@ -12,6 +12,9 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/vars" ) +// Run provides the execution of shell scripts in golang, +// which can support macOS, Windows, and Linux operating systems. +// Other operating systems are currently not supported func Run(arg string, dir string, in ...*bytes.Buffer) (string, error) { goos := runtime.GOOS var cmd *exec.Cmd diff --git a/tools/goctl/rpc/generator/defaultgenerator.go b/tools/goctl/rpc/generator/defaultgenerator.go index eb5853d1..44e0efa5 100644 --- a/tools/goctl/rpc/generator/defaultgenerator.go +++ b/tools/goctl/rpc/generator/defaultgenerator.go @@ -6,18 +6,22 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util/console" ) -type defaultGenerator struct { +// DefaultGenerator defines the environment needs of rpc service generation +type DefaultGenerator struct { log console.Console } -func NewDefaultGenerator() *defaultGenerator { +// NewDefaultGenerator returns an instance of DefaultGenerator +func NewDefaultGenerator() *DefaultGenerator { log := console.NewColorConsole() - return &defaultGenerator{ + return &DefaultGenerator{ log: log, } } -func (g *defaultGenerator) Prepare() error { +// Prepare provides environment detection generated by rpc service, +// including go environment, protoc, whether protoc-gen-go is installed or not +func (g *DefaultGenerator) Prepare() error { _, err := exec.LookPath("go") if err != nil { return err diff --git a/tools/goctl/rpc/generator/gen.go b/tools/goctl/rpc/generator/gen.go index fb298c7f..4eb82adc 100644 --- a/tools/goctl/rpc/generator/gen.go +++ b/tools/goctl/rpc/generator/gen.go @@ -10,27 +10,33 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util/ctx" ) -type RpcGenerator struct { +// RPCGenerator defines a generator and configure +type RPCGenerator struct { g Generator cfg *conf.Config } -func NewDefaultRpcGenerator(style string) (*RpcGenerator, error) { +// NewDefaultRPCGenerator wraps Generator with configure +func NewDefaultRPCGenerator(style string) (*RPCGenerator, error) { cfg, err := conf.NewConfig(style) if err != nil { return nil, err } - return NewRpcGenerator(NewDefaultGenerator(), cfg), nil + return NewRPCGenerator(NewDefaultGenerator(), cfg), nil } -func NewRpcGenerator(g Generator, cfg *conf.Config) *RpcGenerator { - return &RpcGenerator{ +// NewRPCGenerator creates an instance for RPCGenerator +func NewRPCGenerator(g Generator, cfg *conf.Config) *RPCGenerator { + return &RPCGenerator{ g: g, cfg: cfg, } } -func (g *RpcGenerator) Generate(src, target string, protoImportPath []string) error { +// Generate generates an rpc service, through the proto file, +// code storage directory, and proto import parameters to control +// the source file and target location of the rpc service that needs to be generated +func (g *RPCGenerator) Generate(src, target string, protoImportPath []string) error { abs, err := filepath.Abs(target) if err != nil { return err diff --git a/tools/goctl/rpc/generator/gen_test.go b/tools/goctl/rpc/generator/gen_test.go index 45af8cdd..b1c0720c 100644 --- a/tools/goctl/rpc/generator/gen_test.go +++ b/tools/goctl/rpc/generator/gen_test.go @@ -27,7 +27,7 @@ func TestRpcGenerate(t *testing.T) { return } projectName := stringx.Rand() - g := NewRpcGenerator(dispatcher, cfg) + g := NewRPCGenerator(dispatcher, cfg) // case go path src := filepath.Join(build.Default.GOPATH, "src") diff --git a/tools/goctl/rpc/generator/gencall.go b/tools/goctl/rpc/generator/gencall.go index 3e50722a..4c6f7426 100644 --- a/tools/goctl/rpc/generator/gencall.go +++ b/tools/goctl/rpc/generator/gencall.go @@ -61,7 +61,9 @@ func (m *default{{.serviceName}}) {{.method}}(ctx context.Context,in *{{.pbReque ` ) -func (g *defaultGenerator) GenCall(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { +// 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 *DefaultGenerator) GenCall(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { dir := ctx.GetCall() service := proto.Service head := util.GetHead(proto.Name) @@ -105,7 +107,7 @@ func (g *defaultGenerator) GenCall(ctx DirContext, proto parser.Proto, cfg *conf return err } -func (g *defaultGenerator) genFunction(goPackage string, service parser.Service) ([]string, error) { +func (g *DefaultGenerator) genFunction(goPackage string, service parser.Service) ([]string, error) { functions := make([]string, 0) for _, rpc := range service.RPC { text, err := util.LoadTemplate(category, callFunctionTemplateFile, callFunctionTemplate) @@ -133,7 +135,7 @@ func (g *defaultGenerator) genFunction(goPackage string, service parser.Service) return functions, nil } -func (g *defaultGenerator) getInterfaceFuncs(service parser.Service) ([]string, error) { +func (g *DefaultGenerator) getInterfaceFuncs(service parser.Service) ([]string, error) { functions := make([]string, 0) for _, rpc := range service.RPC { diff --git a/tools/goctl/rpc/generator/genconfig.go b/tools/goctl/rpc/generator/genconfig.go index d68c23bf..b255bade 100644 --- a/tools/goctl/rpc/generator/genconfig.go +++ b/tools/goctl/rpc/generator/genconfig.go @@ -20,7 +20,11 @@ type Config struct { } ` -func (g *defaultGenerator) GenConfig(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { +// GenConfig generates the configuration structure definition file of the rpc service, +// which contains the zrpc.RpcServerConf configuration item by default. +// You can specify the naming style of the target file name through config.Config. For details, +// see https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/config.go +func (g *DefaultGenerator) GenConfig(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { dir := ctx.GetConfig() configFilename, err := format.FileNamingFormat(cfg.NamingFormat, "config") if err != nil { diff --git a/tools/goctl/rpc/generator/generator.go b/tools/goctl/rpc/generator/generator.go index ef35b7a7..7b9a2c72 100644 --- a/tools/goctl/rpc/generator/generator.go +++ b/tools/goctl/rpc/generator/generator.go @@ -5,6 +5,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/rpc/parser" ) +// Generator defines a generator interface to describe how to generate rpc service type Generator interface { Prepare() error GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config) error diff --git a/tools/goctl/rpc/generator/genetc.go b/tools/goctl/rpc/generator/genetc.go index caeffb99..60ebe31e 100644 --- a/tools/goctl/rpc/generator/genetc.go +++ b/tools/goctl/rpc/generator/genetc.go @@ -20,7 +20,9 @@ Etcd: Key: {{.serviceName}}.rpc ` -func (g *defaultGenerator) GenEtc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { +// GenEtc generates the yaml configuration file of the rpc service, +// including host, port monitoring configuration items and etcd configuration +func (g *DefaultGenerator) GenEtc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { dir := ctx.GetEtc() etcFilename, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source()) if err != nil { diff --git a/tools/goctl/rpc/generator/genlogic.go b/tools/goctl/rpc/generator/genlogic.go index c3e967c7..c303f1ea 100644 --- a/tools/goctl/rpc/generator/genlogic.go +++ b/tools/goctl/rpc/generator/genlogic.go @@ -48,7 +48,8 @@ func (l *{{.logicName}}) {{.method}} (in {{.request}}) ({{.response}}, error) { ` ) -func (g *defaultGenerator) GenLogic(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { +// GenLogic generates the logic file of the rpc service, which corresponds to the RPC definition items in proto. +func (g *DefaultGenerator) GenLogic(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { dir := ctx.GetLogic() for _, rpc := range proto.Service.RPC { logicFilename, err := format.FileNamingFormat(cfg.NamingFormat, rpc.Name+"_logic") @@ -81,7 +82,7 @@ func (g *defaultGenerator) GenLogic(ctx DirContext, proto parser.Proto, cfg *con return nil } -func (g *defaultGenerator) genLogicFunction(goPackage string, rpc *parser.RPC) (string, error) { +func (g *DefaultGenerator) genLogicFunction(goPackage string, rpc *parser.RPC) (string, error) { var functions = make([]string, 0) text, err := util.LoadTemplate(category, logicFuncTemplateFileFile, logicFunctionTemplate) if err != nil { diff --git a/tools/goctl/rpc/generator/genmain.go b/tools/goctl/rpc/generator/genmain.go index b62eb4e4..7f40a9df 100644 --- a/tools/goctl/rpc/generator/genmain.go +++ b/tools/goctl/rpc/generator/genmain.go @@ -12,9 +12,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util/stringx" ) -const mainTemplate = `{{.head}} - -package main +const mainTemplate = `package main import ( "flag" @@ -47,7 +45,8 @@ func main() { } ` -func (g *defaultGenerator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { +// GenMain generates the main file of the rpc service, which is an rpc service program call entry +func (g *DefaultGenerator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { mainFilename, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source()) if err != nil { return err @@ -60,14 +59,12 @@ func (g *defaultGenerator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf remoteImport := fmt.Sprintf(`"%v"`, ctx.GetServer().Package) configImport := fmt.Sprintf(`"%v"`, ctx.GetConfig().Package) imports = append(imports, configImport, pbImport, remoteImport, svcImport) - head := util.GetHead(proto.Name) text, err := util.LoadTemplate(category, mainTemplateFile, mainTemplate) if err != nil { return err } return util.With("main").GoFmt(true).Parse(text).SaveTo(map[string]interface{}{ - "head": head, "serviceName": strings.ToLower(ctx.GetServiceName().ToCamel()), "imports": strings.Join(imports, util.NL), "pkg": proto.PbPackage, diff --git a/tools/goctl/rpc/generator/genpb.go b/tools/goctl/rpc/generator/genpb.go index bc2ff20a..b29bde04 100644 --- a/tools/goctl/rpc/generator/genpb.go +++ b/tools/goctl/rpc/generator/genpb.go @@ -10,7 +10,9 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/rpc/parser" ) -func (g *defaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, _ *conf.Config) error { +// GenPb generates the pb.go file, which is a layer of packaging for protoc to generate gprc, +// but the commands and flags in protoc are not completely joined in goctl. At present, proto_path(-I) is introduced +func (g *DefaultGenerator) GenPb(ctx DirContext, protoImportPath []string, proto parser.Proto, _ *conf.Config) error { dir := ctx.GetPb() cw := new(bytes.Buffer) base := filepath.Dir(proto.Src) diff --git a/tools/goctl/rpc/generator/genserver.go b/tools/goctl/rpc/generator/genserver.go index c5cb124f..61f2dad9 100644 --- a/tools/goctl/rpc/generator/genserver.go +++ b/tools/goctl/rpc/generator/genserver.go @@ -45,7 +45,8 @@ func (s *{{.server}}Server) {{.method}} (ctx context.Context, in {{.request}}) ( ` ) -func (g *defaultGenerator) GenServer(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { +// GenServer generates rpc server file, which is an implementation of rpc server +func (g *DefaultGenerator) GenServer(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { dir := ctx.GetServer() logicImport := fmt.Sprintf(`"%v"`, ctx.GetLogic().Package) svcImport := fmt.Sprintf(`"%v"`, ctx.GetSvc().Package) @@ -81,7 +82,7 @@ func (g *defaultGenerator) GenServer(ctx DirContext, proto parser.Proto, cfg *co return err } -func (g *defaultGenerator) genFunctions(goPackage string, service parser.Service) ([]string, error) { +func (g *DefaultGenerator) genFunctions(goPackage string, service parser.Service) ([]string, error) { var functionList []string for _, rpc := range service.RPC { text, err := util.LoadTemplate(category, serverFuncTemplateFile, functionTemplate) diff --git a/tools/goctl/rpc/generator/gensvc.go b/tools/goctl/rpc/generator/gensvc.go index beda3c0c..8bc1a9e1 100644 --- a/tools/goctl/rpc/generator/gensvc.go +++ b/tools/goctl/rpc/generator/gensvc.go @@ -25,7 +25,9 @@ func NewServiceContext(c config.Config) *ServiceContext { } ` -func (g *defaultGenerator) GenSvc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { +// GenSvc generates the servicecontext.go file, which is the resource dependency of a service, +// such as rpc dependency, model dependency, etc. +func (g *DefaultGenerator) GenSvc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { dir := ctx.GetSvc() svcFilename, err := format.FileNamingFormat(cfg.NamingFormat, "service_context") if err != nil { diff --git a/tools/goctl/rpc/generator/mkdir.go b/tools/goctl/rpc/generator/mkdir.go index 8be924d1..b1aa6ece 100644 --- a/tools/goctl/rpc/generator/mkdir.go +++ b/tools/goctl/rpc/generator/mkdir.go @@ -23,6 +23,7 @@ const ( ) type ( + // DirContext defines a rpc service directories context DirContext interface { GetCall() Dir GetEtc() Dir @@ -36,11 +37,13 @@ type ( GetServiceName() stringx.String } + // Dir defines a directory Dir struct { Base string Filename string Package string } + defaultDirContext struct { inner map[string]Dir serviceName stringx.String @@ -159,6 +162,7 @@ func (d *defaultDirContext) GetServiceName() stringx.String { return d.serviceName } +// Valid returns true if the directory is valid func (d *Dir) Valid() bool { return len(d.Filename) > 0 && len(d.Package) > 0 } diff --git a/tools/goctl/rpc/generator/prototmpl.go b/tools/goctl/rpc/generator/prototmpl.go index e772a7f7..f7149141 100644 --- a/tools/goctl/rpc/generator/prototmpl.go +++ b/tools/goctl/rpc/generator/prototmpl.go @@ -25,6 +25,7 @@ service {{.serviceName}} { } ` +// ProtoTmpl returns an sample of a proto file func ProtoTmpl(out string) error { protoFilename := filepath.Base(out) serviceName := stringx.From(strings.TrimSuffix(protoFilename, filepath.Ext(protoFilename))) diff --git a/tools/goctl/rpc/generator/template.go b/tools/goctl/rpc/generator/template.go index 8f41fa06..dbf8faaa 100644 --- a/tools/goctl/rpc/generator/template.go +++ b/tools/goctl/rpc/generator/template.go @@ -38,10 +38,13 @@ var templates = map[string]string{ rpcTemplateFile: rpcTemplateText, } +// GenTemplates is the entry for command goctl template, +// it will create the specified category func GenTemplates(_ *cli.Context) error { return util.InitTemplates(category, templates) } +// RevertTemplate restores the deleted template files func RevertTemplate(name string) error { content, ok := templates[name] if !ok { @@ -50,10 +53,13 @@ func RevertTemplate(name string) error { return util.CreateTemplate(category, name, content) } +// Clean deletes all template files func Clean() error { return util.Clean(category) } +// Update is used to update the template files, it will delete the existing old templates at first, +// and then create the latest template files func Update() error { err := Clean() if err != nil { @@ -63,6 +69,7 @@ func Update() error { return util.InitTemplates(category, templates) } +// Category returns a const string value for rpc template category func Category() string { return category } diff --git a/tools/goctl/rpc/parser/comment.go b/tools/goctl/rpc/parser/comment.go index 8d2058cd..e0e72be6 100644 --- a/tools/goctl/rpc/parser/comment.go +++ b/tools/goctl/rpc/parser/comment.go @@ -2,6 +2,7 @@ package parser import "github.com/emicklei/proto" +// GetComment returns content with prefix // func GetComment(comment *proto.Comment) string { if comment == nil { return "" diff --git a/tools/goctl/rpc/parser/import.go b/tools/goctl/rpc/parser/import.go index 5095d52e..bb9591f5 100644 --- a/tools/goctl/rpc/parser/import.go +++ b/tools/goctl/rpc/parser/import.go @@ -2,6 +2,7 @@ package parser import "github.com/emicklei/proto" +// Import embeds proto.Import type Import struct { *proto.Import } diff --git a/tools/goctl/rpc/parser/message.go b/tools/goctl/rpc/parser/message.go index 5f5a7196..9d2c654e 100644 --- a/tools/goctl/rpc/parser/message.go +++ b/tools/goctl/rpc/parser/message.go @@ -1,7 +1,8 @@ package parser -import pr "github.com/emicklei/proto" +import "github.com/emicklei/proto" +// Message embeds proto.Message type Message struct { - *pr.Message + *proto.Message } diff --git a/tools/goctl/rpc/parser/option.go b/tools/goctl/rpc/parser/option.go index 06f34cf4..25f5ee65 100644 --- a/tools/goctl/rpc/parser/option.go +++ b/tools/goctl/rpc/parser/option.go @@ -2,6 +2,7 @@ package parser import "github.com/emicklei/proto" +// Option embeds proto.Option type Option struct { *proto.Option } diff --git a/tools/goctl/rpc/parser/parser.go b/tools/goctl/rpc/parser/parser.go index 764f647d..718cc37e 100644 --- a/tools/goctl/rpc/parser/parser.go +++ b/tools/goctl/rpc/parser/parser.go @@ -14,14 +14,18 @@ import ( ) type ( - defaultProtoParser struct{} + // DefaultProtoParser types a empty struct + DefaultProtoParser struct{} ) -func NewDefaultProtoParser() *defaultProtoParser { - return &defaultProtoParser{} +// NewDefaultProtoParser creates a new instance +func NewDefaultProtoParser() *DefaultProtoParser { + return &DefaultProtoParser{} } -func (p *defaultProtoParser) Parse(src string) (Proto, error) { +// Parse provides to parse the proto file into a golang structure, +// which is convenient for subsequent rpc generation and use +func (p *DefaultProtoParser) Parse(src string) (Proto, error) { var ret Proto abs, err := filepath.Abs(src) @@ -101,7 +105,7 @@ func (p *defaultProtoParser) Parse(src string) (Proto, error) { return ret, nil } -// see google.golang.org/protobuf@v1.25.0/internal/strs/strings.go:71 +// GoSanitized copy from protobuf, for more information, please see google.golang.org/protobuf@v1.25.0/internal/strs/strings.go:71 func GoSanitized(s string) string { // Sanitize the input to the set of valid characters, // which must be '_' or be in the Unicode L or N categories. @@ -121,7 +125,7 @@ func GoSanitized(s string) string { return s } -// copy from github.com/golang/protobuf@v1.4.2/protoc-gen-go/generator/generator.go:2648 +// CamelCase copy from protobuf, for more information, please see github.com/golang/protobuf@v1.4.2/protoc-gen-go/generator/generator.go:2648 func CamelCase(s string) string { if s == "" { return "" diff --git a/tools/goctl/rpc/parser/proto.go b/tools/goctl/rpc/parser/proto.go index 4e23b8e5..084f824d 100644 --- a/tools/goctl/rpc/parser/proto.go +++ b/tools/goctl/rpc/parser/proto.go @@ -1,5 +1,6 @@ package parser +// Proto describes a proto file, type Proto struct { Src string Name string diff --git a/tools/goctl/rpc/parser/rpc.go b/tools/goctl/rpc/parser/rpc.go index bf4cd8ed..bfaf03be 100644 --- a/tools/goctl/rpc/parser/rpc.go +++ b/tools/goctl/rpc/parser/rpc.go @@ -2,6 +2,7 @@ package parser import "github.com/emicklei/proto" +// RPC embeds proto.RPC type RPC struct { *proto.RPC } diff --git a/tools/goctl/rpc/parser/service.go b/tools/goctl/rpc/parser/service.go index 9ace8dfb..3c7dc2bd 100644 --- a/tools/goctl/rpc/parser/service.go +++ b/tools/goctl/rpc/parser/service.go @@ -2,6 +2,8 @@ package parser import "github.com/emicklei/proto" +// Service describes the rpc service, which is the relevant +// content after the translation of the proto file type Service struct { *proto.Service RPC []*RPC diff --git a/tools/goctl/tpl/templates.go b/tools/goctl/tpl/templates.go index c1b42272..ce38b7a0 100644 --- a/tools/goctl/tpl/templates.go +++ b/tools/goctl/tpl/templates.go @@ -16,6 +16,7 @@ import ( const templateParentPath = "/" +// GenTemplates wtites the latest template text into file which is not exists func GenTemplates(ctx *cli.Context) error { if err := errorx.Chain( func() error { @@ -48,6 +49,7 @@ func GenTemplates(ctx *cli.Context) error { return nil } +// CleanTemplates deletes all templates func CleanTemplates(_ *cli.Context) error { err := errorx.Chain( func() error { @@ -68,6 +70,8 @@ func CleanTemplates(_ *cli.Context) error { return nil } +// UpdateTemplates wtites the latest template text into file, +// it will delete the oldler templates if there are exists func UpdateTemplates(ctx *cli.Context) (err error) { category := ctx.String("category") defer func() { @@ -92,6 +96,7 @@ func UpdateTemplates(ctx *cli.Context) (err error) { } } +// RevertTemplates will overwrite the old template content with the new template func RevertTemplates(ctx *cli.Context) (err error) { category := ctx.String("category") filename := ctx.String("name") diff --git a/tools/goctl/update/config/config.go b/tools/goctl/update/config/config.go index 5da7c3de..dc3cb19c 100644 --- a/tools/goctl/update/config/config.go +++ b/tools/goctl/update/config/config.go @@ -2,6 +2,7 @@ package config import "github.com/tal-tech/go-zero/core/logx" +// Config defines a service configure for goctl update type Config struct { logx.LogConf ListenOn string diff --git a/tools/goctl/upgrade/upgrade.go b/tools/goctl/upgrade/upgrade.go index daed3d10..94952c40 100644 --- a/tools/goctl/upgrade/upgrade.go +++ b/tools/goctl/upgrade/upgrade.go @@ -7,6 +7,8 @@ import ( "github.com/urfave/cli" ) +// Upgrade gets the latest goctl by +// go get -u github.com/tal-tech/go-zero/tools/goctl func Upgrade(_ *cli.Context) error { info, err := execx.Run("GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/tal-tech/go-zero/tools/goctl", "") if err != nil { diff --git a/tools/goctl/util/console/console.go b/tools/goctl/util/console/console.go index a6cb2069..a420e7b0 100644 --- a/tools/goctl/util/console/console.go +++ b/tools/goctl/util/console/console.go @@ -28,7 +28,7 @@ type ( } ) -// NewConsole returns a instance of Console +// NewConsole returns an instance of Console func NewConsole(idea bool) Console { if idea { return NewIdeaConsole() @@ -36,7 +36,7 @@ func NewConsole(idea bool) Console { return NewColorConsole() } -// NewColorConsole returns a instance of colorConsole +// NewColorConsole returns an instance of colorConsole func NewColorConsole() Console { return &colorConsole{} } diff --git a/tools/goctl/util/file.go b/tools/goctl/util/file.go index 11f777b1..6603497f 100644 --- a/tools/goctl/util/file.go +++ b/tools/goctl/util/file.go @@ -3,6 +3,7 @@ package util import ( "bufio" "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -10,8 +11,13 @@ import ( "github.com/logrusorgru/aurora" ) -const NL = "\n" +// NL defines a new line +const ( + NL = "\n" + goctlDir = ".goctl" +) +// CreateIfNotExist creates a file if it is not exists func CreateIfNotExist(file string) (*os.File, error) { _, err := os.Stat(file) if !os.IsNotExist(err) { @@ -21,6 +27,7 @@ func CreateIfNotExist(file string) (*os.File, error) { return os.Create(file) } +// RemoveIfExist deletes the specficed file if it is exists func RemoveIfExist(filename string) error { if !FileExists(filename) { return nil @@ -29,6 +36,7 @@ func RemoveIfExist(filename string) error { return os.Remove(filename) } +// RemoveOrQuit deletes the specficed file if read a permit command from stdin func RemoveOrQuit(filename string) error { if !FileExists(filename) { return nil @@ -41,11 +49,105 @@ func RemoveOrQuit(filename string) error { return os.Remove(filename) } +// FileExists returns true if the specficed file is exists func FileExists(file string) bool { _, err := os.Stat(file) return err == nil } +// FileNameWithoutExt returns a file name without suffix func FileNameWithoutExt(file string) string { return strings.TrimSuffix(file, filepath.Ext(file)) } + +// GetGoctlHome returns the path value of the goctl home where Join $HOME with .goctl +func GetGoctlHome() (string, error) { + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + return filepath.Join(home, goctlDir), nil +} + +// GetTemplateDir returns the category path value in GoctlHome where could get it by GetGoctlHome +func GetTemplateDir(category string) (string, error) { + goctlHome, err := GetGoctlHome() + if err != nil { + return "", err + } + + return filepath.Join(goctlHome, category), nil +} + +// InitTemplates creates template files GoctlHome where could get it by GetGoctlHome +func InitTemplates(category string, templates map[string]string) error { + dir, err := GetTemplateDir(category) + if err != nil { + return err + } + + if err := MkdirIfNotExist(dir); err != nil { + return err + } + + for k, v := range templates { + if err := createTemplate(filepath.Join(dir, k), v, false); err != nil { + return err + } + } + + return nil +} + +// CreateTemplate writes template into file even it is exists +func CreateTemplate(category, name, content string) error { + dir, err := GetTemplateDir(category) + if err != nil { + return err + } + return createTemplate(filepath.Join(dir, name), content, true) +} + +// Clean deletes all templates and removes the parent directory +func Clean(category string) error { + dir, err := GetTemplateDir(category) + if err != nil { + return err + } + return os.RemoveAll(dir) +} + +// LoadTemplate gets template content by the specified file +func LoadTemplate(category, file, builtin string) (string, error) { + dir, err := GetTemplateDir(category) + if err != nil { + return "", err + } + + file = filepath.Join(dir, file) + if !FileExists(file) { + return builtin, nil + } + + content, err := ioutil.ReadFile(file) + if err != nil { + return "", err + } + + return string(content), nil +} + +func createTemplate(file, content string, force bool) error { + if FileExists(file) && !force { + return nil + } + + f, err := os.Create(file) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(content) + return err +} diff --git a/tools/goctl/util/files.go b/tools/goctl/util/files.go deleted file mode 100644 index db7dc5bd..00000000 --- a/tools/goctl/util/files.go +++ /dev/null @@ -1,95 +0,0 @@ -package util - -import ( - "io/ioutil" - "os" - "path/filepath" -) - -const goctlDir = ".goctl" - -func GetGoctlHome() (string, error) { - home, err := os.UserHomeDir() - if err != nil { - return "", err - } - return filepath.Join(home, goctlDir), nil -} - -func GetTemplateDir(category string) (string, error) { - goctlHome, err := GetGoctlHome() - if err != nil { - return "", err - } - - return filepath.Join(goctlHome, category), nil -} - -func InitTemplates(category string, templates map[string]string) error { - dir, err := GetTemplateDir(category) - if err != nil { - return err - } - - if err := MkdirIfNotExist(dir); err != nil { - return err - } - - for k, v := range templates { - if err := createTemplate(filepath.Join(dir, k), v, false); err != nil { - return err - } - } - - return nil -} - -func CreateTemplate(category, name, content string) error { - dir, err := GetTemplateDir(category) - if err != nil { - return err - } - return createTemplate(filepath.Join(dir, name), content, true) -} - -func Clean(category string) error { - dir, err := GetTemplateDir(category) - if err != nil { - return err - } - return os.RemoveAll(dir) -} - -func LoadTemplate(category, file, builtin string) (string, error) { - dir, err := GetTemplateDir(category) - if err != nil { - return "", err - } - - file = filepath.Join(dir, file) - if !FileExists(file) { - return builtin, nil - } - - content, err := ioutil.ReadFile(file) - if err != nil { - return "", err - } - - return string(content), nil -} - -func createTemplate(file, content string, force bool) error { - if FileExists(file) && !force { - return nil - } - - f, err := os.Create(file) - if err != nil { - return err - } - defer f.Close() - - _, err = f.WriteString(content) - return err -} diff --git a/tools/goctl/util/head.go b/tools/goctl/util/head.go index b7534c71..36829a5e 100644 --- a/tools/goctl/util/head.go +++ b/tools/goctl/util/head.go @@ -3,6 +3,7 @@ package util var headTemplate = `// Code generated by goctl. DO NOT EDIT! // Source: {{.source}}` +// GetHead returns a code head string with source filename func GetHead(source string) string { buffer, _ := With("head").Parse(headTemplate).Execute(map[string]interface{}{ "source": source, diff --git a/tools/goctl/util/path.go b/tools/goctl/util/path.go index 0ed6b333..3092b749 100644 --- a/tools/goctl/util/path.go +++ b/tools/goctl/util/path.go @@ -15,10 +15,12 @@ const ( goModeIdentifier = "go.mod" ) +// JoinPackages calls strings.Join and returns func JoinPackages(pkgs ...string) string { return strings.Join(pkgs, pkgSep) } +// MkdirIfNotExist makes directories if the input path is not exists func MkdirIfNotExist(dir string) error { if len(dir) == 0 { return nil @@ -31,6 +33,7 @@ func MkdirIfNotExist(dir string) error { return nil } +// PathFromGoSrc returns the path whihout slash where has been trim the prefix $GOPATH func PathFromGoSrc() (string, error) { dir, err := os.Getwd() if err != nil { @@ -48,6 +51,8 @@ func PathFromGoSrc() (string, error) { return dir[len(parent)+1:], nil } +// FindGoModPath returns the path in project where has file go.mod, it maybe return empty string if +// there is no go.mod file in project func FindGoModPath(dir string) (string, bool) { absDir, err := filepath.Abs(dir) if err != nil { @@ -80,6 +85,7 @@ func FindGoModPath(dir string) (string, bool) { return "", false } +// FindProjectPath returns the parent directory where has file go.mod in project func FindProjectPath(loc string) (string, bool) { var dir string if strings.IndexByte(loc, '/') == 0 { diff --git a/tools/goctl/util/string.go b/tools/goctl/util/string.go index 5bd945a3..019cb145 100644 --- a/tools/goctl/util/string.go +++ b/tools/goctl/util/string.go @@ -2,6 +2,8 @@ package util import "strings" +// Title returns a string value with s[0] which has been convert into upper case that +// there are not empty input text func Title(s string) string { if len(s) == 0 { return s @@ -10,6 +12,8 @@ func Title(s string) string { return strings.ToUpper(s[:1]) + s[1:] } +// Untitle returns a string value with s[0] which has been convert into lower case that +// there are not empty input text func Untitle(s string) string { if len(s) == 0 { return s @@ -18,6 +22,7 @@ func Untitle(s string) string { return strings.ToLower(s[:1]) + s[1:] } +// Index returns the index where the item equal,it will return -1 if mismatched func Index(slice []string, item string) int { for i := range slice { if slice[i] == item {