feat: 添加 cron 任务模板,支持定时任务生成

This commit is contained in:
Rogee
2025-09-12 10:52:36 +08:00
parent ee15e0932a
commit c0a437a793
2 changed files with 77 additions and 38 deletions

View File

@@ -2,10 +2,8 @@ package cmd
import ( import (
"fmt" "fmt"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"text/template" "text/template"
"github.com/samber/lo" "github.com/samber/lo"
@@ -23,15 +21,19 @@ func CommandNewJob(root *cobra.Command) {
行为: 行为:
- 名称转换:输入名的 Snake 与 Pascal 形式分别用于文件名与导出名 - 名称转换:输入名的 Snake 与 Pascal 形式分别用于文件名与导出名
- 输出到 app/jobs/<snake>.go - 输出到 app/jobs/<snake>.go;指定 --cron 时输出到 app/jobs/cron_<snake>.go
- --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 . - --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 .
参数:
- --cron 生成定时任务(渲染 cronjob.go.tpl输出 cron_<snake>.go
示例: 示例:
atomctl new job SendDailyReport`, atomctl new job SendDailyReport`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: commandNewJobE, RunE: commandNewJobE,
} }
cmd.Flags().Bool("cron", false, "创建 cron 任务(渲染 cronjob.go.tpl输出 cron_<name>.go")
root.AddCommand(cmd) root.AddCommand(cmd)
} }
@@ -42,6 +44,7 @@ func commandNewJobE(cmd *cobra.Command, args []string) error {
// shared flags // shared flags
dryRun, _ := cmd.Flags().GetBool("dry-run") dryRun, _ := cmd.Flags().GetBool("dry-run")
baseDir, _ := cmd.Flags().GetString("dir") baseDir, _ := cmd.Flags().GetString("dir")
cron, _ := cmd.Flags().GetBool("cron")
basePath := filepath.Join(baseDir, "app/jobs") basePath := filepath.Join(baseDir, "app/jobs")
@@ -64,44 +67,53 @@ func commandNewJobE(cmd *cobra.Command, args []string) error {
} }
} }
err = fs.WalkDir(templates.Jobs, "jobs", func(path string, d fs.DirEntry, err error) error { // always render job file
jobOut := filepath.Join(basePath, snakeName+".go")
jobTpl, err := template.ParseFS(templates.Jobs, "jobs/job.go.tpl")
if err != nil { if err != nil {
return err 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 { if dryRun {
fmt.Printf("[dry-run] render > %s\n", filePath) fmt.Printf("[dry-run] render > %s\n", jobOut)
return nil } else {
} fd, err := os.Create(jobOut)
destFile, err := os.Create(filePath)
if err != nil { if err != nil {
return err return err
} }
defer destFile.Close() if err := jobTpl.Execute(fd, map[string]string{
return tmpl.Execute(destFile, map[string]string{
"Name": camelName, "Name": camelName,
"ModuleName": gomod.GetModuleName(), "ModuleName": gomod.GetModuleName(),
}) }); err != nil {
}) fd.Close()
return err
}
fd.Close()
}
// optionally render cron job file when --cron is set
if cron {
cronOut := filepath.Join(basePath, "cron_"+snakeName+".go")
cronTpl, err := template.ParseFS(templates.Jobs, "jobs/cronjob.go.tpl")
if err != nil { if err != nil {
return err return err
} }
if dryRun {
fmt.Printf("[dry-run] render > %s\n", cronOut)
} else {
fd, err := os.Create(cronOut)
if err != nil {
return err
}
if err := cronTpl.Execute(fd, map[string]string{
"Name": camelName,
"ModuleName": gomod.GetModuleName(),
}); err != nil {
fd.Close()
return err
}
fd.Close()
}
}
fmt.Printf("job 已创建: %s\n", snakeName) fmt.Printf("job 已创建: %s\n", snakeName)
return nil return nil

View File

@@ -0,0 +1,27 @@
package jobs
import (
"context"
"time"
. "github.com/riverqueue/river"
_ "go.ipao.vip/atom"
"go.ipao.vip/atom/contracts"
)
var _ contracts.CronJob = (*Cron{{.Name}})(nil)
// @provider(cronjob)
type Cron{{.Name}} struct{}
func (c *Cron{{.Name}}) Args() []contracts.CronJobArg {
jobs := []contracts.CronJobArg{
{
RunOnStart: true, //
PeriodicInterval: cron.Every(time.Hour * 2), // 2
// PeriodicInterval: PeriodicInterval("* * * * *"), // 1
Arg: {{.Name}}{},
},
}
return jobs
}