forked from cloudwego/hertz
Merge pull request #311 from FGYFFFF/feat/handler_by_method
feat(hz): generate a separate handler file for each method
This commit is contained in:
commit
d6b85fec12
|
@ -123,6 +123,7 @@ func Init() *cli.App {
|
|||
snakeNameFlag := cli.BoolFlag{Name: "snake_tag", Usage: "Use snake_case style naming for tags. (Only works for 'form', 'query', 'json')", Destination: &globalArgs.SnakeName}
|
||||
customLayout := cli.StringFlag{Name: "customize_layout", Usage: "Specify the layout template. ({{Template Profile}}:{{Rendering Data}})", Destination: &globalArgs.CustomizeLayout}
|
||||
customPackage := cli.StringFlag{Name: "customize_package", Usage: "Specify the package template. ({{Template Profile}}:)", Destination: &globalArgs.CustomizePackage}
|
||||
handlerByMethod := cli.BoolFlag{Name: "handler_by_method", Usage: "Generate a separate handler file for each method.", Destination: &globalArgs.HandlerByMethod}
|
||||
|
||||
// app
|
||||
app := cli.NewApp()
|
||||
|
@ -164,6 +165,7 @@ func Init() *cli.App {
|
|||
&excludeFilesFlag,
|
||||
&customLayout,
|
||||
&customPackage,
|
||||
&handlerByMethod,
|
||||
&protoPluginsFlag,
|
||||
&thriftPluginsFlag,
|
||||
},
|
||||
|
@ -191,6 +193,7 @@ func Init() *cli.App {
|
|||
&snakeNameFlag,
|
||||
&excludeFilesFlag,
|
||||
&customPackage,
|
||||
&handlerByMethod,
|
||||
&protoPluginsFlag,
|
||||
&thriftPluginsFlag,
|
||||
},
|
||||
|
|
|
@ -61,6 +61,7 @@ type Argument struct {
|
|||
SnakeName bool
|
||||
Excludes []string
|
||||
NoRecurse bool
|
||||
HandlerByMethod bool
|
||||
|
||||
CustomizeLayout string
|
||||
CustomizePackage string
|
||||
|
|
|
@ -36,6 +36,7 @@ type HttpMethod struct {
|
|||
ReturnTypeName string
|
||||
Path string
|
||||
Serializer string
|
||||
OutputDir string
|
||||
// Annotations map[string]string
|
||||
Models map[string]*model.Model
|
||||
}
|
||||
|
@ -54,29 +55,37 @@ type Client struct {
|
|||
|
||||
func (pkgGen *HttpPackageGenerator) genHandler(pkg *HttpPackage, handlerDir, handlerPackage string, root *RouterNode) error {
|
||||
for _, s := range pkg.Services {
|
||||
handler := Handler{
|
||||
FilePath: filepath.Join(handlerDir, util.ToSnakeCase(s.Name)+".go"),
|
||||
PackageName: util.SplitPackage(handlerPackage, ""),
|
||||
Methods: s.Methods,
|
||||
}
|
||||
|
||||
handler.Imports = make(map[string]*model.Model, len(s.Methods))
|
||||
for _, m := range s.Methods {
|
||||
for key, mm := range m.Models {
|
||||
if v, ok := handler.Imports[mm.PackageName]; ok && v.Package != mm.Package {
|
||||
handler.Imports[key] = mm
|
||||
continue
|
||||
var handler Handler
|
||||
if pkgGen.HandlerByMethod { // generate handler by method
|
||||
for _, m := range s.Methods {
|
||||
handler = Handler{
|
||||
FilePath: filepath.Join(handlerDir, m.OutputDir, util.ToSnakeCase(m.Name)+".go"),
|
||||
PackageName: util.SplitPackage(handlerPackage, ""),
|
||||
Methods: []*HttpMethod{m},
|
||||
}
|
||||
|
||||
if err := pkgGen.processHandler(&handler, root, handlerDir, m.OutputDir, true); err != nil {
|
||||
return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
|
||||
}
|
||||
|
||||
if err := pkgGen.updateHandler(handler, handlerTplName, handler.FilePath, false); err != nil {
|
||||
return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
|
||||
}
|
||||
handler.Imports[mm.PackageName] = mm
|
||||
}
|
||||
err := root.Update(m, handler.PackageName)
|
||||
if err != nil {
|
||||
return err
|
||||
} else { // generate handler service
|
||||
handler = Handler{
|
||||
FilePath: filepath.Join(handlerDir, util.ToSnakeCase(s.Name)+".go"),
|
||||
PackageName: util.SplitPackage(handlerPackage, ""),
|
||||
Methods: s.Methods,
|
||||
}
|
||||
|
||||
if err := pkgGen.processHandler(&handler, root, "", "", false); err != nil {
|
||||
return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
|
||||
}
|
||||
|
||||
if err := pkgGen.updateHandler(handler, handlerTplName, handler.FilePath, false); err != nil {
|
||||
return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
|
||||
}
|
||||
}
|
||||
handler.Format()
|
||||
if err := pkgGen.updateHandler(handler, handlerTplName, handler.FilePath, false); err != nil {
|
||||
return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
|
||||
}
|
||||
|
||||
if len(pkgGen.ClientDir) != 0 {
|
||||
|
@ -96,6 +105,31 @@ func (pkgGen *HttpPackageGenerator) genHandler(pkg *HttpPackage, handlerDir, han
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pkgGen *HttpPackageGenerator) processHandler(handler *Handler, root *RouterNode, handlerDir, projectOutDir string, handlerByMethod bool) error {
|
||||
singleHandlerPackage := ""
|
||||
if handlerByMethod {
|
||||
singleHandlerPackage = util.SubPackage(pkgGen.ProjPackage, filepath.Join(handlerDir, projectOutDir))
|
||||
}
|
||||
handler.Imports = make(map[string]*model.Model, len(handler.Methods))
|
||||
for _, m := range handler.Methods {
|
||||
// Iterate over the request and return parameters of the method to get import path.
|
||||
for key, mm := range m.Models {
|
||||
if v, ok := handler.Imports[mm.PackageName]; ok && v.Package != mm.Package {
|
||||
handler.Imports[key] = mm
|
||||
continue
|
||||
}
|
||||
handler.Imports[mm.PackageName] = mm
|
||||
}
|
||||
err := root.Update(m, handler.PackageName, singleHandlerPackage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
handler.Format()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pkgGen *HttpPackageGenerator) updateHandler(handler interface{}, handlerTpl, filePath string, noRepeat bool) error {
|
||||
isExist, err := util.PathExist(filePath)
|
||||
if err != nil {
|
||||
|
|
|
@ -44,15 +44,16 @@ type Service struct {
|
|||
}
|
||||
|
||||
type HttpPackageGenerator struct {
|
||||
ConfigPath string
|
||||
Backend meta.Backend
|
||||
Options []Option
|
||||
ProjPackage string
|
||||
HandlerDir string
|
||||
RouterDir string
|
||||
ModelDir string
|
||||
ClientDir string
|
||||
NeedModel bool
|
||||
ConfigPath string
|
||||
Backend meta.Backend
|
||||
Options []Option
|
||||
ProjPackage string
|
||||
HandlerDir string
|
||||
RouterDir string
|
||||
ModelDir string
|
||||
ClientDir string
|
||||
NeedModel bool
|
||||
HandlerByMethod bool
|
||||
|
||||
loadedBackend Backend
|
||||
curModel *model.Model
|
||||
|
@ -135,7 +136,11 @@ func (pkgGen *HttpPackageGenerator) Generate(pkg *HttpPackage) error {
|
|||
}
|
||||
}
|
||||
|
||||
// this is for handler_by_service, the handler_dir is {$HANDLER_DIR}/{$PKG}
|
||||
handlerDir := util.SubDir(pkgGen.HandlerDir, pkg.Package)
|
||||
if pkgGen.HandlerByMethod {
|
||||
handlerDir = pkgGen.HandlerDir
|
||||
}
|
||||
handlerPackage := util.SubPackage(pkgGen.ProjPackage, handlerDir)
|
||||
routerDir := util.SubDir(pkgGen.RouterDir, pkg.Package)
|
||||
routerPackage := util.SubPackage(pkgGen.ProjPackage, routerDir)
|
||||
|
|
|
@ -97,7 +97,9 @@ package {{$.PackageName}}
|
|||
import (
|
||||
"github.com/cloudwego/hertz/pkg/app/server"
|
||||
|
||||
{{range $k, $v := .HandlerPackages}}{{$k}} "{{$v}}"{{end}}
|
||||
{{- range $k, $v := .HandlerPackages}}
|
||||
{{$k}} "{{$v}}"
|
||||
{{- end}}
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
|
@ -42,8 +42,10 @@ type RouterNode struct {
|
|||
Path string
|
||||
Children childrenRouterInfo
|
||||
|
||||
Handler string // {{HandlerPackage}}.{{HandlerName}}
|
||||
HttpMethod string
|
||||
Handler string // {{HandlerPackage}}.{{HandlerName}}
|
||||
HandlerPackage string
|
||||
HandlerPackageAlias string
|
||||
HttpMethod string
|
||||
}
|
||||
|
||||
type RegisterDependency struct {
|
||||
|
@ -64,7 +66,7 @@ func (routerNode *RouterNode) Sort() {
|
|||
sort.Sort(routerNode.Children)
|
||||
}
|
||||
|
||||
func (routerNode *RouterNode) Update(method *HttpMethod, handlerType string) error {
|
||||
func (routerNode *RouterNode) Update(method *HttpMethod, handlerType, handlerPkg string) error {
|
||||
if method.Path == "" {
|
||||
return fmt.Errorf("empty path for method '%s'", method.Name)
|
||||
}
|
||||
|
@ -77,7 +79,7 @@ func (routerNode *RouterNode) Update(method *HttpMethod, handlerType string) err
|
|||
return fmt.Errorf("path '%s' has been registered", method.Path)
|
||||
}
|
||||
name := util.ToVarName(paths[:last])
|
||||
parent.Insert(name, method, handlerType, paths[last:])
|
||||
parent.Insert(name, method, handlerType, paths[last:], handlerPkg)
|
||||
parent.Sort()
|
||||
return nil
|
||||
}
|
||||
|
@ -136,14 +138,36 @@ func (routerNode *RouterNode) DFS(i int, hook func(layer int, node *RouterNode)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (routerNode *RouterNode) Insert(name string, method *HttpMethod, handlerType string, paths []string) {
|
||||
var handlerPkgMap map[string]string
|
||||
|
||||
func (routerNode *RouterNode) Insert(name string, method *HttpMethod, handlerType string, paths []string, handlerPkg string) {
|
||||
cur := routerNode
|
||||
for i, p := range paths {
|
||||
c := &RouterNode{
|
||||
Path: "/" + p,
|
||||
}
|
||||
if i == len(paths)-1 {
|
||||
c.Handler = handlerType + "." + method.Name
|
||||
// generate handler by method
|
||||
if len(handlerPkg) != 0 {
|
||||
// get a unique package alias for every handler
|
||||
pkgAlias := filepath.Base(handlerPkg)
|
||||
pkgAlias = util.ToVarName([]string{pkgAlias})
|
||||
val, exist := handlerPkgMap[handlerPkg]
|
||||
if !exist {
|
||||
pkgAlias, _ = util.GetHandlerPackageUniqueName(pkgAlias)
|
||||
if len(handlerPkgMap) == 0 {
|
||||
handlerPkgMap = make(map[string]string, 10)
|
||||
}
|
||||
handlerPkgMap[handlerPkg] = pkgAlias
|
||||
} else {
|
||||
pkgAlias = val
|
||||
}
|
||||
c.HandlerPackageAlias = pkgAlias
|
||||
c.Handler = pkgAlias + "." + method.Name
|
||||
c.HandlerPackage = handlerPkg
|
||||
} else { // generate handler by service
|
||||
c.Handler = handlerType + "." + method.Name
|
||||
}
|
||||
c.HttpMethod = getHttpMethod(method.HTTPMethod)
|
||||
}
|
||||
if cur.Children == nil {
|
||||
|
@ -272,6 +296,19 @@ func (pkgGen *HttpPackageGenerator) genRouter(pkg *HttpPackage, root *RouterNode
|
|||
},
|
||||
Router: root,
|
||||
}
|
||||
|
||||
if pkgGen.HandlerByMethod {
|
||||
handlerMap := make(map[string]string, 1)
|
||||
hook := func(layer int, node *RouterNode) error {
|
||||
if len(node.HandlerPackage) != 0 {
|
||||
handlerMap[node.HandlerPackageAlias] = node.HandlerPackage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
root.DFS(0, hook)
|
||||
router.HandlerPackages = handlerMap
|
||||
}
|
||||
|
||||
if err := pkgGen.TemplateGenerator.Generate(router, routerTplName, router.FilePath, false); err != nil {
|
||||
return fmt.Errorf("generate router %s failed, err: %v", router.FilePath, err.Error())
|
||||
}
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
// Copyright 2022 CloudWeGo Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.0
|
||||
|
@ -243,6 +229,14 @@ var file_api_proto_extTypes = []protoimpl.ExtensionInfo{
|
|||
Tag: "bytes,50308,opt,name=baseurl",
|
||||
Filename: "api.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MethodOptions)(nil),
|
||||
ExtensionType: (*string)(nil),
|
||||
Field: 50309,
|
||||
Name: "api.handler_path",
|
||||
Tag: "bytes,50309,opt,name=handler_path",
|
||||
Filename: "api.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*int32)(nil),
|
||||
|
@ -311,12 +305,14 @@ var (
|
|||
E_Param = &file_api_proto_extTypes[24] // Whether client requests take public parameters
|
||||
// optional string baseurl = 50308;
|
||||
E_Baseurl = &file_api_proto_extTypes[25] // Baseurl used in ttnet routing
|
||||
// optional string handler_path = 50309;
|
||||
E_HandlerPath = &file_api_proto_extTypes[26] // handler_path specifies the path to generate the method
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.EnumValueOptions.
|
||||
var (
|
||||
// optional int32 http_code = 50401;
|
||||
E_HttpCode = &file_api_proto_extTypes[26]
|
||||
E_HttpCode = &file_api_proto_extTypes[27]
|
||||
)
|
||||
|
||||
var File_api_proto protoreflect.FileDescriptor
|
||||
|
@ -416,12 +412,16 @@ var file_api_proto_rawDesc = []byte{
|
|||
0x61, 0x6d, 0x3a, 0x3a, 0x0a, 0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x12, 0x1e, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x84, 0x89,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x3a, 0x40,
|
||||
0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e,
|
||||
0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe1,
|
||||
0x89, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x64, 0x65,
|
||||
0x42, 0x06, 0x5a, 0x04, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x3a, 0x43,
|
||||
0x0a, 0x0c, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x85,
|
||||
0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x50,
|
||||
0x61, 0x74, 0x68, 0x3a, 0x40, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x18, 0xe1, 0x89, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, 0x74, 0x74,
|
||||
0x70, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2f, 0x61, 0x70, 0x69,
|
||||
}
|
||||
|
||||
var file_api_proto_goTypes = []interface{}{
|
||||
|
@ -456,11 +456,12 @@ var file_api_proto_depIdxs = []int32{
|
|||
1, // 23: api.serializer:extendee -> google.protobuf.MethodOptions
|
||||
1, // 24: api.param:extendee -> google.protobuf.MethodOptions
|
||||
1, // 25: api.baseurl:extendee -> google.protobuf.MethodOptions
|
||||
2, // 26: api.http_code:extendee -> google.protobuf.EnumValueOptions
|
||||
27, // [27:27] is the sub-list for method output_type
|
||||
27, // [27:27] is the sub-list for method input_type
|
||||
27, // [27:27] is the sub-list for extension type_name
|
||||
0, // [0:27] is the sub-list for extension extendee
|
||||
1, // 26: api.handler_path:extendee -> google.protobuf.MethodOptions
|
||||
2, // 27: api.http_code:extendee -> google.protobuf.EnumValueOptions
|
||||
28, // [28:28] is the sub-list for method output_type
|
||||
28, // [28:28] is the sub-list for method input_type
|
||||
28, // [28:28] is the sub-list for extension type_name
|
||||
0, // [0:28] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
|
@ -476,7 +477,7 @@ func file_api_proto_init() {
|
|||
RawDescriptor: file_api_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 27,
|
||||
NumExtensions: 28,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_api_proto_goTypes,
|
||||
|
|
|
@ -36,6 +36,7 @@ extend google.protobuf.MethodOptions {
|
|||
optional string serializer = 50306; // Serialization method
|
||||
optional string param = 50307; // Whether client requests take public parameters
|
||||
optional string baseurl = 50308; // Baseurl used in ttnet routing
|
||||
optional string handler_path = 50309; // handler_path specifies the path to generate the method
|
||||
}
|
||||
|
||||
extend google.protobuf.EnumValueOptions {
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/cloudwego/hertz/cmd/hz/internal/generator"
|
||||
"github.com/cloudwego/hertz/cmd/hz/internal/generator/model"
|
||||
"github.com/cloudwego/hertz/cmd/hz/internal/protobuf/api"
|
||||
"github.com/cloudwego/hertz/cmd/hz/internal/util"
|
||||
"github.com/cloudwego/hertz/cmd/hz/internal/util/logs"
|
||||
"github.com/jhump/protoreflect/desc"
|
||||
|
@ -121,6 +122,13 @@ func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resolver) ([]
|
|||
}
|
||||
path := vpath.(string)
|
||||
|
||||
var handlerOutDir string
|
||||
genPath := checkFirstOption(api.E_HandlerPath, m.GetOptions())
|
||||
handlerOutDir, ok := genPath.(string)
|
||||
if !ok || len(handlerOutDir) == 0 {
|
||||
handlerOutDir = ""
|
||||
}
|
||||
|
||||
reqName := m.GetInputType()
|
||||
sb, err := resolver.ResolveIdentifier(reqName)
|
||||
reqName = util.BaseName(sb.Scope.GetOptions().GetGoPackage(), "") + "." + sb.Name
|
||||
|
@ -145,6 +153,7 @@ func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resolver) ([]
|
|||
HTTPMethod: hmethod,
|
||||
Path: path,
|
||||
Serializer: serializer,
|
||||
OutputDir: handlerOutDir,
|
||||
}
|
||||
|
||||
goOptMapAlias := make(map[string]string, 1)
|
||||
|
|
|
@ -582,8 +582,9 @@ func (plugin *Plugin) genHttpPackage(ast *descriptorpb.FileDescriptorProto, deps
|
|||
TemplateGenerator: generator.TemplateGenerator{
|
||||
OutputDir: args.OutDir,
|
||||
},
|
||||
ProjPackage: pkg,
|
||||
Options: options,
|
||||
ProjPackage: pkg,
|
||||
Options: options,
|
||||
HandlerByMethod: args.HandlerByMethod,
|
||||
}
|
||||
|
||||
if args.ModelBackend != "" {
|
||||
|
|
|
@ -70,6 +70,17 @@ func astToService(ast *parser.Thrift, resolver *Resolver) ([]*generator.Service,
|
|||
if len(rs) > 1 {
|
||||
return nil, fmt.Errorf("too many 'api.XXX' annotations: %s", rs)
|
||||
}
|
||||
|
||||
var handlerOutDir string
|
||||
genPaths := getAnnotation(m.Annotations, ApiGenPath)
|
||||
if len(genPaths) == 0 {
|
||||
handlerOutDir = ""
|
||||
} else if len(genPaths) > 1 {
|
||||
return nil, fmt.Errorf("too many 'api.handler_path' for %s", m.Name)
|
||||
} else {
|
||||
handlerOutDir = genPaths[0]
|
||||
}
|
||||
|
||||
hmethod, path := util.GetFirstKV(rs)
|
||||
if len(path) != 1 || path[0] == "" {
|
||||
return nil, fmt.Errorf("invalid api.%s for %s.%s: %s", hmethod, s.Name, m.Name, path)
|
||||
|
@ -103,6 +114,7 @@ func astToService(ast *parser.Thrift, resolver *Resolver) ([]*generator.Service,
|
|||
ReturnTypeName: respName,
|
||||
Path: path[0],
|
||||
Serializer: sr,
|
||||
OutputDir: handlerOutDir,
|
||||
// Annotations: m.Annotations,
|
||||
}
|
||||
refs := resolver.ExportReferred(false, true)
|
||||
|
|
|
@ -90,6 +90,10 @@ func (plugin *Plugin) Run() int {
|
|||
options := CheckTagOption(plugin.args)
|
||||
|
||||
pkgInfo, err := plugin.getPackageInfo()
|
||||
if err != nil {
|
||||
logs.Errorf("get http package info failed: %s", err.Error())
|
||||
return meta.PluginError
|
||||
}
|
||||
|
||||
cf, _ := util.GetColonPair(args.CustomizePackage)
|
||||
pkg, err := args.GetGoPackage()
|
||||
|
@ -126,8 +130,9 @@ func (plugin *Plugin) Run() int {
|
|||
TemplateGenerator: generator.TemplateGenerator{
|
||||
OutputDir: args.OutDir,
|
||||
},
|
||||
ProjPackage: pkg,
|
||||
Options: options,
|
||||
ProjPackage: pkg,
|
||||
Options: options,
|
||||
HandlerByMethod: args.HandlerByMethod,
|
||||
}
|
||||
if args.ModelBackend != "" {
|
||||
sg.Backend = meta.Backend(args.ModelBackend)
|
||||
|
|
|
@ -56,6 +56,7 @@ const (
|
|||
ApiAny = "api.any"
|
||||
ApiPath = "api.path"
|
||||
ApiSerializer = "api.serializer"
|
||||
ApiGenPath = "api.handler_path"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -70,6 +71,10 @@ var (
|
|||
ApiAny: "ANY",
|
||||
}
|
||||
|
||||
HttpMethodOptionAnnotations = map[string]string{
|
||||
ApiGenPath: "handler_path",
|
||||
}
|
||||
|
||||
BindingTags = map[string]string{
|
||||
AnnotationPath: "path",
|
||||
AnnotationQuery: "query",
|
||||
|
|
|
@ -366,8 +366,9 @@ func SubDir(root, subPkg string) string {
|
|||
}
|
||||
|
||||
var (
|
||||
uniquePackageName = map[string]bool{}
|
||||
uniqueMiddlewareName = map[string]bool{}
|
||||
uniquePackageName = map[string]bool{}
|
||||
uniqueMiddlewareName = map[string]bool{}
|
||||
uniqueHandlerPackageName = map[string]bool{}
|
||||
)
|
||||
|
||||
// GetPackageUniqueName can get a non-repeating variable name for package alias
|
||||
|
@ -390,6 +391,15 @@ func GetMiddlewareUniqueName(name string) (string, error) {
|
|||
return name, nil
|
||||
}
|
||||
|
||||
func GetHandlerPackageUniqueName(name string) (string, error) {
|
||||
name, err := getUniqueName(name, uniqueHandlerPackageName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("can not generate unique handler package name: '%s', err: %v", name, err)
|
||||
}
|
||||
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// getUniqueName can get a non-repeating variable name
|
||||
func getUniqueName(name string, uniqueNameSet map[string]bool) (string, error) {
|
||||
uniqueName := name
|
||||
|
|
Loading…
Reference in New Issue