Files
atomctl/cmd/gen_provider.go

100 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cmd
import (
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/samber/lo"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"go.ipao.vip/atomctl/v2/pkg/ast/provider"
"go.ipao.vip/atomctl/v2/pkg/utils/gomod"
)
func CommandGenProvider(root *cobra.Command) {
cmd := &cobra.Command{
Use: "provider",
Aliases: []string{"p"},
Short: "Generate providers",
Long: `扫描源码中带有 @provider 注释的结构体,生成 provider.gen.go 实现依赖注入与分组注册。
注释语法:
@provider(<mode>):[except|only] [returnType] [group]
- modegrpc|event|job|cronjob|model可为空
- :only仅注入字段 tag 为 inject:"true" 的依赖
- :except注入除标注 inject:"false" 之外的非标量依赖
- returnTypeProvide 返回类型(如 contracts.Initial
- group分组如 atom.GroupInitial
模式特性:
- grpc注入 providers/grpc.Grpc设置 GrpcRegisterFunc
- event注入 providers/event.PubSub
- job|cronjob注入 providers/job.Job并引入 github.com/riverqueue/river
- model需要 Prepare 钩子
行为说明:
- 忽略标量类型字段,自动补全 imports
- 以包为单位生成 provider.gen.go
- 可与 gen route 联动(其 PostRun 会触发本命令)`,
RunE: commandGenProviderE,
}
root.AddCommand(cmd)
}
func commandGenProviderE(cmd *cobra.Command, args []string) error {
var err error
var path string
if len(args) > 0 {
path = args[0]
} else {
path, err = os.Getwd()
if err != nil {
return err
}
}
path, _ = filepath.Abs(path)
err = gomod.Parse(filepath.Join(path, "go.mod"))
if err != nil {
return err
}
providers := []provider.Provider{}
// if path is file, then get the dir
log.Infof("generate providers for dir: %s", path)
// travel controller to find all controller objects
_ = filepath.WalkDir(path, func(filepath string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
if !strings.HasSuffix(filepath, ".go") {
return nil
}
if strings.HasSuffix(filepath, "_test.go") {
return nil
}
providers = append(providers, provider.Parse(filepath)...)
return nil
})
// generate files
groups := lo.GroupBy(providers, func(item provider.Provider) string {
return item.ProviderFile
})
for file, conf := range groups {
if err := provider.Render(file, conf); err != nil {
return err
}
}
return nil
}