diff --git a/go.mod b/go.mod index 00f0b38adfa8..2d2f69df3c7d 100644 --- a/go.mod +++ b/go.mod @@ -81,6 +81,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -95,6 +97,7 @@ require ( github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect diff --git a/go.sum b/go.sum index 9fe6bfbe1a48..953a195f93f8 100644 --- a/go.sum +++ b/go.sum @@ -140,6 +140,7 @@ github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7s github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -158,6 +159,7 @@ github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4Vi github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= diff --git a/tools/goctl/Makefile b/tools/goctl/Makefile index f7b92d3d4b76..33f5cc80a716 100644 --- a/tools/goctl/Makefile +++ b/tools/goctl/Makefile @@ -23,3 +23,17 @@ image: docker tag kevinwan/goctl:$(version)-arm64 kevinwan/goctl:latest-arm64 docker push kevinwan/goctl:$(version)-arm64 docker push kevinwan/goctl:latest-arm64 + + +#echo $(shell find $(target_dir) -name "*.proto") +#protoc -I example/app/pb --go_out=example/app/pb --go-grpc_out=example/app/pb +.PHONY: generate-proto +generate-proto: + $(eval target_dir := $(filter-out $@,$(MAKECMDGOALS))) + @if [ -z "$(target_dir)" ]; then \ + echo "Usage: make generate-proto "; \ + exit 1; \ + fi + protoc -I $(target_dir) --go_out=$(target_dir) --go-grpc_out=$(target_dir) $(target_dir)/*.proto + + diff --git a/tools/goctl/example/rpc/hello.proto b/tools/goctl/example/rpc/hello.proto deleted file mode 100644 index 0ea428d0e863..000000000000 --- a/tools/goctl/example/rpc/hello.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -package hello; - -option go_package = "./hello"; - -message HelloReq { - string in = 1; -} - -message HelloResp { - string msg = 1; -} - -service Greet { - rpc SayHello(HelloReq) returns (HelloResp); -} \ No newline at end of file diff --git a/tools/goctl/example/rpc/hello/client/greet/greet.go b/tools/goctl/example/rpc/hello/client/greet/greet.go deleted file mode 100644 index 99af623be875..000000000000 --- a/tools/goctl/example/rpc/hello/client/greet/greet.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hello.proto - -package client - -import ( - "context" - - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" -) - -type ( - HelloReq = hello.HelloReq - HelloResp = hello.HelloResp - - Greet interface { - SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) - } - - defaultGreet struct { - cli zrpc.Client - } -) - -func NewGreet(cli zrpc.Client) Greet { - return &defaultGreet{ - cli: cli, - } -} - -func (m *defaultGreet) SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) { - client := hello.NewGreetClient(m.cli.Conn()) - return client.SayHello(ctx, in, opts...) -} diff --git a/tools/goctl/example/rpc/hello/etc/hello.yaml b/tools/goctl/example/rpc/hello/etc/hello.yaml deleted file mode 100644 index 91d30bb5c487..000000000000 --- a/tools/goctl/example/rpc/hello/etc/hello.yaml +++ /dev/null @@ -1,6 +0,0 @@ -Name: hello.rpc -ListenOn: 127.0.0.1:8080 -Etcd: - Hosts: - - 127.0.0.1:2379 - Key: hello.rpc diff --git a/tools/goctl/example/rpc/hello/hello.go b/tools/goctl/example/rpc/hello/hello.go deleted file mode 100644 index df7705aff0a6..000000000000 --- a/tools/goctl/example/rpc/hello/hello.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "flag" - "fmt" - - "github.com/zeromicro/go-zero/core/conf" - "github.com/zeromicro/go-zero/core/service" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/config" - greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/server/greet" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -var configFile = flag.String("f", "etc/hello.yaml", "the config file") - -func main() { - flag.Parse() - - var c config.Config - conf.MustLoad(*configFile, &c) - ctx := svc.NewServiceContext(c) - - s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { - hello.RegisterGreetServer(grpcServer, greetServer.NewGreetServer(ctx)) - - if c.Mode == service.DevMode || c.Mode == service.TestMode { - reflection.Register(grpcServer) - } - }) - defer s.Stop() - - fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) - s.Start() -} diff --git a/tools/goctl/example/rpc/hello/internal/config/config.go b/tools/goctl/example/rpc/hello/internal/config/config.go deleted file mode 100755 index c1f85b99ac9f..000000000000 --- a/tools/goctl/example/rpc/hello/internal/config/config.go +++ /dev/null @@ -1,7 +0,0 @@ -package config - -import "github.com/zeromicro/go-zero/zrpc" - -type Config struct { - zrpc.RpcServerConf -} diff --git a/tools/goctl/example/rpc/hello/internal/logic/greet/sayhellologic.go b/tools/goctl/example/rpc/hello/internal/logic/greet/sayhellologic.go deleted file mode 100644 index 6bf3cfda88ba..000000000000 --- a/tools/goctl/example/rpc/hello/internal/logic/greet/sayhellologic.go +++ /dev/null @@ -1,29 +0,0 @@ -package greetlogic - -import ( - "context" - - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello" -) - -type SayHelloLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func NewSayHelloLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SayHelloLogic { - return &SayHelloLogic{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} - -func (l *SayHelloLogic) SayHello(in *hello.HelloReq) (*hello.HelloResp, error) { - // todo: add your logic here and delete this line - - return &hello.HelloResp{}, nil -} diff --git a/tools/goctl/example/rpc/hello/internal/server/greet/greetserver.go b/tools/goctl/example/rpc/hello/internal/server/greet/greetserver.go deleted file mode 100644 index e02ba3d0a188..000000000000 --- a/tools/goctl/example/rpc/hello/internal/server/greet/greetserver.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hello.proto - -package server - -import ( - "context" - - greetlogic "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/logic/greet" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello" -) - -type GreetServer struct { - svcCtx *svc.ServiceContext - hello.UnimplementedGreetServer -} - -func NewGreetServer(svcCtx *svc.ServiceContext) *GreetServer { - return &GreetServer{ - svcCtx: svcCtx, - } -} - -func (s *GreetServer) SayHello(ctx context.Context, in *hello.HelloReq) (*hello.HelloResp, error) { - l := greetlogic.NewSayHelloLogic(ctx, s.svcCtx) - return l.SayHello(in) -} diff --git a/tools/goctl/example/rpc/hello/internal/svc/servicecontext.go b/tools/goctl/example/rpc/hello/internal/svc/servicecontext.go deleted file mode 100644 index 961a318deb4d..000000000000 --- a/tools/goctl/example/rpc/hello/internal/svc/servicecontext.go +++ /dev/null @@ -1,13 +0,0 @@ -package svc - -import "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/config" - -type ServiceContext struct { - Config config.Config -} - -func NewServiceContext(c config.Config) *ServiceContext { - return &ServiceContext{ - Config: c, - } -} diff --git a/tools/goctl/example/rpc/hello/pb/hello/hello.pb.go b/tools/goctl/example/rpc/hello/pb/hello/hello.pb.go deleted file mode 100644 index 0181ede2a6d7..000000000000 --- a/tools/goctl/example/rpc/hello/pb/hello/hello.pb.go +++ /dev/null @@ -1,209 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.0 -// protoc v3.19.4 -// source: hello.proto - -package hello - -import ( - reflect "reflect" - sync "sync" - - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type HelloReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - In string `protobuf:"bytes,1,opt,name=in,proto3" json:"in,omitempty"` -} - -func (x *HelloReq) Reset() { - *x = HelloReq{} - if protoimpl.UnsafeEnabled { - mi := &file_hello_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HelloReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HelloReq) ProtoMessage() {} - -func (x *HelloReq) ProtoReflect() protoreflect.Message { - mi := &file_hello_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HelloReq.ProtoReflect.Descriptor instead. -func (*HelloReq) Descriptor() ([]byte, []int) { - return file_hello_proto_rawDescGZIP(), []int{0} -} - -func (x *HelloReq) GetIn() string { - if x != nil { - return x.In - } - return "" -} - -type HelloResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` -} - -func (x *HelloResp) Reset() { - *x = HelloResp{} - if protoimpl.UnsafeEnabled { - mi := &file_hello_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HelloResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HelloResp) ProtoMessage() {} - -func (x *HelloResp) ProtoReflect() protoreflect.Message { - mi := &file_hello_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HelloResp.ProtoReflect.Descriptor instead. -func (*HelloResp) Descriptor() ([]byte, []int) { - return file_hello_proto_rawDescGZIP(), []int{1} -} - -func (x *HelloResp) GetMsg() string { - if x != nil { - return x.Msg - } - return "" -} - -var File_hello_proto protoreflect.FileDescriptor - -var file_hello_proto_rawDesc = []byte{ - 0x0a, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x68, - 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x1a, 0x0a, 0x08, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, - 0x22, 0x1d, 0x0a, 0x09, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x32, - 0x36, 0x0a, 0x05, 0x47, 0x72, 0x65, 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, - 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0f, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x48, 0x65, 0x6c, - 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x10, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x48, 0x65, - 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x68, 0x65, 0x6c, - 0x6c, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_hello_proto_rawDescOnce sync.Once - file_hello_proto_rawDescData = file_hello_proto_rawDesc -) - -func file_hello_proto_rawDescGZIP() []byte { - file_hello_proto_rawDescOnce.Do(func() { - file_hello_proto_rawDescData = protoimpl.X.CompressGZIP(file_hello_proto_rawDescData) - }) - return file_hello_proto_rawDescData -} - -var file_hello_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_hello_proto_goTypes = []any{ - (*HelloReq)(nil), // 0: hello.HelloReq - (*HelloResp)(nil), // 1: hello.HelloResp -} -var file_hello_proto_depIdxs = []int32{ - 0, // 0: hello.Greet.SayHello:input_type -> hello.HelloReq - 1, // 1: hello.Greet.SayHello:output_type -> hello.HelloResp - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_hello_proto_init() } -func file_hello_proto_init() { - if File_hello_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_hello_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*HelloReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hello_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*HelloResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_hello_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_hello_proto_goTypes, - DependencyIndexes: file_hello_proto_depIdxs, - MessageInfos: file_hello_proto_msgTypes, - }.Build() - File_hello_proto = out.File - file_hello_proto_rawDesc = nil - file_hello_proto_goTypes = nil - file_hello_proto_depIdxs = nil -} diff --git a/tools/goctl/example/rpc/hello/pb/hello/hello_grpc.pb.go b/tools/goctl/example/rpc/hello/pb/hello/hello_grpc.pb.go deleted file mode 100644 index 0400debef627..000000000000 --- a/tools/goctl/example/rpc/hello/pb/hello/hello_grpc.pb.go +++ /dev/null @@ -1,106 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.4 -// source: hello.proto - -package hello - -import ( - context "context" - - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// GreetClient is the client API for Greet service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type GreetClient interface { - SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) -} - -type greetClient struct { - cc grpc.ClientConnInterface -} - -func NewGreetClient(cc grpc.ClientConnInterface) GreetClient { - return &greetClient{cc} -} - -func (c *greetClient) SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) { - out := new(HelloResp) - err := c.cc.Invoke(ctx, "/hello.Greet/SayHello", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// GreetServer is the server API for Greet service. -// All implementations must embed UnimplementedGreetServer -// for forward compatibility -type GreetServer interface { - SayHello(context.Context, *HelloReq) (*HelloResp, error) - mustEmbedUnimplementedGreetServer() -} - -// UnimplementedGreetServer must be embedded to have forward compatible implementations. -type UnimplementedGreetServer struct { -} - -func (UnimplementedGreetServer) SayHello(context.Context, *HelloReq) (*HelloResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") -} -func (UnimplementedGreetServer) mustEmbedUnimplementedGreetServer() {} - -// UnsafeGreetServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to GreetServer will -// result in compilation errors. -type UnsafeGreetServer interface { - mustEmbedUnimplementedGreetServer() -} - -func RegisterGreetServer(s grpc.ServiceRegistrar, srv GreetServer) { - s.RegisterService(&Greet_ServiceDesc, srv) -} - -func _Greet_SayHello_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { - in := new(HelloReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GreetServer).SayHello(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/hello.Greet/SayHello", - } - handler := func(ctx context.Context, req any) (any, error) { - return srv.(GreetServer).SayHello(ctx, req.(*HelloReq)) - } - return interceptor(ctx, in, info, handler) -} - -// Greet_ServiceDesc is the grpc.ServiceDesc for Greet service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Greet_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "hello.Greet", - HandlerType: (*GreetServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SayHello", - Handler: _Greet_SayHello_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "hello.proto", -} diff --git a/tools/goctl/example/rpc/hi.proto b/tools/goctl/example/rpc/hi.proto deleted file mode 100644 index c75f577cb89c..000000000000 --- a/tools/goctl/example/rpc/hi.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; - -package hi; - -option go_package = "./hi"; - -message HiReq { - string in = 1; -} - -message HelloReq { - string in = 1; -} - -message HiResp { - string msg = 1; -} - -message HelloResp { - string msg = 1; -} - -service Greet { - rpc SayHi(HiReq) returns (HiResp); - rpc SayHello(HelloReq) returns (HelloResp); -} - -message EventReq{} -message EventResp{} - -service Event { - rpc AskQuestion(EventReq) returns (EventResp); -} \ No newline at end of file diff --git a/tools/goctl/example/rpc/hi/client/event/event.go b/tools/goctl/example/rpc/hi/client/event/event.go deleted file mode 100644 index df88758c87f2..000000000000 --- a/tools/goctl/example/rpc/hi/client/event/event.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hi.proto - -package client - -import ( - "context" - - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" -) - -type ( - EventReq = hi.EventReq - EventResp = hi.EventResp - HelloReq = hi.HelloReq - HelloResp = hi.HelloResp - HiReq = hi.HiReq - HiResp = hi.HiResp - - Event interface { - AskQuestion(ctx context.Context, in *EventReq, opts ...grpc.CallOption) (*EventResp, error) - } - - defaultEvent struct { - cli zrpc.Client - } -) - -func NewEvent(cli zrpc.Client) Event { - return &defaultEvent{ - cli: cli, - } -} - -func (m *defaultEvent) AskQuestion(ctx context.Context, in *EventReq, opts ...grpc.CallOption) (*EventResp, error) { - client := hi.NewEventClient(m.cli.Conn()) - return client.AskQuestion(ctx, in, opts...) -} diff --git a/tools/goctl/example/rpc/hi/client/greet/greet.go b/tools/goctl/example/rpc/hi/client/greet/greet.go deleted file mode 100644 index 366f9ed679aa..000000000000 --- a/tools/goctl/example/rpc/hi/client/greet/greet.go +++ /dev/null @@ -1,46 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hi.proto - -package client - -import ( - "context" - - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" -) - -type ( - EventReq = hi.EventReq - EventResp = hi.EventResp - HelloReq = hi.HelloReq - HelloResp = hi.HelloResp - HiReq = hi.HiReq - HiResp = hi.HiResp - - Greet interface { - SayHi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiResp, error) - SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) - } - - defaultGreet struct { - cli zrpc.Client - } -) - -func NewGreet(cli zrpc.Client) Greet { - return &defaultGreet{ - cli: cli, - } -} - -func (m *defaultGreet) SayHi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiResp, error) { - client := hi.NewGreetClient(m.cli.Conn()) - return client.SayHi(ctx, in, opts...) -} - -func (m *defaultGreet) SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) { - client := hi.NewGreetClient(m.cli.Conn()) - return client.SayHello(ctx, in, opts...) -} diff --git a/tools/goctl/example/rpc/hi/etc/hi.yaml b/tools/goctl/example/rpc/hi/etc/hi.yaml deleted file mode 100644 index ad1c83750d67..000000000000 --- a/tools/goctl/example/rpc/hi/etc/hi.yaml +++ /dev/null @@ -1,6 +0,0 @@ -Name: hi.rpc -ListenOn: 127.0.0.1:8080 -Etcd: - Hosts: - - 127.0.0.1:2379 - Key: hi.rpc diff --git a/tools/goctl/example/rpc/hi/hi.go b/tools/goctl/example/rpc/hi/hi.go deleted file mode 100644 index 75cebb157e45..000000000000 --- a/tools/goctl/example/rpc/hi/hi.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "flag" - "fmt" - - "github.com/zeromicro/go-zero/core/conf" - "github.com/zeromicro/go-zero/core/service" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/config" - eventServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/event" - greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/greet" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -var configFile = flag.String("f", "etc/hi.yaml", "the config file") - -func main() { - flag.Parse() - - var c config.Config - conf.MustLoad(*configFile, &c) - ctx := svc.NewServiceContext(c) - - s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) { - hi.RegisterGreetServer(grpcServer, greetServer.NewGreetServer(ctx)) - hi.RegisterEventServer(grpcServer, eventServer.NewEventServer(ctx)) - - if c.Mode == service.DevMode || c.Mode == service.TestMode { - reflection.Register(grpcServer) - } - }) - defer s.Stop() - - fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) - s.Start() -} diff --git a/tools/goctl/example/rpc/hi/internal/config/config.go b/tools/goctl/example/rpc/hi/internal/config/config.go deleted file mode 100755 index c1f85b99ac9f..000000000000 --- a/tools/goctl/example/rpc/hi/internal/config/config.go +++ /dev/null @@ -1,7 +0,0 @@ -package config - -import "github.com/zeromicro/go-zero/zrpc" - -type Config struct { - zrpc.RpcServerConf -} diff --git a/tools/goctl/example/rpc/hi/internal/logic/event/askquestionlogic.go b/tools/goctl/example/rpc/hi/internal/logic/event/askquestionlogic.go deleted file mode 100644 index 9360bd3323d6..000000000000 --- a/tools/goctl/example/rpc/hi/internal/logic/event/askquestionlogic.go +++ /dev/null @@ -1,29 +0,0 @@ -package eventlogic - -import ( - "context" - - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" -) - -type AskQuestionLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func NewAskQuestionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AskQuestionLogic { - return &AskQuestionLogic{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} - -func (l *AskQuestionLogic) AskQuestion(in *hi.EventReq) (*hi.EventResp, error) { - // todo: add your logic here and delete this line - - return &hi.EventResp{}, nil -} diff --git a/tools/goctl/example/rpc/hi/internal/logic/greet/sayhellologic.go b/tools/goctl/example/rpc/hi/internal/logic/greet/sayhellologic.go deleted file mode 100644 index 11c9f8687945..000000000000 --- a/tools/goctl/example/rpc/hi/internal/logic/greet/sayhellologic.go +++ /dev/null @@ -1,29 +0,0 @@ -package greetlogic - -import ( - "context" - - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" -) - -type SayHelloLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func NewSayHelloLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SayHelloLogic { - return &SayHelloLogic{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} - -func (l *SayHelloLogic) SayHello(in *hi.HelloReq) (*hi.HelloResp, error) { - // todo: add your logic here and delete this line - - return &hi.HelloResp{}, nil -} diff --git a/tools/goctl/example/rpc/hi/internal/logic/greet/sayhilogic.go b/tools/goctl/example/rpc/hi/internal/logic/greet/sayhilogic.go deleted file mode 100644 index f97eca7afadd..000000000000 --- a/tools/goctl/example/rpc/hi/internal/logic/greet/sayhilogic.go +++ /dev/null @@ -1,29 +0,0 @@ -package greetlogic - -import ( - "context" - - "github.com/zeromicro/go-zero/core/logx" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" -) - -type SayHiLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func NewSayHiLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SayHiLogic { - return &SayHiLogic{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} - -func (l *SayHiLogic) SayHi(in *hi.HiReq) (*hi.HiResp, error) { - // todo: add your logic here and delete this line - - return &hi.HiResp{}, nil -} diff --git a/tools/goctl/example/rpc/hi/internal/server/event/eventserver.go b/tools/goctl/example/rpc/hi/internal/server/event/eventserver.go deleted file mode 100644 index 22cd2a374735..000000000000 --- a/tools/goctl/example/rpc/hi/internal/server/event/eventserver.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hi.proto - -package server - -import ( - "context" - - eventlogic "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/logic/event" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" -) - -type EventServer struct { - svcCtx *svc.ServiceContext - hi.UnimplementedEventServer -} - -func NewEventServer(svcCtx *svc.ServiceContext) *EventServer { - return &EventServer{ - svcCtx: svcCtx, - } -} - -func (s *EventServer) AskQuestion(ctx context.Context, in *hi.EventReq) (*hi.EventResp, error) { - l := eventlogic.NewAskQuestionLogic(ctx, s.svcCtx) - return l.AskQuestion(in) -} diff --git a/tools/goctl/example/rpc/hi/internal/server/greet/greetserver.go b/tools/goctl/example/rpc/hi/internal/server/greet/greetserver.go deleted file mode 100644 index a6212826c6f8..000000000000 --- a/tools/goctl/example/rpc/hi/internal/server/greet/greetserver.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by goctl. DO NOT EDIT! -// Source: hi.proto - -package server - -import ( - "context" - - greetlogic "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/logic/greet" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc" - "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi" -) - -type GreetServer struct { - svcCtx *svc.ServiceContext - hi.UnimplementedGreetServer -} - -func NewGreetServer(svcCtx *svc.ServiceContext) *GreetServer { - return &GreetServer{ - svcCtx: svcCtx, - } -} - -func (s *GreetServer) SayHi(ctx context.Context, in *hi.HiReq) (*hi.HiResp, error) { - l := greetlogic.NewSayHiLogic(ctx, s.svcCtx) - return l.SayHi(in) -} - -func (s *GreetServer) SayHello(ctx context.Context, in *hi.HelloReq) (*hi.HelloResp, error) { - l := greetlogic.NewSayHelloLogic(ctx, s.svcCtx) - return l.SayHello(in) -} diff --git a/tools/goctl/example/rpc/hi/internal/svc/servicecontext.go b/tools/goctl/example/rpc/hi/internal/svc/servicecontext.go deleted file mode 100644 index fe4af36e8a86..000000000000 --- a/tools/goctl/example/rpc/hi/internal/svc/servicecontext.go +++ /dev/null @@ -1,13 +0,0 @@ -package svc - -import "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/config" - -type ServiceContext struct { - Config config.Config -} - -func NewServiceContext(c config.Config) *ServiceContext { - return &ServiceContext{ - Config: c, - } -} diff --git a/tools/goctl/example/rpc/hi/pb/hi/hi.pb.go b/tools/goctl/example/rpc/hi/pb/hi/hi.pb.go deleted file mode 100644 index 011b4e95eae9..000000000000 --- a/tools/goctl/example/rpc/hi/pb/hi/hi.pb.go +++ /dev/null @@ -1,444 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.0 -// protoc v3.19.4 -// source: hi.proto - -package hi - -import ( - reflect "reflect" - sync "sync" - - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type HiReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - In string `protobuf:"bytes,1,opt,name=in,proto3" json:"in,omitempty"` -} - -func (x *HiReq) Reset() { - *x = HiReq{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HiReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HiReq) ProtoMessage() {} - -func (x *HiReq) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HiReq.ProtoReflect.Descriptor instead. -func (*HiReq) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{0} -} - -func (x *HiReq) GetIn() string { - if x != nil { - return x.In - } - return "" -} - -type HelloReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - In string `protobuf:"bytes,1,opt,name=in,proto3" json:"in,omitempty"` -} - -func (x *HelloReq) Reset() { - *x = HelloReq{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HelloReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HelloReq) ProtoMessage() {} - -func (x *HelloReq) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HelloReq.ProtoReflect.Descriptor instead. -func (*HelloReq) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{1} -} - -func (x *HelloReq) GetIn() string { - if x != nil { - return x.In - } - return "" -} - -type HiResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` -} - -func (x *HiResp) Reset() { - *x = HiResp{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HiResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HiResp) ProtoMessage() {} - -func (x *HiResp) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HiResp.ProtoReflect.Descriptor instead. -func (*HiResp) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{2} -} - -func (x *HiResp) GetMsg() string { - if x != nil { - return x.Msg - } - return "" -} - -type HelloResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` -} - -func (x *HelloResp) Reset() { - *x = HelloResp{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HelloResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HelloResp) ProtoMessage() {} - -func (x *HelloResp) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HelloResp.ProtoReflect.Descriptor instead. -func (*HelloResp) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{3} -} - -func (x *HelloResp) GetMsg() string { - if x != nil { - return x.Msg - } - return "" -} - -type EventReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *EventReq) Reset() { - *x = EventReq{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EventReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventReq) ProtoMessage() {} - -func (x *EventReq) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EventReq.ProtoReflect.Descriptor instead. -func (*EventReq) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{4} -} - -type EventResp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *EventResp) Reset() { - *x = EventResp{} - if protoimpl.UnsafeEnabled { - mi := &file_hi_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EventResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventResp) ProtoMessage() {} - -func (x *EventResp) ProtoReflect() protoreflect.Message { - mi := &file_hi_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EventResp.ProtoReflect.Descriptor instead. -func (*EventResp) Descriptor() ([]byte, []int) { - return file_hi_proto_rawDescGZIP(), []int{5} -} - -var File_hi_proto protoreflect.FileDescriptor - -var file_hi_proto_rawDesc = []byte{ - 0x0a, 0x08, 0x68, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x68, 0x69, 0x22, 0x17, - 0x0a, 0x05, 0x48, 0x69, 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x22, 0x1a, 0x0a, 0x08, 0x48, 0x65, 0x6c, 0x6c, 0x6f, - 0x52, 0x65, 0x71, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x6e, 0x22, 0x1a, 0x0a, 0x06, 0x48, 0x69, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, - 0x1d, 0x0a, 0x09, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, - 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x0a, - 0x0a, 0x08, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x22, 0x0b, 0x0a, 0x09, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x32, 0x50, 0x0a, 0x05, 0x47, 0x72, 0x65, 0x65, 0x74, - 0x12, 0x1e, 0x0a, 0x05, 0x53, 0x61, 0x79, 0x48, 0x69, 0x12, 0x09, 0x2e, 0x68, 0x69, 0x2e, 0x48, - 0x69, 0x52, 0x65, 0x71, 0x1a, 0x0a, 0x2e, 0x68, 0x69, 0x2e, 0x48, 0x69, 0x52, 0x65, 0x73, 0x70, - 0x12, 0x27, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0c, 0x2e, 0x68, - 0x69, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x0d, 0x2e, 0x68, 0x69, 0x2e, - 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x32, 0x33, 0x0a, 0x05, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x0b, 0x41, 0x73, 0x6b, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x0c, 0x2e, 0x68, 0x69, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, - 0x0d, 0x2e, 0x68, 0x69, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x06, - 0x5a, 0x04, 0x2e, 0x2f, 0x68, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_hi_proto_rawDescOnce sync.Once - file_hi_proto_rawDescData = file_hi_proto_rawDesc -) - -func file_hi_proto_rawDescGZIP() []byte { - file_hi_proto_rawDescOnce.Do(func() { - file_hi_proto_rawDescData = protoimpl.X.CompressGZIP(file_hi_proto_rawDescData) - }) - return file_hi_proto_rawDescData -} - -var file_hi_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_hi_proto_goTypes = []any{ - (*HiReq)(nil), // 0: hi.HiReq - (*HelloReq)(nil), // 1: hi.HelloReq - (*HiResp)(nil), // 2: hi.HiResp - (*HelloResp)(nil), // 3: hi.HelloResp - (*EventReq)(nil), // 4: hi.EventReq - (*EventResp)(nil), // 5: hi.EventResp -} -var file_hi_proto_depIdxs = []int32{ - 0, // 0: hi.Greet.SayHi:input_type -> hi.HiReq - 1, // 1: hi.Greet.SayHello:input_type -> hi.HelloReq - 4, // 2: hi.Event.AskQuestion:input_type -> hi.EventReq - 2, // 3: hi.Greet.SayHi:output_type -> hi.HiResp - 3, // 4: hi.Greet.SayHello:output_type -> hi.HelloResp - 5, // 5: hi.Event.AskQuestion:output_type -> hi.EventResp - 3, // [3:6] is the sub-list for method output_type - 0, // [0:3] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_hi_proto_init() } -func file_hi_proto_init() { - if File_hi_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_hi_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*HiReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hi_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*HelloReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hi_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*HiResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hi_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*HelloResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hi_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*EventReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_hi_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*EventResp); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_hi_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 2, - }, - GoTypes: file_hi_proto_goTypes, - DependencyIndexes: file_hi_proto_depIdxs, - MessageInfos: file_hi_proto_msgTypes, - }.Build() - File_hi_proto = out.File - file_hi_proto_rawDesc = nil - file_hi_proto_goTypes = nil - file_hi_proto_depIdxs = nil -} diff --git a/tools/goctl/example/rpc/hi/pb/hi/hi_grpc.pb.go b/tools/goctl/example/rpc/hi/pb/hi/hi_grpc.pb.go deleted file mode 100644 index 113dbd6cbb92..000000000000 --- a/tools/goctl/example/rpc/hi/pb/hi/hi_grpc.pb.go +++ /dev/null @@ -1,228 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.19.4 -// source: hi.proto - -package hi - -import ( - context "context" - - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// GreetClient is the client API for Greet service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type GreetClient interface { - SayHi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiResp, error) - SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) -} - -type greetClient struct { - cc grpc.ClientConnInterface -} - -func NewGreetClient(cc grpc.ClientConnInterface) GreetClient { - return &greetClient{cc} -} - -func (c *greetClient) SayHi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiResp, error) { - out := new(HiResp) - err := c.cc.Invoke(ctx, "/hi.Greet/SayHi", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *greetClient) SayHello(ctx context.Context, in *HelloReq, opts ...grpc.CallOption) (*HelloResp, error) { - out := new(HelloResp) - err := c.cc.Invoke(ctx, "/hi.Greet/SayHello", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// GreetServer is the server API for Greet service. -// All implementations must embed UnimplementedGreetServer -// for forward compatibility -type GreetServer interface { - SayHi(context.Context, *HiReq) (*HiResp, error) - SayHello(context.Context, *HelloReq) (*HelloResp, error) - mustEmbedUnimplementedGreetServer() -} - -// UnimplementedGreetServer must be embedded to have forward compatible implementations. -type UnimplementedGreetServer struct { -} - -func (UnimplementedGreetServer) SayHi(context.Context, *HiReq) (*HiResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method SayHi not implemented") -} -func (UnimplementedGreetServer) SayHello(context.Context, *HelloReq) (*HelloResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") -} -func (UnimplementedGreetServer) mustEmbedUnimplementedGreetServer() {} - -// UnsafeGreetServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to GreetServer will -// result in compilation errors. -type UnsafeGreetServer interface { - mustEmbedUnimplementedGreetServer() -} - -func RegisterGreetServer(s grpc.ServiceRegistrar, srv GreetServer) { - s.RegisterService(&Greet_ServiceDesc, srv) -} - -func _Greet_SayHi_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { - in := new(HiReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GreetServer).SayHi(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/hi.Greet/SayHi", - } - handler := func(ctx context.Context, req any) (any, error) { - return srv.(GreetServer).SayHi(ctx, req.(*HiReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _Greet_SayHello_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { - in := new(HelloReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(GreetServer).SayHello(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/hi.Greet/SayHello", - } - handler := func(ctx context.Context, req any) (any, error) { - return srv.(GreetServer).SayHello(ctx, req.(*HelloReq)) - } - return interceptor(ctx, in, info, handler) -} - -// Greet_ServiceDesc is the grpc.ServiceDesc for Greet service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Greet_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "hi.Greet", - HandlerType: (*GreetServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SayHi", - Handler: _Greet_SayHi_Handler, - }, - { - MethodName: "SayHello", - Handler: _Greet_SayHello_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "hi.proto", -} - -// EventClient is the client API for Event service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type EventClient interface { - AskQuestion(ctx context.Context, in *EventReq, opts ...grpc.CallOption) (*EventResp, error) -} - -type eventClient struct { - cc grpc.ClientConnInterface -} - -func NewEventClient(cc grpc.ClientConnInterface) EventClient { - return &eventClient{cc} -} - -func (c *eventClient) AskQuestion(ctx context.Context, in *EventReq, opts ...grpc.CallOption) (*EventResp, error) { - out := new(EventResp) - err := c.cc.Invoke(ctx, "/hi.Event/AskQuestion", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// EventServer is the server API for Event service. -// All implementations must embed UnimplementedEventServer -// for forward compatibility -type EventServer interface { - AskQuestion(context.Context, *EventReq) (*EventResp, error) - mustEmbedUnimplementedEventServer() -} - -// UnimplementedEventServer must be embedded to have forward compatible implementations. -type UnimplementedEventServer struct { -} - -func (UnimplementedEventServer) AskQuestion(context.Context, *EventReq) (*EventResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method AskQuestion not implemented") -} -func (UnimplementedEventServer) mustEmbedUnimplementedEventServer() {} - -// UnsafeEventServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to EventServer will -// result in compilation errors. -type UnsafeEventServer interface { - mustEmbedUnimplementedEventServer() -} - -func RegisterEventServer(s grpc.ServiceRegistrar, srv EventServer) { - s.RegisterService(&Event_ServiceDesc, srv) -} - -func _Event_AskQuestion_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) { - in := new(EventReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(EventServer).AskQuestion(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/hi.Event/AskQuestion", - } - handler := func(ctx context.Context, req any) (any, error) { - return srv.(EventServer).AskQuestion(ctx, req.(*EventReq)) - } - return interceptor(ctx, in, info, handler) -} - -// Event_ServiceDesc is the grpc.ServiceDesc for Event service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Event_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "hi.Event", - HandlerType: (*EventServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "AskQuestion", - Handler: _Event_AskQuestion_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "hi.proto", -} diff --git a/tools/goctl/example/rpc/multiple_rpc_service_generate.sh b/tools/goctl/example/rpc/multiple_rpc_service_generate.sh deleted file mode 100644 index 10b1fa968f84..000000000000 --- a/tools/goctl/example/rpc/multiple_rpc_service_generate.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -wd=$(pwd) -output="$wd/hi" - -rm -rf $output - -goctl rpc protoc -I $wd "$wd/hi.proto" --go_out="$output/pb" --go-grpc_out="$output/pb" --zrpc_out="$output" --multiple - -if [ $? -ne 0 ]; then - echo "Generate failed" - exit 1 -fi - -go mod tidy - -if [ $? -ne 0 ]; then - echo "Tidy failed" - exit 1 -fi - -go test ./... \ No newline at end of file diff --git a/tools/goctl/example/rpc/single_rpc_service_generate.sh b/tools/goctl/example/rpc/single_rpc_service_generate.sh deleted file mode 100644 index c8e8316f6e8d..000000000000 --- a/tools/goctl/example/rpc/single_rpc_service_generate.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -wd=$(pwd) -output="$wd/hello" - -rm -rf $output - -goctl rpc protoc -I $wd "$wd/hello.proto" --go_out="$output/pb" --go-grpc_out="$output/pb" --zrpc_out="$output" --multiple - -if [ $? -ne 0 ]; then - echo "Generate failed" - exit 1 -fi - -go mod tidy - -if [ $? -ne 0 ]; then - echo "Tidy failed" - exit 1 -fi - -go test ./... \ No newline at end of file diff --git a/tools/goctl/internal/flags/default_en.json b/tools/goctl/internal/flags/default_en.json index 2b86cdda89e2..1373a5dd03ce 100644 --- a/tools/goctl/internal/flags/default_en.json +++ b/tools/goctl/internal/flags/default_en.json @@ -259,7 +259,8 @@ "remote": "{{.global.remote}}", "branch": "{{.global.branch}}", "verbose": "Enable log output", - "client": "Whether to generate rpc client" + "client": "Whether to generate rpc client", + "name": "Service name. Setting the rpc service name prevents it from defaulting to the proto file name. This enables the use of multiple proto files within the same service for code generation" } }, "template": { diff --git a/tools/goctl/rpc/README.md b/tools/goctl/rpc/README.md index 2394fbd1bb8b..79c579101027 100644 --- a/tools/goctl/rpc/README.md +++ b/tools/goctl/rpc/README.md @@ -105,6 +105,7 @@ Flags: --style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md] (default "gozero") -v, --verbose Enable log output --zrpc_out string The zrpc output directory + --name string Rpc service name. Setting the rpc service name prevents it from defaulting to the proto file name. This enables the use of multiple proto files within the same service for code generation. ``` ### 参数说明 @@ -115,6 +116,7 @@ Flags: * --style 指定文件输出格式 * -v, --verbose 显示日志 * --zrpc_out 指定zrpc输出目录 +* --name 指定rpc服务名,如果如果不设置就使用proto文件名作为rpc服务名称,同时也允许在同一个rpc服务中使用多个proto文件来生成代码 > ## --multiple > 是否开启多个 rpc service 生成,如果开启,则满足一下新特性 @@ -200,4 +202,160 @@ hello └── hello ├── hello.pb.go └── hello_grpc.pb.go +``` + +### --name +分别执行以下命令 +```shell +goctl.exe rpc protoc app/pb/user.proto --go_out=./app/pb --go-grpc_out=./app/pb --zrpc_out=./app --style=go_zero -m --name app +goctl.exe rpc protoc app/pb/role.proto --go_out=./app/pb --go-grpc_out=./app/pb --zrpc_out=./app --style=go_zero -m --name app +``` +生成目录结构如下: +```text +app/ +├── app.go +├── client/ +│ ├── roleservice/ +│ │ └── role_service.go +│ └── userservice/ +│ └── user_service.go +├── etc/ +│ └── app.yaml +├── internal/ +│ ├── config/ +│ │ └── config.go +│ ├── logic/ +│ │ ├── roleservice/ +│ │ │ ├── create_role_logic.go +│ │ │ └── update_role_logic.go +│ │ └── userservice/ +│ │ ├── create_user_logic.go +│ │ └── user_detail_logic.go +│ ├── server/ +│ │ ├── roleservice/ +│ │ │ └── role_service_server.go +│ │ └── userservice/ +│ │ └── user_service_server.go +│ └── svc/ +│ └── service_context.go +└── pb/ + ├── role/ + │ ├── role.pb.go + │ └── role_grpc.pb.go + ├── user/ + │ ├── user.pb.go + │ └── user_grpc.pb.go + ├── user.proto + └── role.proto +``` + +## 使用多个proto生成rpc服务,并且允许导入其他proto文件 +目录结构如下: +```text +root/ +├── app/ +│ └──pb/ +│ ├── subpb/ +│ ├── common.proto +│ ├── role.proto +│ └── user.proto +└── third_party/ + └── google/ +``` +commom.proto +```protobuf +syntax = "proto3"; + +package common; + +option go_package = "github/xxx/project/app/pb/common"; + +message EmptyRequest { +} + +message EmptyResponse { +} +``` +role.proto +```protobuf +syntax = "proto3"; + +package role; +option go_package = "github/xxx/project/app/pb/role"; + +import "common.proto"; +import "google/protobuf/any.proto"; +import "subpb/sub.proto"; + +message GetRoleRequest { + string id = 1; +} + +message GetRoleResponse { + string id = 1; + string name = 2; + string description = 3; +} + + +service role { +// rpc GetRole(GetRoleRequest) returns (GetRoleResponse); + rpc Empty(common.EmptyRequest) returns (subpb.sub.SubMessage); + rpc GetRole(google.protobuf.Any) returns (GetRoleResponse); + rpc GetStream(stream GetRoleRequest) returns (stream subpb.sub.SubResponse); + rpc GetStream2(GetRoleRequest) returns (stream subpb.sub.SubResponse); + rpc GetStream3(stream GetRoleRequest) returns (subpb.sub.SubResponse); +} +``` +user.proto +```protobuf +syntax = "proto3"; + +package user; +option go_package = "github/xxx/project/app/pb/user"; + +message GetUserRequest { + string id = 1; +} + +message GetUserResponse { + string id = 1; + string name = 2; +} +service user { + rpc GetUser(GetUserRequest) returns (GetUserResponse); +} +``` +sub.proto +```protobuf +syntax = "proto3"; + +package subpb.sub; + +option go_package = "github/xxx/project/app/pb/subpb/sub;sub"; + +message SubMessage { + string name = 1; +} + +message SubResponse { + SubMessage message = 1; +} +``` +执行命令生成rpc服务(需要配合go_package一起使用) +```shell +goctl rpc protoc \ +app/pb/role.proto \ +app/pb/user.proto \ +app/pb/common.proto \ +app/pb/subpb/sub.proto \ +--go_out=./app/pb \ +--go_opt=module=github/xxx/project/app/pb \ +--go-grpc_out=./app/pb \ +--go-grpc_opt=module=github/xxx/project/app/pb \ +--zrpc_out=./app \ +--style go_zero \ +-I ./app/pb \ +-I ./third_party \ +-m --name=myapp ``` \ No newline at end of file diff --git a/tools/goctl/rpc/cli/cli.go b/tools/goctl/rpc/cli/cli.go index 09193052a34b..4028dc15754a 100644 --- a/tools/goctl/rpc/cli/cli.go +++ b/tools/goctl/rpc/cli/cli.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/zeromicro/go-zero/tools/goctl/rpc/generator" "github.com/zeromicro/go-zero/tools/goctl/util" "github.com/zeromicro/go-zero/tools/goctl/util/console" @@ -38,6 +39,8 @@ var ( VarStringStyle string // VarStringZRPCOut describes the zRPC output. VarStringZRPCOut string + // VarStringName describes the service name + VarStringName string // VarBoolIdea describes whether idea or not VarBoolIdea bool // VarBoolVerbose describes whether verbose. @@ -86,7 +89,7 @@ func RPCNew(_ *cobra.Command, args []string) error { } var ctx generator.ZRpcContext - ctx.Src = src + ctx.Src = []string{src} ctx.GoOutput = filepath.Dir(src) ctx.GrpcOutput = filepath.Dir(src) ctx.IsGooglePlugin = true @@ -94,6 +97,10 @@ func RPCNew(_ *cobra.Command, args []string) error { ctx.ProtocCmd = fmt.Sprintf("protoc -I=%s %s --go_out=%s --go-grpc_out=%s", filepath.Dir(src), filepath.Base(src), filepath.Dir(src), filepath.Dir(src)) ctx.IsGenClient = VarBoolClient ctx.Module = VarStringModule + ctx.Name = VarStringName + for _, protoPath := range VarStringSliceProtoPath { + ctx.ImportProtoDirs = append(ctx.ImportProtoDirs, filepath.Dir(protoPath)) + } grpcOptList := VarStringSliceGoGRPCOpt if len(grpcOptList) > 0 { diff --git a/tools/goctl/rpc/cli/zrpc.go b/tools/goctl/rpc/cli/zrpc.go index 3f42c1135ac8..fac7c3badfb8 100644 --- a/tools/goctl/rpc/cli/zrpc.go +++ b/tools/goctl/rpc/cli/zrpc.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/spf13/cobra" + "github.com/zeromicro/go-zero/tools/goctl/rpc/generator" "github.com/zeromicro/go-zero/tools/goctl/util" "github.com/zeromicro/go-zero/tools/goctl/util/pathx" @@ -27,7 +28,8 @@ func ZRPC(_ *cobra.Command, args []string) error { return err } - source := args[0] + // source := args[0] + source := args grpcOutList := VarStringSliceGoGRPCOut goOutList := VarStringSliceGoOut zrpcOut := VarStringZRPCOut @@ -66,6 +68,7 @@ func ZRPC(_ *cobra.Command, args []string) error { if err != nil { return err } + if len(remote) > 0 { repo, _ := util.CloneIntoGitHome(remote, branch) if len(repo) > 0 { @@ -104,6 +107,15 @@ func ZRPC(_ *cobra.Command, args []string) error { ctx.ProtocCmd = strings.Join(protocArgs, " ") ctx.IsGenClient = VarBoolClient ctx.Module = VarStringModule + ctx.Name = VarStringName + for _, protoPath := range VarStringSliceProtoPath { + protoPath, err = filepath.Abs(protoPath) + if err != nil { + return err + } + ctx.ImportProtoDirs = append(ctx.ImportProtoDirs, protoPath) + } + g := generator.NewGenerator(style, verbose) return g.Generate(&ctx) } diff --git a/tools/goctl/rpc/cmd.go b/tools/goctl/rpc/cmd.go index c474acc2c778..044b5d78db5d 100644 --- a/tools/goctl/rpc/cmd.go +++ b/tools/goctl/rpc/cmd.go @@ -2,6 +2,7 @@ package rpc import ( "github.com/spf13/cobra" + "github.com/zeromicro/go-zero/tools/goctl/config" "github.com/zeromicro/go-zero/tools/goctl/internal/cobrax" "github.com/zeromicro/go-zero/tools/goctl/rpc/cli" @@ -17,7 +18,7 @@ var ( })) newCmd = cobrax.NewCommand("new", cobrax.WithRunE(cli.RPCNew), cobrax.WithArgs(cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs))) - protocCmd = cobrax.NewCommand("protoc", cobrax.WithRunE(cli.ZRPC), cobrax.WithArgs(cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs))) + protocCmd = cobrax.NewCommand("protoc", cobrax.WithRunE(cli.ZRPC), cobrax.WithArgs(cobra.MatchAll(cobra.MinimumNArgs(1), cobra.OnlyValidArgs))) ) func init() { @@ -59,6 +60,7 @@ func init() { protocCmdFlags.StringVar(&cli.VarStringRemote, "remote") protocCmdFlags.StringVar(&cli.VarStringBranch, "branch") protocCmdFlags.StringVar(&cli.VarStringModule, "module") + protocCmdFlags.StringVar(&cli.VarStringName, "name") protocCmdFlags.BoolVarP(&cli.VarBoolVerbose, "verbose", "v") protocCmdFlags.MarkHidden("go_out") protocCmdFlags.MarkHidden("go-grpc_out") diff --git a/tools/goctl/rpc/generator/call.tpl b/tools/goctl/rpc/generator/call.tpl index 27b48796dff3..e607b5d47dcd 100644 --- a/tools/goctl/rpc/generator/call.tpl +++ b/tools/goctl/rpc/generator/call.tpl @@ -5,15 +5,13 @@ package {{.filePackage}} import ( "context" - {{.pbPackage}} - {{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}} + {{.imports}} "github.com/zeromicro/go-zero/zrpc" "google.golang.org/grpc" ) type ( - {{.alias}} {{.serviceName}} interface { {{.interface}} diff --git a/tools/goctl/rpc/generator/gen.go b/tools/goctl/rpc/generator/gen.go index 9ff9aa60deaf..c056ecb94a8f 100644 --- a/tools/goctl/rpc/generator/gen.go +++ b/tools/goctl/rpc/generator/gen.go @@ -11,7 +11,7 @@ import ( type ZRpcContext struct { // Src is the source file of the proto. - Src string + Src []string // ProtocCmd is the command to generate proto files. ProtocCmd string // ProtoGenGrpcDir is the directory to store the generated proto files. @@ -26,12 +26,16 @@ type ZRpcContext struct { GrpcOutput string // Output is the output directory of the generated files. Output string + // Name is the rpc service name + Name string // Multiple is the flag to indicate whether the proto file is generated in multiple mode. Multiple bool // Whether to generate rpc client IsGenClient bool // Module is the custom module name for go.mod Module string + // ImportProtoDirs is the directories to import proto files + ImportProtoDirs []string } // Generate generates a rpc service, through the proto file, @@ -64,55 +68,56 @@ func (g *Generator) Generate(zctx *ZRpcContext) error { } p := parser.NewDefaultProtoParser() - proto, err := p.Parse(zctx.Src, zctx.Multiple) + protos, err := p.ParseAll(zctx.Src, zctx.ImportProtoDirs, zctx.Multiple) if err != nil { return err } - dirCtx, err := mkdir(projectCtx, proto, g.cfg, zctx) - if err != nil { - return err + for i, proto := range protos { + dirCtx, err := mkdir(projectCtx, proto, g.cfg, zctx) + if err != nil { + return err + } + + err = g.GenEtc(dirCtx, proto, g.cfg, zctx) + if err != nil { + return err + } + + err = g.GenPb(dirCtx, zctx, i, proto.HasGrpcService()) + if err != nil { + return err + } + + err = g.GenConfig(dirCtx, proto, g.cfg) + if err != nil { + return err + } + + err = g.GenSvc(dirCtx, proto, g.cfg) + if err != nil { + return err + } + + err = g.GenLogic(dirCtx, proto, g.cfg, zctx) + if err != nil { + return err + } + + err = g.GenServer(dirCtx, proto, g.cfg, zctx) + if err != nil { + return err + } + + err = g.GenMain(dirCtx, proto, g.cfg, zctx) + if err != nil { + return err + } + + if zctx.IsGenClient { + err = g.GenCall(dirCtx, proto, g.cfg, zctx) + } } - - err = g.GenEtc(dirCtx, proto, g.cfg) - if err != nil { - return err - } - - err = g.GenPb(dirCtx, zctx) - if err != nil { - return err - } - - err = g.GenConfig(dirCtx, proto, g.cfg) - if err != nil { - return err - } - - err = g.GenSvc(dirCtx, proto, g.cfg) - if err != nil { - return err - } - - err = g.GenLogic(dirCtx, proto, g.cfg, zctx) - if err != nil { - return err - } - - err = g.GenServer(dirCtx, proto, g.cfg, zctx) - if err != nil { - return err - } - - err = g.GenMain(dirCtx, proto, g.cfg, zctx) - if err != nil { - return err - } - - if zctx.IsGenClient { - err = g.GenCall(dirCtx, proto, g.cfg, zctx) - } - console.NewColorConsole().MarkDone() return err diff --git a/tools/goctl/rpc/generator/gen_module_test.go b/tools/goctl/rpc/generator/gen_module_test.go index daa57c39e27b..6d912f7c3298 100644 --- a/tools/goctl/rpc/generator/gen_module_test.go +++ b/tools/goctl/rpc/generator/gen_module_test.go @@ -82,7 +82,7 @@ service ` + strings.Title(tt.serviceName) + ` { // Set up ZRpcContext with module support zctx := &ZRpcContext{ - Src: protoFile, + Src: []string{protoFile}, ProtocCmd: "", // We'll skip protoc generation in tests GoOutput: serviceDir, GrpcOutput: serviceDir, @@ -188,7 +188,7 @@ func testRpcGenerateCore(g *Generator, zctx *ZRpcContext) error { func TestZRpcContext_ModuleField(t *testing.T) { // Test that ZRpcContext properly holds the Module field zctx := &ZRpcContext{ - Src: "/path/to/test.proto", + Src: []string{"/path/to/test.proto"}, Output: "/path/to/output", Multiple: false, IsGenClient: false, @@ -292,7 +292,7 @@ func TestRandomProjectGeneration_WithModule(t *testing.T) { // Test with a custom module name customModule := "github.com/test/" + projectName zctx := &ZRpcContext{ - Src: filepath.Join(serviceDir, "test.proto"), + Src: []string{filepath.Join(serviceDir, "test.proto")}, Output: serviceDir, Module: customModule, Multiple: false, @@ -314,10 +314,10 @@ service Test { rpc Call(Request) returns (Response); }` - err = os.WriteFile(zctx.Src, []byte(protoContent), 0644) + err = os.WriteFile(zctx.Src[0], []byte(protoContent), 0644) require.NoError(t, err) // Verify file was created and context is properly set - assert.FileExists(t, zctx.Src) + assert.FileExists(t, zctx.Src[0]) assert.Equal(t, customModule, zctx.Module) } diff --git a/tools/goctl/rpc/generator/gen_test.go b/tools/goctl/rpc/generator/gen_test.go index 1c87a1d72be8..0a0cdfa695fe 100644 --- a/tools/goctl/rpc/generator/gen_test.go +++ b/tools/goctl/rpc/generator/gen_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stringx" + "github.com/zeromicro/go-zero/tools/goctl/rpc/execx" ) @@ -39,7 +40,7 @@ func TestRpcGenerate(t *testing.T) { // case go path t.Run("GOPATH", func(t *testing.T) { ctx := &ZRpcContext{ - Src: "./test.proto", + Src: []string{"./test.proto"}, ProtocCmd: fmt.Sprintf("protoc -I=%s test.proto --go_out=%s --go_opt=Mbase/common.proto=./base --go-grpc_out=%s", common, projectDir, projectDir), IsGooglePlugin: true, @@ -65,7 +66,7 @@ func TestRpcGenerate(t *testing.T) { projectDir = filepath.Join(workDir, projectName) ctx := &ZRpcContext{ - Src: "./test.proto", + Src: []string{"./test.proto"}, ProtocCmd: fmt.Sprintf("protoc -I=%s test.proto --go_out=%s --go_opt=Mbase/common.proto=./base --go-grpc_out=%s", common, projectDir, projectDir), IsGooglePlugin: true, diff --git a/tools/goctl/rpc/generator/gencall.go b/tools/goctl/rpc/generator/gencall.go index 6d59610be259..16ac2aab8571 100644 --- a/tools/goctl/rpc/generator/gencall.go +++ b/tools/goctl/rpc/generator/gencall.go @@ -4,11 +4,11 @@ import ( _ "embed" "fmt" "path/filepath" - "sort" "strings" "github.com/emicklei/proto" "github.com/zeromicro/go-zero/core/collection" + conf "github.com/zeromicro/go-zero/tools/goctl/config" "github.com/zeromicro/go-zero/tools/goctl/rpc/parser" "github.com/zeromicro/go-zero/tools/goctl/util" @@ -60,32 +60,27 @@ func (g *Generator) genCallGroup(ctx DirContext, proto parser.Proto, cfg *conf.C childDir := filepath.Base(childPkg) filename := filepath.Join(dir.Filename, childDir, fmt.Sprintf("%s.go", callFilename)) - isCallPkgSameToPbPkg := childDir == ctx.GetProtoGo().Filename isCallPkgSameToGrpcPkg := childDir == ctx.GetProtoGo().Filename serviceName := stringx.From(service.Name).ToCamel() - alias := collection.NewSet[string]() var hasSameNameBetweenMessageAndService bool for _, item := range proto.Message { msgName := getMessageName(*item.Message) if serviceName == msgName { hasSameNameBetweenMessageAndService = true } - if !isCallPkgSameToPbPkg { - alias.Add(fmt.Sprintf("%s = %s", parser.CamelCase(msgName), - fmt.Sprintf("%s.%s", proto.PbPackage, parser.CamelCase(msgName)))) - } } + if hasSameNameBetweenMessageAndService { serviceName = stringx.From(service.Name + "_zrpc_client").ToCamel() } - functions, err := g.genFunction(proto.PbPackage, serviceName, service, isCallPkgSameToGrpcPkg) + functions, err := g.genFunction(proto, serviceName, service, isCallPkgSameToGrpcPkg) if err != nil { return err } - iFunctions, err := g.getInterfaceFuncs(proto.PbPackage, service, isCallPkgSameToGrpcPkg) + iFunctions, err := g.getInterfaceFuncs(proto, service, isCallPkgSameToGrpcPkg) if err != nil { return err } @@ -95,25 +90,20 @@ func (g *Generator) genCallGroup(ctx DirContext, proto parser.Proto, cfg *conf.C return err } - pbPackage := fmt.Sprintf(`"%s"`, ctx.GetPb().Package) - protoGoPackage := fmt.Sprintf(`"%s"`, ctx.GetProtoGo().Package) - if isCallPkgSameToGrpcPkg { - pbPackage = "" - protoGoPackage = "" + imports := collection.NewSet[string]() + workDir := ctx.GetMain() + for _, item := range proto.ImportMessageMap { + imports.Add(buildImportPackage(item.GoPackage, proto, workDir)) } - aliasKeys := alias.Keys() - sort.Strings(aliasKeys) if err = util.With("shared").GoFmt(true).Parse(text).SaveTo(map[string]any{ - "name": callFilename, - "alias": strings.Join(aliasKeys, pathx.NL), - "head": head, - "filePackage": childDir, - "pbPackage": pbPackage, - "protoGoPackage": protoGoPackage, - "serviceName": serviceName, - "functions": strings.Join(functions, pathx.NL), - "interface": strings.Join(iFunctions, pathx.NL), + "name": callFilename, + "head": head, + "filePackage": childDir, + "imports": strings.Join(imports.Keys(), pathx.NL), + "serviceName": serviceName, + "functions": strings.Join(functions, pathx.NL), + "interface": strings.Join(iFunctions, pathx.NL), }, filename, true); err != nil { return err } @@ -126,7 +116,6 @@ func (g *Generator) genCallInCompatibility(ctx DirContext, proto parser.Proto, dir := ctx.GetCall() service := proto.Service[0] head := util.GetHead(proto.Name) - isCallPkgSameToPbPkg := ctx.GetCall().Filename == ctx.GetPb().Filename isCallPkgSameToGrpcPkg := ctx.GetCall().Filename == ctx.GetProtoGo().Filename callFilename, err := format.FileNamingFormat(cfg.NamingFormat, service.Name) @@ -135,17 +124,12 @@ func (g *Generator) genCallInCompatibility(ctx DirContext, proto parser.Proto, } serviceName := stringx.From(service.Name).ToCamel() - alias := collection.NewSet[string]() var hasSameNameBetweenMessageAndService bool for _, item := range proto.Message { msgName := getMessageName(*item.Message) if serviceName == msgName { hasSameNameBetweenMessageAndService = true } - if !isCallPkgSameToPbPkg { - alias.Add(fmt.Sprintf("%s = %s", parser.CamelCase(msgName), - fmt.Sprintf("%s.%s", proto.PbPackage, parser.CamelCase(msgName)))) - } } if hasSameNameBetweenMessageAndService { @@ -153,12 +137,12 @@ func (g *Generator) genCallInCompatibility(ctx DirContext, proto parser.Proto, } filename := filepath.Join(dir.Filename, fmt.Sprintf("%s.go", callFilename)) - functions, err := g.genFunction(proto.PbPackage, serviceName, service, isCallPkgSameToGrpcPkg) + functions, err := g.genFunction(proto, serviceName, service, isCallPkgSameToGrpcPkg) if err != nil { return err } - iFunctions, err := g.getInterfaceFuncs(proto.PbPackage, service, isCallPkgSameToGrpcPkg) + iFunctions, err := g.getInterfaceFuncs(proto, service, isCallPkgSameToGrpcPkg) if err != nil { return err } @@ -168,24 +152,20 @@ func (g *Generator) genCallInCompatibility(ctx DirContext, proto parser.Proto, return err } - pbPackage := fmt.Sprintf(`"%s"`, ctx.GetPb().Package) - protoGoPackage := fmt.Sprintf(`"%s"`, ctx.GetProtoGo().Package) - if isCallPkgSameToGrpcPkg { - pbPackage = "" - protoGoPackage = "" + imports := collection.NewSet[string]() + workDir := ctx.GetMain() + for _, item := range proto.ImportMessageMap { + imports.Add(buildImportPackage(item.GoPackage, proto, workDir)) } - aliasKeys := alias.Keys() - sort.Strings(aliasKeys) + return util.With("shared").GoFmt(true).Parse(text).SaveTo(map[string]any{ - "name": callFilename, - "alias": strings.Join(aliasKeys, pathx.NL), - "head": head, - "filePackage": dir.Base, - "pbPackage": pbPackage, - "protoGoPackage": protoGoPackage, - "serviceName": serviceName, - "functions": strings.Join(functions, pathx.NL), - "interface": strings.Join(iFunctions, pathx.NL), + "name": callFilename, + "head": head, + "filePackage": dir.Base, + "imports": strings.Join(imports.Keys(), pathx.NL), + "serviceName": serviceName, + "functions": strings.Join(functions, pathx.NL), + "interface": strings.Join(iFunctions, pathx.NL), }, filename, true) } @@ -211,8 +191,9 @@ func getMessageName(msg proto.Message) string { return strings.Join(list, "_") } -func (g *Generator) genFunction(goPackage string, serviceName string, service parser.Service, +func (g *Generator) genFunction(proto parser.Proto, serviceName string, service parser.Service, isCallPkgSameToGrpcPkg bool) ([]string, error) { + goPackage := proto.PbPackage functions := make([]string, 0) for _, rpc := range service.RPC { @@ -228,13 +209,25 @@ func (g *Generator) genFunction(goPackage string, serviceName string, service pa streamServer = fmt.Sprintf("%s_%s%s", parser.CamelCase(service.Name), parser.CamelCase(rpc.Name), "Client") } + + requestMsg, existed := proto.GetImportMessage(rpc.RequestType) + if !existed { + err = fmt.Errorf("request type %s is invalid", rpc.RequestType) + return nil, err + } + responseMsg, existed := proto.GetImportMessage(rpc.ReturnsType) + if !existed { + err = fmt.Errorf("response type %s is invalid", rpc.ReturnsType) + return nil, err + } + buffer, err := util.With("sharedFn").Parse(text).Execute(map[string]any{ "serviceName": serviceName, "rpcServiceName": parser.CamelCase(service.Name), "method": parser.CamelCase(rpc.Name), "package": goPackage, - "pbRequest": parser.CamelCase(rpc.RequestType), - "pbResponse": parser.CamelCase(rpc.ReturnsType), + "pbRequest": buildPackageArg(requestMsg.PbPackage, requestMsg.Name, false), + "pbResponse": buildPackageArg(responseMsg.PbPackage, responseMsg.Name, false), "hasComment": len(comment) > 0, "comment": comment, "hasReq": !rpc.StreamsRequest, @@ -252,8 +245,9 @@ func (g *Generator) genFunction(goPackage string, serviceName string, service pa return functions, nil } -func (g *Generator) getInterfaceFuncs(goPackage string, service parser.Service, +func (g *Generator) getInterfaceFuncs(proto parser.Proto, service parser.Service, isCallPkgSameToGrpcPkg bool) ([]string, error) { + goPackage := proto.PbPackage functions := make([]string, 0) for _, rpc := range service.RPC { @@ -270,15 +264,27 @@ func (g *Generator) getInterfaceFuncs(goPackage string, service parser.Service, streamServer = fmt.Sprintf("%s_%s%s", parser.CamelCase(service.Name), parser.CamelCase(rpc.Name), "Client") } + + requestMsg, existed := proto.GetImportMessage(rpc.RequestType) + if !existed { + err = fmt.Errorf("request type %s is invalid", rpc.RequestType) + return nil, err + } + responseMsg, existed := proto.GetImportMessage(rpc.ReturnsType) + if !existed { + err = fmt.Errorf("response type %s is invalid", rpc.ReturnsType) + return nil, err + } + buffer, err := util.With("interfaceFn").Parse(text).Execute( map[string]any{ "hasComment": len(comment) > 0, "comment": comment, "method": parser.CamelCase(rpc.Name), "hasReq": !rpc.StreamsRequest, - "pbRequest": parser.CamelCase(rpc.RequestType), + "pbRequest": buildPackageArg(requestMsg.PbPackage, requestMsg.Name, false), "notStream": !rpc.StreamsRequest && !rpc.StreamsReturns, - "pbResponse": parser.CamelCase(rpc.ReturnsType), + "pbResponse": buildPackageArg(responseMsg.PbPackage, responseMsg.Name, false), "streamBody": streamServer, }) if err != nil { diff --git a/tools/goctl/rpc/generator/genetc.go b/tools/goctl/rpc/generator/genetc.go index 8729e76fa67c..3226df7709d7 100644 --- a/tools/goctl/rpc/generator/genetc.go +++ b/tools/goctl/rpc/generator/genetc.go @@ -19,9 +19,13 @@ var etcTemplate string // GenEtc generates the yaml configuration file of the rpc service, // including host, port monitoring configuration items and etcd configuration -func (g *Generator) GenEtc(ctx DirContext, _ parser.Proto, cfg *conf.Config) error { +func (g *Generator) GenEtc(ctx DirContext, _ parser.Proto, cfg *conf.Config, c *ZRpcContext) error { dir := ctx.GetEtc() - etcFilename, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source()) + serviceName := c.Name + if len(serviceName) == 0 { + serviceName = ctx.GetServiceName().Source() + } + etcFilename, err := format.FileNamingFormat(cfg.NamingFormat, serviceName) if err != nil { return err } @@ -34,6 +38,6 @@ func (g *Generator) GenEtc(ctx DirContext, _ parser.Proto, cfg *conf.Config) err } return util.With("etc").Parse(text).SaveTo(map[string]any{ - "serviceName": strings.ToLower(stringx.From(ctx.GetServiceName().Source()).ToCamel()), + "serviceName": strings.ToLower(stringx.From(serviceName).ToCamel()), }, fileName, false) } diff --git a/tools/goctl/rpc/generator/genlogic.go b/tools/goctl/rpc/generator/genlogic.go index 4a51d4fb7340..e52ad559f730 100644 --- a/tools/goctl/rpc/generator/genlogic.go +++ b/tools/goctl/rpc/generator/genlogic.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/zeromicro/go-zero/core/collection" + conf "github.com/zeromicro/go-zero/tools/goctl/config" "github.com/zeromicro/go-zero/tools/goctl/rpc/parser" "github.com/zeromicro/go-zero/tools/goctl/util" @@ -39,7 +40,7 @@ func (g *Generator) GenLogic(ctx DirContext, proto parser.Proto, cfg *conf.Confi func (g *Generator) genLogicInCompatibility(ctx DirContext, proto parser.Proto, cfg *conf.Config) error { dir := ctx.GetLogic() - service := proto.Service[0].Service.Name + // service := proto.Service[0].Service.Name for _, rpc := range proto.Service[0].RPC { logicName := fmt.Sprintf("%sLogic", stringx.From(rpc.Name).ToCamel()) logicFilename, err := format.FileNamingFormat(cfg.NamingFormat, rpc.Name+"_logic") @@ -48,14 +49,18 @@ func (g *Generator) genLogicInCompatibility(ctx DirContext, proto parser.Proto, } filename := filepath.Join(dir.Filename, logicFilename+".go") - functions, err := g.genLogicFunction(service, proto.PbPackage, logicName, rpc) + functions, err := g.genLogicFunction(proto, logicName, rpc) if err != nil { return err } imports := collection.NewSet[string]() imports.Add(fmt.Sprintf(`"%v"`, ctx.GetSvc().Package)) - imports.Add(fmt.Sprintf(`"%v"`, ctx.GetPb().Package)) + funcImports, err := getImports(ctx, proto, rpc) + if err != nil { + return err + } + imports.Add(funcImports...) text, err := pathx.LoadTemplate(category, logicTemplateFileFile, logicTemplate) if err != nil { return err @@ -101,14 +106,18 @@ func (g *Generator) genLogicGroup(ctx DirContext, proto parser.Proto, cfg *conf. } filename = filepath.Join(dir.Filename, serviceDir, logicFilename+".go") - functions, err := g.genLogicFunction(serviceName, proto.PbPackage, logicName, rpc) + functions, err := g.genLogicFunction(proto, logicName, rpc) if err != nil { return err } imports := collection.NewSet[string]() imports.Add(fmt.Sprintf(`"%v"`, ctx.GetSvc().Package)) - imports.Add(fmt.Sprintf(`"%v"`, ctx.GetPb().Package)) + funcImports, err := getImports(ctx, proto, rpc) + if err != nil { + return err + } + imports.Add(funcImports...) text, err := pathx.LoadTemplate(category, logicTemplateFileFile, logicTemplate) if err != nil { return err @@ -127,9 +136,9 @@ func (g *Generator) genLogicGroup(ctx DirContext, proto parser.Proto, cfg *conf. return nil } -func (g *Generator) genLogicFunction(serviceName, goPackage, logicName string, - rpc *parser.RPC) (string, - error) { +func (g *Generator) genLogicFunction(proto parser.Proto, logicName string, rpc *parser.RPC) (string, error) { + serviceName := proto.Service[0].Service.Name + goPackage := proto.PbPackage functions := make([]string, 0) text, err := pathx.LoadTemplate(category, logicFuncTemplateFileFile, logicFunctionTemplate) if err != nil { @@ -137,16 +146,26 @@ func (g *Generator) genLogicFunction(serviceName, goPackage, logicName string, } comment := parser.GetComment(rpc.Doc()) - streamServer := fmt.Sprintf("%s.%s_%s%s", goPackage, parser.CamelCase(serviceName), - parser.CamelCase(rpc.Name), "Server") + requestMsg, existed := proto.GetImportMessage(rpc.RequestType) + if !existed { + err = fmt.Errorf("request type %s is invalid", rpc.RequestType) + return "", err + } + responseMsg, existed := proto.GetImportMessage(rpc.ReturnsType) + if !existed { + err = fmt.Errorf("response type %s is invalid", rpc.ReturnsType) + return "", err + } + + streamServer := buildPackageArg(goPackage, fmt.Sprintf("%s_%s%s", parser.CamelCase(serviceName), parser.CamelCase(rpc.Name), "Server"), false) buffer, err := util.With("fun").Parse(text).Execute(map[string]any{ "logicName": logicName, "method": parser.CamelCase(rpc.Name), "hasReq": !rpc.StreamsRequest, - "request": fmt.Sprintf("*%s.%s", goPackage, parser.CamelCase(rpc.RequestType)), + "request": buildPackageArg(requestMsg.PbPackage, requestMsg.Name, true), "hasReply": !rpc.StreamsRequest && !rpc.StreamsReturns, - "response": fmt.Sprintf("*%s.%s", goPackage, parser.CamelCase(rpc.ReturnsType)), - "responseType": fmt.Sprintf("%s.%s", goPackage, parser.CamelCase(rpc.ReturnsType)), + "response": buildPackageArg(responseMsg.PbPackage, responseMsg.Name, true), + "responseType": buildPackageArg(responseMsg.PbPackage, responseMsg.Name, false), "stream": rpc.StreamsRequest || rpc.StreamsReturns, "streamBody": streamServer, "hasComment": len(comment) > 0, @@ -159,3 +178,47 @@ func (g *Generator) genLogicFunction(serviceName, goPackage, logicName string, functions = append(functions, buffer.String()) return strings.Join(functions, pathx.NL), nil } + +func getImports(ctx DirContext, proto parser.Proto, rpc *parser.RPC) ([]string, error) { + var err error + requestMsg, existed := proto.GetImportMessage(rpc.RequestType) + if !existed { + err = fmt.Errorf("request type %s is invalid", rpc.RequestType) + return nil, err + } + responseMsg, existed := proto.GetImportMessage(rpc.ReturnsType) + if !existed { + err = fmt.Errorf("response type %s is invalid", rpc.ReturnsType) + return nil, err + } + workDir := ctx.GetMain() + imports := collection.NewSet[string]() + imports.Add(buildImportPackage(requestMsg.GoPackage, proto, workDir)) + // has reply + if !rpc.StreamsRequest && !rpc.StreamsReturns { + imports.Add(buildImportPackage(responseMsg.GoPackage, proto, workDir)) + } + return imports.Keys(), nil +} + +func buildPackageArg(goPackage string, arg string, isPtr bool) string { + if strings.Contains(arg, ".") { + arg = fmt.Sprintf("%s", arg) + } else { + arg = fmt.Sprintf("%s.%s", goPackage, parser.CamelCase(arg)) + } + + if isPtr { + arg = fmt.Sprintf("*%s", arg) + } + + return arg +} + +func buildImportPackage(importPackage string, proto parser.Proto, workDir Dir) string { + if strings.HasPrefix(importPackage, "./") { + importPackage = filepath.ToSlash(filepath.Join(workDir.Package, strings.TrimPrefix(proto.Src, workDir.Filename))) + importPackage = strings.TrimSuffix(importPackage, ".proto") + } + return fmt.Sprintf(`"%s"`, importPackage) +} diff --git a/tools/goctl/rpc/generator/genmain.go b/tools/goctl/rpc/generator/genmain.go index e0d0849acb02..037869668a22 100644 --- a/tools/goctl/rpc/generator/genmain.go +++ b/tools/goctl/rpc/generator/genmain.go @@ -27,7 +27,11 @@ type MainServiceTemplateData struct { // GenMain generates the main file of the rpc service, which is an rpc service program call entry func (g *Generator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config, c *ZRpcContext) error { - mainFilename, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source()) + serviceName := c.Name + if len(serviceName) == 0 { + serviceName = ctx.GetServiceName().Source() + } + mainFilename, err := format.FileNamingFormat(cfg.NamingFormat, serviceName) if err != nil { return err } @@ -71,7 +75,7 @@ func (g *Generator) GenMain(ctx DirContext, proto parser.Proto, cfg *conf.Config return err } - etcFileName, err := format.FileNamingFormat(cfg.NamingFormat, ctx.GetServiceName().Source()) + etcFileName, err := format.FileNamingFormat(cfg.NamingFormat, serviceName) if err != nil { return err } diff --git a/tools/goctl/rpc/generator/genpb.go b/tools/goctl/rpc/generator/genpb.go index ceb50fd9ddb3..593426abf163 100644 --- a/tools/goctl/rpc/generator/genpb.go +++ b/tools/goctl/rpc/generator/genpb.go @@ -14,11 +14,11 @@ import ( // 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 *Generator) GenPb(ctx DirContext, c *ZRpcContext) error { - return g.genPbDirect(ctx, c) +func (g *Generator) GenPb(ctx DirContext, c *ZRpcContext, srcIndex int, hasService bool) error { + return g.genPbDirect(ctx, c, srcIndex, hasService) } -func (g *Generator) genPbDirect(ctx DirContext, c *ZRpcContext) error { +func (g *Generator) genPbDirect(ctx DirContext, c *ZRpcContext, srcIndex int, hasService bool) error { g.log.Debug("[command]: %s", c.ProtocCmd) pwd, err := os.Getwd() if err != nil { @@ -29,28 +29,32 @@ func (g *Generator) genPbDirect(ctx DirContext, c *ZRpcContext) error { if err != nil { return err } - return g.setPbDir(ctx, c) + return g.setPbDir(ctx, c, srcIndex, hasService) } -func (g *Generator) setPbDir(ctx DirContext, c *ZRpcContext) error { - pbDir, err := findPbFile(c.GoOutput, c.Src, false) +func (g *Generator) setPbDir(ctx DirContext, c *ZRpcContext, srcIndex int, hasService bool) error { + var grpcDir string + pbDir, err := findPbFile(c.GoOutput, c.Src[srcIndex], false) if err != nil { return err } if len(pbDir) == 0 { return fmt.Errorf("pg.go is not found under %q", c.GoOutput) } - grpcDir, err := findPbFile(c.GrpcOutput, c.Src, true) - if err != nil { - return err - } - if len(grpcDir) == 0 { - return fmt.Errorf("_grpc.pb.go is not found in %q", c.GrpcOutput) - } - if pbDir != grpcDir { - return fmt.Errorf("the pb.go and _grpc.pb.go must under the same dir: "+ - "\n pb.go: %s\n_grpc.pb.go: %s", pbDir, grpcDir) + if hasService { + grpcDir, err = findPbFile(c.GrpcOutput, c.Src[srcIndex], true) + if err != nil { + return err + } + if len(grpcDir) == 0 { + return fmt.Errorf("_grpc.pb.go is not found in %q", c.GrpcOutput) + } + if pbDir != grpcDir { + return fmt.Errorf("the pb.go and _grpc.pb.go must under the same dir: "+ + "\n pb.go: %s\n_grpc.pb.go: %s", pbDir, grpcDir) + } } + if pbDir == c.Output { return fmt.Errorf("the output of pb.go and _grpc.pb.go must not be the same "+ "with --zrpc_out:\npb output: %s\nzrpc out: %s", pbDir, c.Output) diff --git a/tools/goctl/rpc/generator/genserver.go b/tools/goctl/rpc/generator/genserver.go index c24b11426633..d1f6928f7fd8 100644 --- a/tools/goctl/rpc/generator/genserver.go +++ b/tools/goctl/rpc/generator/genserver.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/zeromicro/go-zero/core/collection" + conf "github.com/zeromicro/go-zero/tools/goctl/config" "github.com/zeromicro/go-zero/tools/goctl/rpc/parser" "github.com/zeromicro/go-zero/tools/goctl/util" @@ -69,9 +70,17 @@ func (g *Generator) genServerGroup(ctx DirContext, proto parser.Proto, cfg *conf imports := collection.NewSet[string]() imports.Add(logicImport, svcImport, pbImport) + for _, rpc := range service.RPC { + funcImports, err := getImports(ctx, proto, rpc) + if err != nil { + return err + } + imports.Add(funcImports...) + } + head := util.GetHead(proto.Name) - funcList, err := g.genFunctions(proto.PbPackage, service, true) + funcList, err := g.genFunctions(proto.PbPackage, service, proto, true) if err != nil { return err } @@ -114,6 +123,14 @@ func (g *Generator) genServerInCompatibility(ctx DirContext, proto parser.Proto, imports := collection.NewSet[string]() imports.Add(logicImport, svcImport, pbImport) + for _, rpc := range proto.Service[0].RPC { + funcImports, err := getImports(ctx, proto, rpc) + if err != nil { + return err + } + imports.Add(funcImports...) + } + head := util.GetHead(proto.Name) service := proto.Service[0] serverFilename, err := format.FileNamingFormat(cfg.NamingFormat, service.Name+"_server") @@ -122,7 +139,7 @@ func (g *Generator) genServerInCompatibility(ctx DirContext, proto parser.Proto, } serverFile := filepath.Join(dir.Filename, serverFilename+".go") - funcList, err := g.genFunctions(proto.PbPackage, service, false) + funcList, err := g.genFunctions(proto.PbPackage, service, proto, false) if err != nil { return err } @@ -151,7 +168,7 @@ func (g *Generator) genServerInCompatibility(ctx DirContext, proto parser.Proto, }, serverFile, true) } -func (g *Generator) genFunctions(goPackage string, service parser.Service, multiple bool) ([]string, error) { +func (g *Generator) genFunctions(goPackage string, service parser.Service, proto parser.Proto, multiple bool) ([]string, error) { var ( functionList []string logicPkg string @@ -173,14 +190,25 @@ func (g *Generator) genFunctions(goPackage string, service parser.Service, multi } comment := parser.GetComment(rpc.Doc()) - streamServer := fmt.Sprintf("%s.%s_%s%s", goPackage, parser.CamelCase(service.Name), - parser.CamelCase(rpc.Name), "Server") + requestMsg, existed := proto.GetImportMessage(rpc.RequestType) + if !existed { + err = fmt.Errorf("request type %s is invalid", rpc.RequestType) + return nil, err + } + responseMsg, existed := proto.GetImportMessage(rpc.ReturnsType) + if !existed { + err = fmt.Errorf("response type %s is invalid", rpc.ReturnsType) + return nil, err + } + // streamServer := fmt.Sprintf("%s.%s_%s%s", goPackage, parser.CamelCase(service.Name), + // parser.CamelCase(rpc.Name), "Server") + streamServer := buildPackageArg(goPackage, fmt.Sprintf("%s_%s%s", parser.CamelCase(service.Name), parser.CamelCase(rpc.Name), "Server"), false) buffer, err := util.With("func").Parse(text).Execute(map[string]any{ "server": stringx.From(service.Name).ToCamel(), "logicName": logicName, "method": parser.CamelCase(rpc.Name), - "request": fmt.Sprintf("*%s.%s", goPackage, parser.CamelCase(rpc.RequestType)), - "response": fmt.Sprintf("*%s.%s", goPackage, parser.CamelCase(rpc.ReturnsType)), + "request": buildPackageArg(requestMsg.PbPackage, requestMsg.Name, true), + "response": buildPackageArg(responseMsg.PbPackage, responseMsg.Name, true), "hasComment": len(comment) > 0, "comment": comment, "hasReq": !rpc.StreamsRequest, diff --git a/tools/goctl/rpc/parser/common/common.proto b/tools/goctl/rpc/parser/common/common.proto new file mode 100644 index 000000000000..1ab6972ec6fa --- /dev/null +++ b/tools/goctl/rpc/parser/common/common.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package common; +option go_package = "github/go-zero/common"; + +message CommonMessage{ + string name = 1; +} + diff --git a/tools/goctl/rpc/parser/import.go b/tools/goctl/rpc/parser/import.go index bb9591f56949..baaa242ca2ea 100644 --- a/tools/goctl/rpc/parser/import.go +++ b/tools/goctl/rpc/parser/import.go @@ -5,4 +5,5 @@ import "github.com/emicklei/proto" // Import embeds proto.Import type Import struct { *proto.Import + Proto Proto } diff --git a/tools/goctl/rpc/parser/parser.go b/tools/goctl/rpc/parser/parser.go index ad50009009d2..aee69fb50acb 100644 --- a/tools/goctl/rpc/parser/parser.go +++ b/tools/goctl/rpc/parser/parser.go @@ -4,12 +4,15 @@ import ( "errors" "go/token" "os" + "path" "path/filepath" "strings" "unicode" "unicode/utf8" "github.com/emicklei/proto" + + "github.com/zeromicro/go-zero/tools/goctl/util/pathx" ) type ( @@ -24,9 +27,22 @@ func NewDefaultProtoParser() *DefaultProtoParser { return &DefaultProtoParser{} } +func (p *DefaultProtoParser) ParseAll(sources []string, protoPath []string, multiple ...bool) ([]Proto, error) { + var protos []Proto + for _, source := range sources { + parsed, err := p.Parse(source, protoPath, multiple...) + if err != nil { + return nil, err + } + protos = append(protos, parsed) + } + return protos, nil + +} + // 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, multiple ...bool) (Proto, error) { +func (p *DefaultProtoParser) Parse(src string, protoPath []string, multiple ...bool) (Proto, error) { var ret Proto abs, err := filepath.Abs(src) @@ -50,7 +66,11 @@ func (p *DefaultProtoParser) Parse(src string, multiple ...bool) (Proto, error) proto.Walk( set, proto.WithImport(func(i *proto.Import) { - ret.Import = append(ret.Import, Import{Import: i}) + importProto := Import{ + Import: i, + Proto: p.parseImportProto(i.Filename, protoPath, multiple...), + } + ret.Import = append(ret.Import, importProto) }), proto.WithMessage(func(message *proto.Message) { ret.Message = append(ret.Message, Message{Message: message}) @@ -73,10 +93,13 @@ func (p *DefaultProtoParser) Parse(src string, multiple ...bool) (Proto, error) }), proto.WithOption(func(option *proto.Option) { if option.Name == "go_package" { - ret.GoPackage = option.Constant.Source + goPackage := option.Constant.Source + goPackageArr := strings.Split(goPackage, ";") + ret.GoPackage = goPackageArr[0] } }), ) + if err = serviceList.validate(abs, multiple...); err != nil { return ret, err } @@ -92,10 +115,28 @@ func (p *DefaultProtoParser) Parse(src string, multiple ...bool) (Proto, error) ret.Src = abs ret.Name = filepath.Base(abs) ret.Service = serviceList + ret.generateImportMessageMap() return ret, nil } +// parseImportProto provides to parse the import proto file +func (p *DefaultProtoParser) parseImportProto(importFileName string, protoPath []string, multiple ...bool) Proto { + var importProto Proto + var err error + for index := range protoPath { + protoFilePath := path.Join(protoPath[index], importFileName) + if !pathx.FileExists(protoFilePath) { + continue + } + importProto, err = p.Parse(protoFilePath, protoPath, multiple...) + if err == nil { + break + } + } + return importProto +} + // 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, diff --git a/tools/goctl/rpc/parser/parser_test.go b/tools/goctl/rpc/parser/parser_test.go index 4375b0599530..fda037173f8a 100644 --- a/tools/goctl/rpc/parser/parser_test.go +++ b/tools/goctl/rpc/parser/parser_test.go @@ -10,7 +10,7 @@ import ( func TestDefaultProtoParse(t *testing.T) { p := NewDefaultProtoParser() - data, err := p.Parse("./test.proto") + data, err := p.Parse("./test.proto", nil) assert.Nil(t, err) assert.Equal(t, "base.proto", func() string { ip := data.Import[0] @@ -46,7 +46,7 @@ func TestDefaultProtoParse(t *testing.T) { func TestDefaultProtoParseCaseInvalidRequestType(t *testing.T) { p := NewDefaultProtoParser() - _, err := p.Parse("./test_invalid_request.proto") + _, err := p.Parse("./test_invalid_request.proto", nil) assert.True(t, true, func() bool { return strings.Contains(err.Error(), "request type must defined in") }()) @@ -54,7 +54,7 @@ func TestDefaultProtoParseCaseInvalidRequestType(t *testing.T) { func TestDefaultProtoParseCaseInvalidResponseType(t *testing.T) { p := NewDefaultProtoParser() - _, err := p.Parse("./test_invalid_response.proto") + _, err := p.Parse("./test_invalid_response.proto", nil) assert.True(t, true, func() bool { return strings.Contains(err.Error(), "response type must defined in") }()) @@ -62,13 +62,13 @@ func TestDefaultProtoParseCaseInvalidResponseType(t *testing.T) { func TestDefaultProtoParseError(t *testing.T) { p := NewDefaultProtoParser() - _, err := p.Parse("./nil.proto") + _, err := p.Parse("./nil.proto", nil) assert.NotNil(t, err) } func TestDefaultProtoParse_Option(t *testing.T) { p := NewDefaultProtoParser() - data, err := p.Parse("./test_option.proto") + data, err := p.Parse("./test_option.proto", nil) assert.Nil(t, err) assert.Equal(t, "github.com/zeromicro/go-zero", data.GoPackage) assert.Equal(t, "go_zero", data.PbPackage) @@ -76,8 +76,16 @@ func TestDefaultProtoParse_Option(t *testing.T) { func TestDefaultProtoParse_Option2(t *testing.T) { p := NewDefaultProtoParser() - data, err := p.Parse("./test_option2.proto") + data, err := p.Parse("./test_option2.proto", nil) assert.Nil(t, err) assert.Equal(t, "stream", data.GoPackage) assert.Equal(t, "stream", data.PbPackage) } + +func TestDefaultProtoParse_import(t *testing.T) { + p := NewDefaultProtoParser() + data, err := p.Parse("./test_import.proto", []string{"./"}) + assert.Nil(t, err) + assert.NotNil(t, data.ImportMessageMap) + assert.Equal(t, 2, len(data.ImportMessageMap)) +} diff --git a/tools/goctl/rpc/parser/proto.go b/tools/goctl/rpc/parser/proto.go index a08137bffd1d..1a5fe760475c 100644 --- a/tools/goctl/rpc/parser/proto.go +++ b/tools/goctl/rpc/parser/proto.go @@ -1,13 +1,67 @@ package parser -// Proto describes a proto file, -type Proto struct { - Src string +import "fmt" + +type PbMessage struct { Name string - Package Package + Package string PbPackage string GoPackage string - Import []Import - Message []Message - Service Services +} + +// Proto describes a proto file, +type Proto struct { + Src string + Name string + Package Package + PbPackage string + GoPackage string + Import []Import + Message []Message + Service Services + ImportMessageMap map[string]PbMessage +} + +func (p *Proto) generateImportMessageMap() { + if p.ImportMessageMap == nil { + p.ImportMessageMap = make(map[string]PbMessage) + } + for _, message := range p.Message { + p.ImportMessageMap[message.Name] = PbMessage{ + Name: CamelCase(message.Name), + Package: p.Package.Package.Name, + PbPackage: p.PbPackage, + GoPackage: p.GoPackage, + } + } + for _, importFile := range p.Import { + for _, message := range importFile.Proto.Message { + key := fmt.Sprintf("%s.%s", importFile.Proto.Package.Package.Name, CamelCase(message.Name)) + p.ImportMessageMap[key] = PbMessage{ + Name: CamelCase(message.Name), + Package: importFile.Proto.Package.Package.Name, + PbPackage: importFile.Proto.PbPackage, + GoPackage: importFile.Proto.GoPackage, + } + } + } +} + +func (p *Proto) GetImportMessage(key string) (PbMessage, bool) { + msg, existed := p.ImportMessageMap[key] + return msg, existed +} + +func (p *Proto) HasGrpcService() bool { + var hasGrpcService bool + if p == nil { + return hasGrpcService + } + for _, service := range p.Service { + if len(service.RPC) > 0 { + hasGrpcService = true + break + } + } + return hasGrpcService } diff --git a/tools/goctl/rpc/parser/proto_test.go b/tools/goctl/rpc/parser/proto_test.go new file mode 100644 index 000000000000..f5a93541dec9 --- /dev/null +++ b/tools/goctl/rpc/parser/proto_test.go @@ -0,0 +1,39 @@ +package parser + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// TestProto_GetImportMessage tests the functionality of retrieving imported messages from a proto file. +// It verifies that: +// 1. The proto parser can successfully parse a proto file with imports +// 2. The GetImportMessage method can correctly locate and return imported message information +// 3. The returned message contains accurate metadata including name, package, and go package path +// The test uses a test proto file located at "./test_import.proto" with import paths set to "./" +func TestProto_GetImportMessage(t *testing.T) { + p := NewDefaultProtoParser() + data, err := p.Parse("./test_import.proto", []string{"./"}) + assert.Nil(t, err) + pbMsg, existed := data.GetImportMessage("common.CommonMessage") + assert.Equal(t, true, existed) + assert.Equal(t, "CommonMessage", pbMsg.Name) + assert.Equal(t, "common", pbMsg.Package) + assert.Equal(t, "common", pbMsg.PbPackage) + assert.Equal(t, "github/go-zero/common", pbMsg.GoPackage) +} + +func TestProto_HasGrpcService(t *testing.T) { + p := NewDefaultProtoParser() + data, err := p.Parse("./test_import.proto", []string{"./"}) + assert.Nil(t, err) + assert.Equal(t, true, data.HasGrpcService()) +} + +func TestProto_HasGrpcService2(t *testing.T) { + p := NewDefaultProtoParser() + data, err := p.Parse("./common/common.proto", nil) + assert.Nil(t, err) + assert.Equal(t, false, data.HasGrpcService()) +} diff --git a/tools/goctl/rpc/parser/service.go b/tools/goctl/rpc/parser/service.go index b060e2fd341f..a2954aa8fdd6 100644 --- a/tools/goctl/rpc/parser/service.go +++ b/tools/goctl/rpc/parser/service.go @@ -2,9 +2,6 @@ package parser import ( "errors" - "fmt" - "path/filepath" - "strings" "github.com/emicklei/proto" ) @@ -23,7 +20,10 @@ type ( func (s Services) validate(filename string, multipleOpt ...bool) error { if len(s) == 0 { - return errors.New("rpc service not found") + // return errors.New("rpc service not found") + + // message only proto file, no service defined + return nil } var multiple bool @@ -34,21 +34,5 @@ func (s Services) validate(filename string, multipleOpt ...bool) error { if !multiple && len(s) > 1 { return errors.New("only one service expected") } - - name := filepath.Base(filename) - for _, service := range s { - for _, rpc := range service.RPC { - if strings.Contains(rpc.RequestType, ".") { - return fmt.Errorf("line %v:%v, request type must defined in %s", - rpc.Position.Line, - rpc.Position.Column, name) - } - if strings.Contains(rpc.ReturnsType, ".") { - return fmt.Errorf("line %v:%v, returns type must defined in %s", - rpc.Position.Line, - rpc.Position.Column, name) - } - } - } return nil } diff --git a/tools/goctl/rpc/parser/test_import.proto b/tools/goctl/rpc/parser/test_import.proto new file mode 100644 index 000000000000..f12a653f9268 --- /dev/null +++ b/tools/goctl/rpc/parser/test_import.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package stream; + +import "common/common.proto"; + +message placeholder {} + +service greet { + rpc hello (placeholder) returns (common.CommonMessage); +} \ No newline at end of file