package cmd import ( "fmt" "io/fs" "os" "path/filepath" "strings" "text/template" "github.com/samber/lo" "github.com/spf13/cobra" "go.ipao.vip/atomctl/v2/pkg/utils/gomod" "go.ipao.vip/atomctl/v2/templates" ) // CommandNewProvider 注册 new_provider 命令 func CommandNewJob(root *cobra.Command) { cmd := &cobra.Command{ Use: "job", Short: "创建新的 job", Long: `在 app/jobs 下渲染创建任务模板文件。 行为: - 名称转换:输入名的 Snake 与 Pascal 形式分别用于文件名与导出名 - 输出到 app/jobs/.go - --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 .) 示例: atomctl new job SendDailyReport`, Args: cobra.ExactArgs(1), RunE: commandNewJobE, } root.AddCommand(cmd) } func commandNewJobE(cmd *cobra.Command, args []string) error { snakeName := lo.SnakeCase(args[0]) camelName := lo.PascalCase(args[0]) // shared flags dryRun, _ := cmd.Flags().GetBool("dry-run") baseDir, _ := cmd.Flags().GetString("dir") basePath := filepath.Join(baseDir, "app/jobs") 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 } if dryRun { fmt.Printf("[dry-run] mkdir -p %s\n", basePath) } else { if err := os.MkdirAll(basePath, os.ModePerm); err != nil { return err } } err = fs.WalkDir(templates.Jobs, "jobs", func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { return nil } if strings.HasPrefix(snakeName, "job_") { snakeName = "job_" + snakeName } filePath := filepath.Join(basePath, snakeName+".go") tmpl, err := template.ParseFS(templates.Jobs, path) if err != nil { return err } if dryRun { fmt.Printf("[dry-run] render > %s\n", filePath) return nil } destFile, err := os.Create(filePath) if err != nil { return err } defer destFile.Close() return tmpl.Execute(destFile, map[string]string{ "Name": camelName, "ModuleName": gomod.GetModuleName(), }) }) if err != nil { return err } fmt.Printf("job 已创建: %s\n", snakeName) return nil }