fix: gen provider

This commit is contained in:
Rogee
2025-09-22 14:16:22 +08:00
parent 07e70a80ea
commit a8eb9e0025
13 changed files with 142 additions and 126 deletions

View File

@@ -37,6 +37,7 @@ import (
// - RunE: commandGenProviderE - 命令执行函数 // - RunE: commandGenProviderE - 命令执行函数
// //
// 注释语法说明: // 注释语法说明:
//
// @provider(<mode>):[except|only] [returnType] [group] // @provider(<mode>):[except|only] [returnType] [group]
// - mode: grpc|event|job|cronjob|model可选 // - mode: grpc|event|job|cronjob|model可选
// - :only: 仅注入字段 tag 为 inject:"true" 的依赖 // - :only: 仅注入字段 tag 为 inject:"true" 的依赖
@@ -149,6 +150,7 @@ func CommandGenProvider(root *cobra.Command) {
// - 文件生成错误:返回 provider.Render() 的错误 // - 文件生成错误:返回 provider.Render() 的错误
// //
// 使用示例: // 使用示例:
//
// # 在当前目录生成 Provider // # 在当前目录生成 Provider
// atomctl gen provider // atomctl gen provider
// //

View File

@@ -218,6 +218,7 @@ type NodeVisitor interface {
// - *ASTWalker: 配置好的遍历器实例,可以直接使用 // - *ASTWalker: 配置好的遍历器实例,可以直接使用
// //
// 使用示例: // 使用示例:
//
// walker := NewASTWalker() // walker := NewASTWalker()
// visitor := NewProviderDiscoveryVisitor() // visitor := NewProviderDiscoveryVisitor()
// walker.AddVisitor(visitor) // walker.AddVisitor(visitor)
@@ -264,6 +265,7 @@ func NewASTWalker() *ASTWalker {
// - *ASTWalker: 使用指定配置的遍历器实例 // - *ASTWalker: 使用指定配置的遍历器实例
// //
// 使用示例: // 使用示例:
//
// config := &WalkerConfig{ // config := &WalkerConfig{
// IncludeTestFiles: true, // IncludeTestFiles: true,
// IncludeGeneratedFiles: true, // IncludeGeneratedFiles: true,
@@ -392,6 +394,7 @@ func (aw *ASTWalker) RemoveVisitor(visitor NodeVisitor) {
// - 访问者错误:返回访问者产生的错误,停止后续处理 // - 访问者错误:返回访问者产生的错误,停止后续处理
// //
// 使用示例: // 使用示例:
//
// walker := NewASTWalker() // walker := NewASTWalker()
// walker.AddVisitor(NewProviderDiscoveryVisitor()) // walker.AddVisitor(NewProviderDiscoveryVisitor())
// err := walker.WalkFile("user_service.go") // err := walker.WalkFile("user_service.go")
@@ -964,6 +967,7 @@ type ProviderDiscoveryVisitor struct {
// - *ProviderDiscoveryVisitor: 配置好的访问者实例 // - *ProviderDiscoveryVisitor: 配置好的访问者实例
// //
// 使用示例: // 使用示例:
//
// commentParser := NewCommentParser() // commentParser := NewCommentParser()
// visitor := NewProviderDiscoveryVisitor(commentParser) // visitor := NewProviderDiscoveryVisitor(commentParser)
// walker := NewASTWalker() // walker := NewASTWalker()

View File

@@ -114,8 +114,8 @@ func (c *ParserContext) ShouldIncludeFile(filePath string) bool {
return false return false
} }
// Skip generated files if not allowed // Skip generated files if not allowed, but allow routes.gen.go since it may contain providers
if !c.Config.AllowGenFiles && strings.HasSuffix(filePath, ".gen.go") { if !c.Config.AllowGenFiles && strings.HasSuffix(filePath, ".gen.go") && !strings.HasSuffix(filePath, "routes.gen.go") {
return false return false
} }

View File

@@ -116,7 +116,6 @@ func ParseRefactored(source string) []Provider {
// 调用详细的文件解析方法 // 调用详细的文件解析方法
providers, err := parser.ParseFile(source) providers, err := parser.ParseFile(source)
// 错误处理:记录错误并返回空结果 // 错误处理:记录错误并返回空结果
if err != nil { if err != nil {
log.Error("Parse error: ", err) log.Error("Parse error: ", err)

View File

@@ -184,6 +184,7 @@ type GoParser struct {
// - *GoParser: 配置好的解析器实例,可以直接使用 // - *GoParser: 配置好的解析器实例,可以直接使用
// //
// 使用示例: // 使用示例:
//
// parser := NewGoParser() // parser := NewGoParser()
// providers, err := parser.ParseFile("user_service.go") // providers, err := parser.ParseFile("user_service.go")
func NewGoParser() *GoParser { func NewGoParser() *GoParser {
@@ -229,6 +230,7 @@ func NewGoParser() *GoParser {
// - *GoParser: 使用指定配置的解析器实例 // - *GoParser: 使用指定配置的解析器实例
// //
// 使用示例: // 使用示例:
//
// config := &ParserConfig{ // config := &ParserConfig{
// CacheEnabled: true, // CacheEnabled: true,
// StrictMode: true, // StrictMode: true,
@@ -552,12 +554,13 @@ func (p *GoParser) parseStructFields(structType *ast.StructType, imports map[str
// Add injection parameter // Add injection parameter
for _, name := range field.Names { for _, name := range field.Names {
provider.InjectParams[name.Name] = InjectParam{ param := InjectParam{
Star: star, Star: star,
Type: typ, Type: typ,
Package: pkg, Package: pkg,
PackageAlias: pkgAlias, PackageAlias: pkgAlias,
} }
provider.InjectParams[name.Name] = param
// Add to imports // Add to imports
if pkg != "" && pkgAlias != "" { if pkg != "" && pkgAlias != "" {
@@ -576,7 +579,15 @@ func (p *GoParser) parseFieldType(expr ast.Expr, imports map[string]string) (sta
typ = t.Name typ = t.Name
case *ast.StarExpr: case *ast.StarExpr:
star = "*" star = "*"
return p.parseFieldType(t.X, imports) _, innerPkg, innerPkgAlias, innerTyp, innerErr := p.parseFieldType(t.X, imports)
if innerErr != nil {
return "", "", "", "", innerErr
}
// Use inner package info but keep star
pkg = innerPkg
pkgAlias = innerPkgAlias
typ = innerTyp
return star, pkg, pkgAlias, typ, nil
case *ast.SelectorExpr: case *ast.SelectorExpr:
if x, ok := t.X.(*ast.Ident); ok { if x, ok := t.X.(*ast.Ident); ok {
pkgAlias = x.Name pkgAlias = x.Name

View File

@@ -415,6 +415,7 @@ func (p ProviderDescribe) String() {
// parseProvider 解析 @provider 注解的语法 // parseProvider 解析 @provider 注解的语法
// //
// 支持的语法格式: // 支持的语法格式:
//
// @provider - 基本格式 // @provider - 基本格式
// @provider(job) - 指定模式 // @provider(job) - 指定模式
// @provider(job):except - 排除模式 // @provider(job):except - 排除模式
@@ -437,6 +438,7 @@ func (p ProviderDescribe) String() {
// - ProviderDescribe: 解析后的注解信息 // - ProviderDescribe: 解析后的注解信息
// //
// 示例: // 示例:
//
// 输入: "@provider(job) contracts.Initial atom.GroupInitial" // 输入: "@provider(job) contracts.Initial atom.GroupInitial"
// 输出: ProviderDescribe{ // 输出: ProviderDescribe{
// Mode: "job", // Mode: "job",

View File

@@ -8,7 +8,6 @@ import (
"go.ipao.vip/atomctl/v2/pkg/utils/gomod" "go.ipao.vip/atomctl/v2/pkg/utils/gomod"
) )
//go:embed router.go.tpl //go:embed router.go.tpl
var routeTpl string var routeTpl string

View File

@@ -12,7 +12,6 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
type RouteDefinition struct { type RouteDefinition struct {
FilePath string FilePath string
Path string Path string

View File

@@ -26,7 +26,7 @@ func (c *UserController) GetUser() error {
// Create a temporary file for testing // Create a temporary file for testing
tmpFile := "/tmp/test_route.go" tmpFile := "/tmp/test_route.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -63,7 +63,7 @@ func (c *UserController) GetUser(id string, limit int) {
// Create a temporary file for testing // Create a temporary file for testing
tmpFile := "/tmp/test_params.go" tmpFile := "/tmp/test_params.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -104,7 +104,7 @@ func (c *UserController) GetUser() {
// Create a temporary file for testing // Create a temporary file for testing
tmpFile := "/tmp/test_invalid.go" tmpFile := "/tmp/test_invalid.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -130,7 +130,7 @@ func (c *UserController) GetUser() {
// Create a temporary file for testing // Create a temporary file for testing
tmpFile := "/tmp/test_empty.go" tmpFile := "/tmp/test_empty.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -196,7 +196,7 @@ func (c *HealthController) Check() error {
` `
// Create a temporary file for testing // Create a temporary file for testing
tmpFile := "/tmp/test_compatibility.go" tmpFile := "/tmp/test_compatibility.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -251,7 +251,7 @@ func (c *ApiController) DownloadFile(filename string) error {
} }
` `
tmpFile := "/tmp/test_special_paths.go" tmpFile := "/tmp/test_special_paths.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -352,13 +352,13 @@ func (c *HealthController) Check() error {
// Create a realistic file structure // Create a realistic file structure
tmpDir := "/tmp/test_app" tmpDir := "/tmp/test_app"
httpDir := tmpDir + "/app/http" httpDir := tmpDir + "/app/http"
err := os.MkdirAll(httpDir, 0755) err := os.MkdirAll(httpDir, 0o755)
assert.NoError(t, err, "Should create directory structure") assert.NoError(t, err, "Should create directory structure")
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// Write controller file // Write controller file
controllerFile := httpDir + "/user_controller.go" controllerFile := httpDir + "/user_controller.go"
err = os.WriteFile(controllerFile, []byte(code), 0644) err = os.WriteFile(controllerFile, []byte(code), 0o644)
assert.NoError(t, err, "Should write controller file") assert.NoError(t, err, "Should write controller file")
// WHEN parsing using the same method as CLI // WHEN parsing using the same method as CLI
@@ -398,7 +398,7 @@ type EmptyController struct {
} }
` `
tmpFile := "/tmp/test_empty.go" tmpFile := "/tmp/test_empty.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)
@@ -419,7 +419,7 @@ package main
type BrokenController struct { type BrokenController struct {
` `
tmpFile := "/tmp/test_broken.go" tmpFile := "/tmp/test_broken.go"
err := os.WriteFile(tmpFile, []byte(code), 0644) err := os.WriteFile(tmpFile, []byte(code), 0o644)
assert.NoError(t, err, "Should create temp file") assert.NoError(t, err, "Should create temp file")
defer os.Remove(tmpFile) defer os.Remove(tmpFile)