Skip to content

Commit

Permalink
Merge 2a27d78 into ab37d29
Browse files Browse the repository at this point in the history
  • Loading branch information
FGYFFFF authored Apr 10, 2023
2 parents ab37d29 + 2a27d78 commit 29207a8
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 54 deletions.
1 change: 1 addition & 0 deletions cmd/hz/config/argument.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type Argument struct {
NoRecurse bool
HandlerByMethod bool
ForceNew bool
SnakeStyleMiddleware bool

CustomizeLayout string
CustomizeLayoutData string
Expand Down
33 changes: 18 additions & 15 deletions cmd/hz/generator/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,25 @@ type Service struct {
BaseDomain string // base domain for client code
}

// HttpPackageGenerator is used to record the configuration related to generating hertz http code.
type HttpPackageGenerator struct {
ConfigPath string
Backend meta.Backend
Options []Option
CmdType string
ProjPackage string
HandlerDir string
RouterDir string
ModelDir string
UseDir string
ClientDir string
IdlClientDir string
ForceClientDir string
NeedModel bool
HandlerByMethod bool
BaseDomain string
ConfigPath string // package template path
Backend meta.Backend // model template
Options []Option
CmdType string
ProjPackage string // go module for project
HandlerDir string
RouterDir string
ModelDir string
UseDir string // model dir for third repo
ClientDir string // client dir for "new"/"update" command
IdlClientDir string // client dir for "client" command
ForceClientDir string // client dir without namespace for "client" command
BaseDomain string // request domain for "client" command

NeedModel bool
HandlerByMethod bool // generate handler files with method dimension
SnakeStyleMiddleware bool // use snake name style for middleware

loadedBackend Backend
curModel *model.Model
Expand Down
14 changes: 11 additions & 3 deletions cmd/hz/generator/package_tpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ import (
{{define "G"}}
{{- if ne .Handler ""}}
{{- .GroupName}}.{{.HttpMethod}}("{{.Path}}", append({{.MiddleWare}}Mw(), {{.Handler}})...)
{{- .GroupName}}.{{.HttpMethod}}("{{.Path}}", append({{.HandlerMiddleware}}Mw(), {{.Handler}})...)
{{- end}}
{{- if ne (len .Children) 0}}
{{.MiddleWare}} := {{template "g" .}}.Group("{{.Path}}", {{.MiddleWare}}Mw()...)
{{.MiddleWare}} := {{template "g" .}}.Group("{{.Path}}", {{.GroupMiddleware}}Mw()...)
{{- end}}
{{- range $_, $router := .Children}}
{{- if ne .Handler ""}}
Expand Down Expand Up @@ -177,10 +177,18 @@ import (
)
{{define "M"}}
func {{.MiddleWare}}Mw() []app.HandlerFunc {
{{- if ne .Children.Len 0}}
func {{.GroupMiddleware}}Mw() []app.HandlerFunc {
// your code...
return nil
}
{{end}}
{{- if ne .Handler ""}}
func {{.HandlerMiddleware}}Mw() []app.HandlerFunc {
// your code...
return nil
}
{{end}}
{{range $_, $router := $.Children}}{{template "M" $router}}{{end}}
{{- end}}
Expand Down
107 changes: 86 additions & 21 deletions cmd/hz/generator/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ type Router struct {
}

type RouterNode struct {
GroupName string
MiddleWare string
GroupName string // current group name(the parent middleware name), used to register route. example: {{.GroupName}}.{{HttpMethod}}
MiddleWare string // current node middleware, used to be group name for children.
HandlerMiddleware string
GroupMiddleware string
PathPrefix string

Path string
Parent *RouterNode
Children childrenRouterInfo

Handler string // {{HandlerPackage}}.{{HandlerName}}
Expand All @@ -57,9 +61,11 @@ type RegisterInfo struct {
// NewRouterTree contains "/" as root node
func NewRouterTree() *RouterNode {
return &RouterNode{
GroupName: "root",
MiddleWare: "root",
Path: "/",
GroupName: "root",
MiddleWare: "root",
GroupMiddleware: "root",
Path: "/",
Parent: nil,
}
}

Expand All @@ -85,8 +91,15 @@ func (routerNode *RouterNode) Update(method *HttpMethod, handlerType, handlerPkg
return nil
}

// DyeGroupName traverses the routing tree in depth and names the middleware for each node.
func (routerNode *RouterNode) DyeGroupName() error {
func (routerNode *RouterNode) RawHandlerName() string {
parts := strings.Split(routerNode.Handler, ".")
handlerName := parts[len(parts)-1]
return handlerName
}

// DyeGroupName traverses the routing tree in depth and names the handler/group middleware for each node.
// If snakeStyleMiddleware is set to true, the name style of the middleware will use snake name style.
func (routerNode *RouterNode) DyeGroupName(snakeStyleMiddleware bool) error {
groups := []string{"root"}

hook := func(layer int, node *RouterNode) error {
Expand All @@ -96,18 +109,56 @@ func (routerNode *RouterNode) DyeGroupName() error {
if len(pname) > 1 && pname[0] == '/' {
pname = pname[1:]
}
if len(node.Children) == 0 && node.Handler != "" {
handleName := strings.Split(node.Handler, ".")
pname = handleName[len(handleName)-1]

if node.Parent != nil {
node.PathPrefix = node.Parent.PathPrefix + "_" + util.ToGoFuncName(pname)
} else {
node.PathPrefix = "_" + util.ToGoFuncName(pname)
}
pname = util.ToVarName([]string{pname})
// The tolow operation is placed here, unifying the middleware raw name
pname = strings.ToLower(pname)
pname, err := util.GetMiddlewareUniqueName(pname)
if err != nil {
return fmt.Errorf("get unique name for middleware '%s' failed, err: %v", pname, err)

handlerMiddlewareName := ""
isLeafNode := false
if len(node.Handler) != 0 {
handlerMiddlewareName = node.RawHandlerName()
// If it is a leaf node, then "group middleware name" and "handler middleware name" are the same
if len(node.Children) == 0 {
pname = handlerMiddlewareName
isLeafNode = true
}
}

pname = convertToMiddlewareName(pname)
handlerMiddlewareName = convertToMiddlewareName(handlerMiddlewareName)

if isLeafNode {
name, err := util.GetMiddlewareUniqueName(pname)
if err != nil {
return fmt.Errorf("get unique name for middleware '%s' failed, err: %v", name, err)
}
pname = name
handlerMiddlewareName = name
} else {
var err error
pname, err = util.GetMiddlewareUniqueName(pname)
if err != nil {
return fmt.Errorf("get unique name for middleware '%s' failed, err: %v", pname, err)
}
handlerMiddlewareName, err = util.GetMiddlewareUniqueName(handlerMiddlewareName)
if err != nil {
return fmt.Errorf("get unique name for middleware '%s' failed, err: %v", handlerMiddlewareName, err)
}
}
node.MiddleWare = "_" + pname
if len(node.Handler) != 0 {
node.HandlerMiddleware = "_" + handlerMiddlewareName
if snakeStyleMiddleware {
node.HandlerMiddleware = "_" + node.RawHandlerName()
}
}
node.GroupMiddleware = node.MiddleWare
if snakeStyleMiddleware {
node.GroupMiddleware = node.PathPrefix
}
}
if layer >= len(groups)-1 {
groups = append(groups, node.MiddleWare)
Expand Down Expand Up @@ -145,7 +196,8 @@ func (routerNode *RouterNode) Insert(name string, method *HttpMethod, handlerTyp
cur := routerNode
for i, p := range paths {
c := &RouterNode{
Path: "/" + p,
Path: "/" + p,
Parent: cur,
}
if i == len(paths)-1 {
// generate handler by method
Expand Down Expand Up @@ -285,7 +337,7 @@ func (pkgGen *HttpPackageGenerator) updateRegister(pkg, rDir, pkgName string) er
}

func (pkgGen *HttpPackageGenerator) genRouter(pkg *HttpPackage, root *RouterNode, handlerPackage, routerDir, routerPackage string) error {
err := root.DyeGroupName()
err := root.DyeGroupName(pkgGen.SnakeStyleMiddleware)
if err != nil {
return err
}
Expand Down Expand Up @@ -334,10 +386,16 @@ func (pkgGen *HttpPackageGenerator) updateMiddlewareReg(router interface{}, midd
if !isExist {
return pkgGen.TemplateGenerator.Generate(router, middlewareTpl, filePath, false)
}
middlewareList := make([]string, 1)
var middlewareList []string

_ = router.(Router).Router.DFS(0, func(layer int, node *RouterNode) error {
middlewareList = append(middlewareList, node.MiddleWare)
// non-leaf node will generate group middleware
if node.Children.Len() > 0 && len(node.GroupMiddleware) > 0 {
middlewareList = append(middlewareList, node.GroupMiddleware)
}
if len(node.HandlerMiddleware) > 0 {
middlewareList = append(middlewareList, node.HandlerMiddleware)
}
return nil
})

Expand All @@ -347,7 +405,7 @@ func (pkgGen *HttpPackageGenerator) updateMiddlewareReg(router interface{}, midd
}

for _, mw := range middlewareList {
if bytes.Contains(file, []byte(mw+"Mw")) {
if bytes.Contains(file, []byte(mw)) {
continue
}
middlewareSingleTpl := pkgGen.tpls[middlewareSingleTplName]
Expand Down Expand Up @@ -378,3 +436,10 @@ func (pkgGen *HttpPackageGenerator) updateMiddlewareReg(router interface{}, midd

return nil
}

// convertToMiddlewareName converts a route path to a middleware name
func convertToMiddlewareName(path string) string {
path = util.ToVarName([]string{path})
path = strings.ToLower(path)
return path
}
15 changes: 8 additions & 7 deletions cmd/hz/protobuf/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,13 +600,14 @@ func (plugin *Plugin) genHttpPackage(ast *descriptorpb.FileDescriptorProto, deps
OutputDir: args.OutDir,
Excludes: args.Excludes,
},
ProjPackage: pkg,
Options: options,
HandlerByMethod: args.HandlerByMethod,
CmdType: args.CmdType,
IdlClientDir: plugin.IdlClientDir,
ForceClientDir: args.ForceClientDir,
BaseDomain: args.BaseDomain,
ProjPackage: pkg,
Options: options,
HandlerByMethod: args.HandlerByMethod,
CmdType: args.CmdType,
IdlClientDir: plugin.IdlClientDir,
ForceClientDir: args.ForceClientDir,
BaseDomain: args.BaseDomain,
SnakeStyleMiddleware: args.SnakeStyleMiddleware,
}

if args.ModelBackend != "" {
Expand Down
15 changes: 8 additions & 7 deletions cmd/hz/thrift/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,14 @@ func (plugin *Plugin) Run() int {
OutputDir: args.OutDir,
Excludes: args.Excludes,
},
ProjPackage: pkg,
Options: options,
HandlerByMethod: args.HandlerByMethod,
CmdType: args.CmdType,
IdlClientDir: util.SubDir(modelDir, pkgInfo.Package),
ForceClientDir: args.ForceClientDir,
BaseDomain: args.BaseDomain,
ProjPackage: pkg,
Options: options,
HandlerByMethod: args.HandlerByMethod,
CmdType: args.CmdType,
IdlClientDir: util.SubDir(modelDir, pkgInfo.Package),
ForceClientDir: args.ForceClientDir,
BaseDomain: args.BaseDomain,
SnakeStyleMiddleware: args.SnakeStyleMiddleware,
}
if args.ModelBackend != "" {
sg.Backend = meta.Backend(args.ModelBackend)
Expand Down
16 changes: 15 additions & 1 deletion cmd/hz/util/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"net/url"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -307,7 +308,7 @@ func ToVarName(paths []string) string {
if c == ':' || c == '*' {
continue
}
if (c >= '0' && c <= '9' && i != 0) || (c >= 'a' && c <= 'z') || (c > 'A' && c <= 'Z') || (c == '_') {
if (c >= '0' && c <= '9' && i != 0) || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') {
out = append(out, c)
} else {
out = append(out, '_')
Expand Down Expand Up @@ -420,3 +421,16 @@ func SubPackageDir(path string) string {
}
return path[:index]
}

var validFuncReg = regexp.MustCompile("[_0-9a-zA-Z]")

// ToGoFuncName converts a string to a function naming style for go
func ToGoFuncName(s string) string {
ss := []byte(s)
for i := range ss {
if !validFuncReg.Match([]byte{s[i]}) {
ss[i] = '_'
}
}
return string(ss)
}

0 comments on commit 29207a8

Please sign in to comment.