Files
atomctl/cmd/gen_route.go
Rogee 439456b6ad fix: 恢复 gen route 的 model 参数渲染到 f2a8b98 实现
- 恢复 buildParamToken 函数的直接实现,移除复杂的 builder 模式
- 恢复 buildRenderData 函数的简单实现,提高代码可读性
- 恢复 Render 函数的基础实现,移除过度工程化的验证逻辑
- 修复路由分组路径问题:移除 buildResult 中错误的路径覆盖逻辑
- 当使用 model() 绑定时生成完整的数据库查询函数代码

此提交将 gen route 功能恢复到 commit f2a8b9876e
的实现方式,确保 model 参数渲染符合原始设计。

修复问题:
- 修复路由生成时 "open /v1/medias/routes.gen.go: no such file or directory" 错误
- 确保 model 参数正确生成完整的数据库查询代码而非简化接口
2025-09-22 19:01:40 +08:00

117 lines
3.0 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 (
"fmt"
"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/route"
"go.ipao.vip/atomctl/v2/pkg/utils/gomod"
)
func CommandGenRoute(root *cobra.Command) {
cmd := &cobra.Command{
Use: "route",
Short: "generate routes",
Long: `扫描项目控制器,解析注释生成 routes.gen.go。
用法与规则:
- 扫描根目录通过 --path 指定(默认 CWD会在 <path>/app/http 下递归搜索。
- 使用注释定义路由与参数绑定:
- @Router <path> [<method>] 例如:@Router /users/:id [get]
- @Bind <name> (<position>) key(<key>) [model(<field[:field_type]>)]
- position 枚举path|query|body|header|cookie|local|file
- model() 形式model() 默认 id:intmodel(id) 默认 intmodel(id:int) 显式类型
参数位置与类型建议:
- path标量或结合 model() 从路径值加载模型
- query/header标量或结构体
- cookie标量string 有快捷写法
- body结构体或标量
- file固定 multipart.FileHeader
- local任意类型上下文本地值
说明:生成完成后会自动运行 gen provider 以补全依赖注入。`,
RunE: commandGenRouteE,
PostRunE: commandGenProviderE,
}
cmd.Flags().String("path", ".", "Base path to scan (defaults to CWD)")
root.AddCommand(cmd)
}
// https://go.ipao.vip/atomctl/v2/pkg/swag?tab=readme-ov-file#api-operation
func commandGenRouteE(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
}
}
// allow overriding via --path flag
if f := cmd.Flag("path"); f != nil && f.Value.String() != "." && f.Value.String() != "" {
path = f.Value.String()
}
path, _ = filepath.Abs(path)
err = gomod.Parse(filepath.Join(path, "go.mod"))
if err != nil {
return err
}
routes := []route.RouteDefinition{}
modulePath := filepath.Join(path, "app/http")
if _, err := os.Stat(modulePath); os.IsNotExist(err) {
return fmt.Errorf("routes directory not found: %s (set --path to your project root)", modulePath)
}
// controllerPattern := regexp.MustCompile(`controller(_?\w+)?\.go`)
err = filepath.WalkDir(modulePath, func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}
// if !controllerPattern.MatchString(d.Name()) {
// return nil
// }
if strings.HasSuffix(path, ".gen.go") {
return nil
}
if strings.HasSuffix(path, "_test.go") {
return nil
}
routes = append(routes, route.ParseFile(path)...)
return nil
})
if err != nil {
return err
}
routeGroups := lo.GroupBy(routes, func(item route.RouteDefinition) string {
return filepath.Dir(item.Path)
})
for path, routes := range routeGroups {
if err := route.Render(path, routes); err != nil {
log.WithError(err).WithField("path", path).Error("render route failed")
}
}
return nil
}