update shorturl doc

This commit is contained in:
kevin
2020-08-29 20:27:52 +08:00
parent 6e3d99e869
commit 6c4a4be5d2
16 changed files with 465 additions and 144 deletions

View File

@@ -24,7 +24,6 @@ import (
func {{.handlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.{{.logic}}(r.Context(), ctx)
{{.handlerBody}}
}
}
@@ -39,6 +38,7 @@ func {{.handlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {
}
`
hasRespTemplate = `
l := logic.{{.logic}}(r.Context(), ctx)
{{.logicResponse}} l.{{.callee}}({{.req}})
if err != nil {
httpx.Error(w, err)
@@ -84,6 +84,7 @@ func genHandler(dir string, group spec.Group, route spec.Route) error {
var logicBodyBuilder strings.Builder
t := template.Must(template.New("hasRespTemplate").Parse(hasRespTemplate))
if err := t.Execute(&logicBodyBuilder, map[string]string{
"logic": "New" + strings.TrimSuffix(strings.Title(handler), "Handler") + "Logic",
"callee": strings.Title(strings.TrimSuffix(handler, "Handler")),
"req": req,
"logicResponse": logicResponse,
@@ -134,7 +135,6 @@ func doGenToFile(dir, handler string, group spec.Group, route spec.Route, bodyBu
t := template.Must(template.New("handlerTemplate").Parse(handlerTemplate))
buffer := new(bytes.Buffer)
err = t.Execute(buffer, map[string]string{
"logic": "New" + strings.TrimSuffix(strings.Title(handler), "Handler") + "Logic",
"importPackages": genHandlerImports(group, route, parentPkg),
"handlerName": handler,
"handlerBody": strings.TrimSpace(bodyBuilder.String()),

View File

@@ -20,10 +20,9 @@ type ServiceContext struct {
Config {{.config}}
}
func NewServiceContext(config {{.config}}) *ServiceContext {
return &ServiceContext{Config: config}
func NewServiceContext(c {{.config}}) *ServiceContext {
return &ServiceContext{Config: c}
}
`
)

View File

@@ -2,7 +2,7 @@ package template
var Delete = `
func (m *{{.upperStartCamelObject}}Model) Delete({{.lowerStartCamelPrimaryKey}} {{.dataType}}) error {
{{if .withCache}}{{if .containsIndexCache}}data,err:=m.FindOne({{.lowerStartCamelPrimaryKey}})
{{if .withCache}}{{if .containsIndexCache}}_, err:=m.FindOne({{.lowerStartCamelPrimaryKey}})
if err!=nil{
return err
}{{end}}

View File

@@ -5,7 +5,6 @@ var (
"database/sql"
"fmt"
"strings"
"time"
"github.com/tal-tech/go-zero/core/stores/cache"
"github.com/tal-tech/go-zero/core/stores/sqlc"

View File

@@ -2,7 +2,7 @@ package template
var Insert = `
func (m *{{.upperStartCamelObject}}Model) Insert(data {{.upperStartCamelObject}}) (sql.Result, error) {
query := ` + "`" + `insert into ` + "`" + ` + m.table + ` + "`(` + " + `{{.lowerStartCamelObject}}RowsExpectAutoSet` + " + `) value ({{.expression}})` " + `
query := ` + "`" + `insert into ` + "`" + ` + m.table + ` + "` (` + " + `{{.lowerStartCamelObject}}RowsExpectAutoSet` + " + `) values ({{.expression}})` " + `
return m.{{if .withCache}}ExecNoCache{{else}}conn.Exec{{end}}(query, {{.expressionValues}})
}
`

View File

@@ -16,27 +16,23 @@ import (
const (
flagSrc = "src"
flagDir = "dir"
flagShared = "shared"
flagService = "service"
flagIdea = "idea"
)
type (
RpcContext struct {
ProjectPath string
ProjectName stringx.String
ServiceName stringx.String
CurrentPath string
Module string
ProtoFileSrc string
ProtoSource string
TargetDir string
SharedDir string
console.Console
}
)
type RpcContext struct {
ProjectPath string
ProjectName stringx.String
ServiceName stringx.String
CurrentPath string
Module string
ProtoFileSrc string
ProtoSource string
TargetDir string
console.Console
}
func MustCreateRpcContext(protoSrc, targetDir, sharedDir, serviceName string, idea bool) *RpcContext {
func MustCreateRpcContext(protoSrc, targetDir, serviceName string, idea bool) *RpcContext {
log := console.NewConsole(idea)
info, err := prepare(log)
log.Must(err)
@@ -54,15 +50,9 @@ func MustCreateRpcContext(protoSrc, targetDir, sharedDir, serviceName string, id
if stringx.From(targetDir).IsEmptyOrSpace() {
targetDir = current
}
if stringx.From(sharedDir).IsEmptyOrSpace() {
sharedDir = filepath.Join(current, "shared")
}
targetDirFp, err := filepath.Abs(targetDir)
log.Must(err)
sharedFp, err := filepath.Abs(sharedDir)
log.Must(err)
if stringx.From(serviceName).IsEmptyOrSpace() {
serviceName = getServiceFromRpcStructure(targetDirFp)
}
@@ -80,7 +70,6 @@ func MustCreateRpcContext(protoSrc, targetDir, sharedDir, serviceName string, id
ProtoFileSrc: srcFp,
ProtoSource: filepath.Base(srcFp),
TargetDir: targetDirFp,
SharedDir: sharedFp,
Console: log,
}
}
@@ -93,10 +82,9 @@ func MustCreateRpcContextFromCli(ctx *cli.Context) *RpcContext {
}
protoSrc := ctx.String(flagSrc)
targetDir := ctx.String(flagDir)
sharedDir := ctx.String(flagShared)
serviceName := ctx.String(flagService)
idea := ctx.Bool(flagIdea)
return MustCreateRpcContext(protoSrc, targetDir, sharedDir, serviceName, idea)
return MustCreateRpcContext(protoSrc, targetDir, serviceName, idea)
}
func getServiceFromRpcStructure(targetDir string) string {

View File

@@ -10,8 +10,7 @@ const (
dirConfig = "config"
dirEtc = "etc"
dirSvc = "svc"
dirShared = "shared"
dirHandler = "handler"
dirServer = "server"
dirLogic = "logic"
dirPb = "pb"
dirInternal = "internal"
@@ -19,13 +18,11 @@ const (
fileServiceContext = "servicecontext.go"
)
type (
defaultRpcGenerator struct {
dirM map[string]string
Ctx *ctx.RpcContext
ast *parser.PbAst
}
)
type defaultRpcGenerator struct {
dirM map[string]string
Ctx *ctx.RpcContext
ast *parser.PbAst
}
func NewDefaultRpcGenerator(ctx *ctx.RpcContext) *defaultRpcGenerator {
return &defaultRpcGenerator{
@@ -80,7 +77,7 @@ func (g *defaultRpcGenerator) Generate() (err error) {
return
}
err = g.genShared()
err = g.genCall()
if err != nil {
return
}

View File

@@ -13,9 +13,9 @@ import (
)
const (
sharedTemplateText = `{{.head}}
callTemplateText = `{{.head}}
//go:generate mockgen -destination ./{{.name}}model_mock.go -package {{.filePackage}} -source $GOFILE
//go:generate mockgen -destination ./{{.name}}_mock.go -package {{.filePackage}} -source $GOFILE
package {{.filePackage}}
@@ -29,24 +29,24 @@ import (
)
type (
{{.serviceName}}Model interface {
{{.serviceName}} interface {
{{.interface}}
}
default{{.serviceName}}Model struct {
default{{.serviceName}} struct {
cli rpcx.Client
}
)
func New{{.serviceName}}Model(cli rpcx.Client) {{.serviceName}}Model {
return &default{{.serviceName}}Model{
func New{{.serviceName}}(cli rpcx.Client) {{.serviceName}} {
return &default{{.serviceName}}{
cli: cli,
}
}
{{.functions}}
`
sharedTemplateTypes = `{{.head}}
callTemplateTypes = `{{.head}}
package {{.filePackage}}
@@ -56,11 +56,11 @@ var errJsonConvert = errors.New("json convert error")
{{.types}}
`
sharedInterfaceFunctionTemplate = `{{if .hasComment}}{{.comment}}
callInterfaceFunctionTemplate = `{{if .hasComment}}{{.comment}}
{{end}}{{.method}}(ctx context.Context,in *{{.pbRequest}}) {{if .hasResponse}}(*{{.pbResponse}},{{end}} error{{if .hasResponse}}){{end}}`
sharedFunctionTemplate = `
callFunctionTemplate = `
{{if .hasComment}}{{.comment}}{{end}}
func (m *default{{.rpcServiceName}}Model) {{.method}}(ctx context.Context,in *{{.pbRequest}}) {{if .hasResponse}}(*{{.pbResponse}},{{end}} error{{if .hasResponse}}){{end}} {
func (m *default{{.rpcServiceName}}) {{.method}}(ctx context.Context,in *{{.pbRequest}}) {{if .hasResponse}}(*{{.pbResponse}},{{end}} error{{if .hasResponse}}){{end}} {
var request {{.package}}.{{.pbRequest}}
bts, err := jsonx.Marshal(in)
if err != nil {
@@ -98,59 +98,78 @@ func (m *default{{.rpcServiceName}}Model) {{.method}}(ctx context.Context,in *{{
`
)
func (g *defaultRpcGenerator) genShared() error {
sharePackage := filepath.Base(g.Ctx.SharedDir)
func (g *defaultRpcGenerator) genCall() error {
file := g.ast
if len(file.Service) == 0 {
return nil
}
if len(file.Service) > 1 {
return fmt.Errorf("we recommend only one service in a proto, currently %d", len(file.Service))
}
typeCode, err := file.GenTypesCode()
if err != nil {
return err
}
service := file.Service[0]
callPath, err := filepath.Abs(service.Name.Lower())
if err != nil {
return err
}
if err = util.MkdirIfNotExist(callPath); err != nil {
return err
}
pbPkg := file.Package
remotePackage := fmt.Sprintf(`%v "%v"`, pbPkg, g.mustGetPackage(dirPb))
filename := filepath.Join(g.Ctx.SharedDir, "types.go")
filename := filepath.Join(callPath, "types.go")
head := util.GetHead(g.Ctx.ProtoSource)
err = util.With("types").GoFmt(true).Parse(sharedTemplateTypes).SaveTo(map[string]interface{}{
err = util.With("types").GoFmt(true).Parse(callTemplateTypes).SaveTo(map[string]interface{}{
"head": head,
"filePackage": sharePackage,
"filePackage": service.Name.Lower(),
"pbPkg": pbPkg,
"serviceName": g.Ctx.ServiceName.Title(),
"lowerStartServiceName": g.Ctx.ServiceName.UnTitle(),
"types": typeCode,
}, filename, true)
if err != nil {
return err
}
_, err = exec.LookPath("mockgen")
mockGenInstalled := err == nil
for _, service := range file.Service {
filename := filepath.Join(g.Ctx.SharedDir, fmt.Sprintf("%smodel.go", service.Name.Lower()))
functions, err := g.getFuncs(service)
if err != nil {
return err
}
iFunctions, err := g.getInterfaceFuncs(service)
if err != nil {
return err
}
mockFile := filepath.Join(g.Ctx.SharedDir, fmt.Sprintf("%smodel_mock.go", service.Name.Lower()))
os.Remove(mockFile)
err = util.With("shared").GoFmt(true).Parse(sharedTemplateText).SaveTo(map[string]interface{}{
"name": service.Name.Lower(),
"head": head,
"filePackage": sharePackage,
"pbPkg": pbPkg,
"package": remotePackage,
"serviceName": service.Name.Title(),
"functions": strings.Join(functions, "\n"),
"interface": strings.Join(iFunctions, "\n"),
}, filename, true)
if err != nil {
return err
}
// if mockgen is already installed, it will generate code of gomock for shared files
_, err = exec.LookPath("mockgen")
if mockGenInstalled {
execx.Run(fmt.Sprintf("go generate %s", filename))
}
filename = filepath.Join(callPath, fmt.Sprintf("%s.go", service.Name.Lower()))
functions, err := g.getFuncs(service)
if err != nil {
return err
}
iFunctions, err := g.getInterfaceFuncs(service)
if err != nil {
return err
}
mockFile := filepath.Join(callPath, fmt.Sprintf("%s_mock.go", service.Name.Lower()))
os.Remove(mockFile)
err = util.With("shared").GoFmt(true).Parse(callTemplateText).SaveTo(map[string]interface{}{
"name": service.Name.Lower(),
"head": head,
"filePackage": service.Name.Lower(),
"pbPkg": pbPkg,
"package": remotePackage,
"serviceName": service.Name.Title(),
"functions": strings.Join(functions, "\n"),
"interface": strings.Join(iFunctions, "\n"),
}, filename, true)
if err != nil {
return err
}
// if mockgen is already installed, it will generate code of gomock for shared files
_, err = exec.LookPath("mockgen")
if mockGenInstalled {
execx.Run(fmt.Sprintf("go generate %s", filename))
}
return nil
@@ -169,7 +188,7 @@ func (g *defaultRpcGenerator) getFuncs(service *parser.RpcService) ([]string, er
if len(method.Document) > 0 {
comment = method.Document[0]
}
buffer, err := util.With("sharedFn").Parse(sharedFunctionTemplate).Execute(map[string]interface{}{
buffer, err := util.With("sharedFn").Parse(callFunctionTemplate).Execute(map[string]interface{}{
"rpcServiceName": service.Name.Title(),
"method": method.Name.Title(),
"package": pkgName,
@@ -191,6 +210,7 @@ func (g *defaultRpcGenerator) getFuncs(service *parser.RpcService) ([]string, er
func (g *defaultRpcGenerator) getInterfaceFuncs(service *parser.RpcService) ([]string, error) {
file := g.ast
functions := make([]string, 0)
for _, method := range service.Funcs {
data, found := file.Strcuts[strings.ToLower(method.OutType)]
if found {
@@ -200,19 +220,21 @@ func (g *defaultRpcGenerator) getInterfaceFuncs(service *parser.RpcService) ([]s
if len(method.Document) > 0 {
comment = method.Document[0]
}
buffer, err := util.With("interfaceFn").Parse(sharedInterfaceFunctionTemplate).Execute(map[string]interface{}{
"hasComment": len(method.Document) > 0,
"comment": comment,
"method": method.Name.Title(),
"pbRequest": method.InType,
"pbResponse": method.OutType,
"hasResponse": found,
})
buffer, err := util.With("interfaceFn").Parse(callInterfaceFunctionTemplate).Execute(
map[string]interface{}{
"hasComment": len(method.Document) > 0,
"comment": comment,
"method": method.Name.Title(),
"pbRequest": method.InType,
"pbResponse": method.OutType,
"hasResponse": found,
})
if err != nil {
return nil, err
}
functions = append(functions, buffer.String())
}
return functions, nil
}

View File

@@ -23,11 +23,10 @@ func (g *defaultRpcGenerator) createDir() error {
m[dirEtc] = filepath.Join(ctx.TargetDir, dirEtc)
m[dirInternal] = filepath.Join(ctx.TargetDir, dirInternal)
m[dirConfig] = filepath.Join(ctx.TargetDir, dirInternal, dirConfig)
m[dirHandler] = filepath.Join(ctx.TargetDir, dirInternal, dirHandler)
m[dirServer] = filepath.Join(ctx.TargetDir, dirInternal, dirServer)
m[dirLogic] = filepath.Join(ctx.TargetDir, dirInternal, dirLogic)
m[dirPb] = filepath.Join(ctx.TargetDir, dirPb)
m[dirSvc] = filepath.Join(ctx.TargetDir, dirInternal, dirSvc)
m[dirShared] = g.Ctx.SharedDir
for _, d := range m {
err := util.MkdirIfNotExist(d)
if err != nil {

View File

@@ -13,7 +13,7 @@ Log:
ListenOn: 127.0.0.1:8080
Etcd:
Hosts:
- 127.0.0.1:6379
- 127.0.0.1:2379
Key: {{.serviceName}}.rpc
`

View File

@@ -36,11 +36,9 @@ func New{{.logicName}}(ctx context.Context,svcCtx *svc.ServiceContext) *{{.logic
`
logicFunctionTemplate = `{{if .hasComment}}{{.comment}}{{end}}
func (l *{{.logicName}}) {{.method}} (in *{{.package}}.{{.request}}) (*{{.package}}.{{.response}}, error) {
var resp {{.package}}.{{.response}}
// todo: add your logic here and delete this line
return &resp,nil
return &{{.package}}.{{.response}}{}, nil
}
`
)

View File

@@ -56,7 +56,7 @@ func (g *defaultRpcGenerator) genMain() error {
imports := make([]string, 0)
pbImport := fmt.Sprintf(`%v "%v"`, pkg, g.mustGetPackage(dirPb))
svcImport := fmt.Sprintf(`"%v"`, g.mustGetPackage(dirSvc))
remoteImport := fmt.Sprintf(`"%v"`, g.mustGetPackage(dirHandler))
remoteImport := fmt.Sprintf(`"%v"`, g.mustGetPackage(dirServer))
configImport := fmt.Sprintf(`"%v"`, g.mustGetPackage(dirConfig))
imports = append(imports, configImport, pbImport, remoteImport, svcImport)
srv, registers := g.genServer(pkg, file.Service)
@@ -76,7 +76,7 @@ func (g *defaultRpcGenerator) genServer(pkg string, list []*parser.RpcService) (
list2 := make([]string, 0)
for _, item := range list {
name := item.Name.UnTitle()
list1 = append(list1, fmt.Sprintf("%sSrv := handler.New%sServer(ctx)", name, item.Name.Title()))
list1 = append(list1, fmt.Sprintf("%sSrv := server.New%sServer(ctx)", name, item.Name.Title()))
list2 = append(list2, fmt.Sprintf("%s.Register%sServer(grpcServer, %sSrv)", pkg, item.Name.Title(), name))
}
return strings.Join(list1, "\n"), strings.Join(list2, "\n")

View File

@@ -10,9 +10,9 @@ import (
)
const (
handlerTemplate = `{{.head}}
serverTemplate = `{{.head}}
package handler
package server
import (
"context"
@@ -43,7 +43,7 @@ func (s *{{.server}}Server) {{.method}} (ctx context.Context, in *{{.package}}.{
)
func (g *defaultRpcGenerator) genHandler() error {
handlerPath := g.dirM[dirHandler]
serverPath := g.dirM[dirServer]
file := g.ast
pkg := file.Package
pbImport := fmt.Sprintf(`%v "%v"`, pkg, g.mustGetPackage(dirPb))
@@ -56,19 +56,19 @@ func (g *defaultRpcGenerator) genHandler() error {
}
head := util.GetHead(g.Ctx.ProtoSource)
for _, service := range file.Service {
filename := fmt.Sprintf("%vhandler.go", service.Name.Lower())
handlerFile := filepath.Join(handlerPath, filename)
filename := fmt.Sprintf("%vserver.go", service.Name.Lower())
serverFile := filepath.Join(serverPath, filename)
funcList, err := g.genFunctions(service)
if err != nil {
return err
}
err = util.With("server").GoFmt(true).Parse(handlerTemplate).SaveTo(map[string]interface{}{
err = util.With("server").GoFmt(true).Parse(serverTemplate).SaveTo(map[string]interface{}{
"head": head,
"types": fmt.Sprintf(typeFmt, service.Name.Title()),
"server": service.Name.Title(),
"imports": strings.Join(imports, "\n\t"),
"funcs": strings.Join(funcList, "\n"),
}, handlerFile, true)
}, serverFile, true)
if err != nil {
return err
}