diff --git a/pkg/ast/provider/provider.go b/pkg/ast/provider/provider.go index 1740438..eee20ea 100644 --- a/pkg/ast/provider/provider.go +++ b/pkg/ast/provider/provider.go @@ -163,45 +163,6 @@ func Parse(source string) []Provider { provider.ReturnType = "*" + provider.StructName } - if providerDoc.Mode == "event" { - provider.Mode = "event" - - modePkg := gomod.GetModuleName() + "/providers/events" - - provider.Imports["git.ipao.vip/rogeecn/atom/contracts"] = "" - provider.Imports[modePkg] = "" - - provider.ProviderGroup = "atom.GroupInitial" - provider.ReturnType = "contracts.Initial" - - provider.InjectParams["__event"] = InjectParam{ - Star: "*", - Type: "PubSub", - Package: modePkg, - PackageAlias: "events", - } - } - - if providerDoc.Mode == "job" { - provider.Mode = "job" - - modePkg := gomod.GetModuleName() + "/providers/job" - - provider.Imports["git.ipao.vip/rogeecn/atom/contracts"] = "" - provider.Imports["github.com/riverqueue/river"] = "" - provider.Imports[modePkg] = "" - - provider.ProviderGroup = "atom.GroupInitial" - provider.ReturnType = "contracts.Initial" - - provider.InjectParams["__job"] = InjectParam{ - Star: "*", - Type: "Job", - Package: modePkg, - PackageAlias: "job", - } - } - for _, field := range structType.Fields.List { if field.Names == nil { continue @@ -289,6 +250,64 @@ func Parse(source string) []Provider { provider.PkgName = node.Name.Name provider.ProviderFile = filepath.Join(filepath.Dir(source), "provider.gen.go") + if providerDoc.Mode == "grpc" { + provider.Mode = "grpc" + + modePkg := gomod.GetModuleName() + "/providers/grpc" + + provider.Imports["git.ipao.vip/rogeecn/atom/contracts"] = "" + provider.Imports[modePkg] = "" + + provider.ProviderGroup = "atom.GroupInitial" + provider.ReturnType = "contracts.Initial" + + provider.InjectParams["__grpc"] = InjectParam{ + Star: "*", + Type: "Grpc", + Package: modePkg, + PackageAlias: "grpc", + } + } + + if providerDoc.Mode == "event" { + provider.Mode = "event" + + modePkg := gomod.GetModuleName() + "/providers/events" + + provider.Imports["git.ipao.vip/rogeecn/atom/contracts"] = "" + provider.Imports[modePkg] = "" + + provider.ProviderGroup = "atom.GroupInitial" + provider.ReturnType = "contracts.Initial" + + provider.InjectParams["__event"] = InjectParam{ + Star: "*", + Type: "PubSub", + Package: modePkg, + PackageAlias: "events", + } + } + + if providerDoc.Mode == "job" { + provider.Mode = "job" + + modePkg := gomod.GetModuleName() + "/providers/job" + + provider.Imports["git.ipao.vip/rogeecn/atom/contracts"] = "" + provider.Imports["github.com/riverqueue/river"] = "" + provider.Imports[modePkg] = "" + + provider.ProviderGroup = "atom.GroupInitial" + provider.ReturnType = "contracts.Initial" + + provider.InjectParams["__job"] = InjectParam{ + Star: "*", + Type: "Job", + Package: modePkg, + PackageAlias: "job", + } + } + providers = append(providers, provider) } diff --git a/pkg/ast/provider/provider.go.tpl b/pkg/ast/provider/provider.go.tpl index fa81884..99ad9ac 100644 --- a/pkg/ast/provider/provider.go.tpl +++ b/pkg/ast/provider/provider.go.tpl @@ -19,7 +19,7 @@ func Provide(opts ...opt.Option) error { ) ({{.ReturnType}}, error) { obj := &{{.StructName}}{ {{- range $key, $param := .InjectParams }} - {{- if and (ne $key "__job") (ne $key "__event")}} + {{- if and (ne $key "__job") (ne $key "__event") (ne $key "__grpc")}} {{$key}}: {{$key}}, {{- end}} {{- end }} @@ -30,6 +30,10 @@ func Provide(opts ...opt.Option) error { } {{- end }} + {{- if eq .Mode "grpc"}} + userv1.RegisterUserServiceServer(__grpc.Server, obj) + {{- end }} + {{- if eq .Mode "event"}} __event.Handle("handler:{{.StructName}}", obj.Topic(), obj.PublishToTopic(), obj.Handler) {{- end }} @@ -39,6 +43,7 @@ func Provide(opts ...opt.Option) error { return nil, err } {{- end }} + return obj, nil }{{if .ProviderGroup}}, {{.ProviderGroup}}{{end}}); err != nil { return err diff --git a/templates/project/Makefile.tpl b/templates/project/Makefile.tpl index 3704707..fcf4513 100755 --- a/templates/project/Makefile.tpl +++ b/templates/project/Makefile.tpl @@ -22,3 +22,12 @@ test: .PHONY: lint lint: @golangci-lint run + +.PHONY: init +init: + go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway + go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 + go install google.golang.org/protobuf/cmd/protoc-gen-go + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc + go install github.com/bufbuild/buf/cmd/buf + go install github.com/golangci/golangci-lint/cmd/golangci-lint diff --git a/templates/project/app/service/grpc/grpc.go.tpl b/templates/project/app/service/grpc/grpc.go.tpl new file mode 100644 index 0000000..1e450ef --- /dev/null +++ b/templates/project/app/service/grpc/grpc.go.tpl @@ -0,0 +1,58 @@ +package grpc + +import ( + "qq/app/grpc/users" + "qq/app/service" + _ "qq/docs" + "qq/providers/app" + "qq/providers/grpc" + "qq/providers/postgres" + + "git.ipao.vip/rogeecn/atom" + "git.ipao.vip/rogeecn/atom/container" + "git.ipao.vip/rogeecn/atom/contracts" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "go.uber.org/dig" +) + +func defaultProviders() container.Providers { + return service.Default(container.Providers{ + postgres.DefaultProvider(), + grpc.DefaultProvider(), + }...) +} + +func Command() atom.Option { + return atom.Command( + atom.Name("grpc"), + atom.Short("run grpc server"), + atom.RunE(Serve), + atom.Providers( + defaultProviders(). + With( + users.Provide, + ), + ), + ) +} + +type Service struct { + dig.In + + App *app.Config + Grpc *grpc.Grpc + Initials []contracts.Initial `group:"initials"` +} + +func Serve(cmd *cobra.Command, args []string) error { + return container.Container.Invoke(func(svc Service) error { + log.SetFormatter(&log.JSONFormatter{}) + + if svc.App.IsDevMode() { + log.SetLevel(log.DebugLevel) + } + + return svc.Grpc.Serve() + }) +} diff --git a/templates/project/buf.gen.yaml.tpl b/templates/project/buf.gen.yaml.tpl index 5e442b7..3f96699 100644 --- a/templates/project/buf.gen.yaml.tpl +++ b/templates/project/buf.gen.yaml.tpl @@ -1,4 +1,6 @@ version: v2 +inputs: + - directory: proto managed: enabled: true override: @@ -6,24 +8,16 @@ managed: value: {{.ModuleName}}/pkg/proto plugins: - - remote: buf.build/protocolbuffers/go - out: gen/go + - local: protoc-gen-go + out: pkg/proto opt: paths=source_relative - - remote: buf.build/grpc/go - out: gen/go - opt: paths=source_relative,require_unimplemented_servers=false - - remote: buf.build/grpc-ecosystem/gateway - out: gen/go + - local: protoc-gen-grpc-gateway + out: pkg/proto + opt: + - paths=source_relative + - generate_unbound_methods=true + - local: protoc-gen-go-grpc + out: pkg/proto opt: paths=source_relative - # languages - - remote: buf.build/protocolbuffers/js - out: gen/js - - remote: buf.build/protocolbuffers/php - out: gen/php - # generate openapi documentation for api - - remote: buf.build/grpc-ecosystem/openapiv2 - out: gen/openapiv2 - opt: allow_merge=true,merge_file_name=services - -inputs: - - directory: proto + # - local: protoc-gen-openapiv2 + # out: docs/proto diff --git a/templates/project/buf.yaml.tpl b/templates/project/buf.yaml.tpl index 53da97a..06039af 100644 --- a/templates/project/buf.yaml.tpl +++ b/templates/project/buf.yaml.tpl @@ -8,3 +8,6 @@ lint: breaking: use: - FILE +deps: + - buf.build/googleapis/googleapis + - buf.build/grpc-ecosystem/grpc-gateway diff --git a/templates/project/providers/grpc/config.go.tpl b/templates/project/providers/grpc/config.go.tpl new file mode 100644 index 0000000..fbd1be4 --- /dev/null +++ b/templates/project/providers/grpc/config.go.tpl @@ -0,0 +1,48 @@ +package grpc + +import ( + "fmt" + "net" + + "git.ipao.vip/rogeecn/atom/container" + "git.ipao.vip/rogeecn/atom/utils/opt" + "google.golang.org/grpc" +) + +const DefaultPrefix = "Grpc" + +func DefaultProvider() container.ProviderContainer { + return container.ProviderContainer{ + Provider: Provide, + Options: []opt.Option{ + opt.Prefix(DefaultPrefix), + }, + } +} + +type Config struct { + Host *string + Port uint +} + +func (h *Config) Address() string { + if h.Host == nil { + return fmt.Sprintf(":%d", h.Port) + } + return fmt.Sprintf("%s:%d", *h.Host, h.Port) +} + +type Grpc struct { + Server *grpc.Server + config *Config +} + +// Serve +func (g *Grpc) Serve() error { + l, err := net.Listen("tcp", g.config.Address()) + if err != nil { + return err + } + + return g.Server.Serve(l) +} diff --git a/templates/project/providers/grpc/provider.go.tpl b/templates/project/providers/grpc/provider.go.tpl new file mode 100644 index 0000000..0629103 --- /dev/null +++ b/templates/project/providers/grpc/provider.go.tpl @@ -0,0 +1,26 @@ +package grpc + +import ( + "git.ipao.vip/rogeecn/atom/container" + "git.ipao.vip/rogeecn/atom/utils/opt" + "google.golang.org/grpc" +) + +func Provide(opts ...opt.Option) error { + o := opt.New(opts...) + var config Config + if err := o.UnmarshalConfig(&config); err != nil { + return err + } + return container.Container.Provide(func() (*Grpc, error) { + server := grpc.NewServer() + + grpc := &Grpc{ + Server: server, + config: &config, + } + container.AddCloseAble(grpc.Server.GracefulStop) + + return grpc, nil + }, o.DiOptions()...) +}