feat: 增强命令帮助文档,添加详细说明和示例

This commit is contained in:
Rogee
2025-09-12 10:33:57 +08:00
parent a96df4d628
commit ee15e0932a
17 changed files with 217 additions and 52 deletions

View File

@@ -11,11 +11,20 @@ import (
) )
func CommandBuf(root *cobra.Command) { func CommandBuf(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "buf", Use: "buf",
Short: "run buf commands", Short: "run buf commands",
RunE: commandBufE, Long: `在指定目录执行 buf generate。若本机未安装 buf将自动 go install github.com/bufbuild/buf/cmd/buf@v1.48.0。
}
Flags:
- --dir 执行目录(默认 .
- --dry-run 仅打印将要执行的命令
说明:
- 运行前会检查 buf.yaml 是否存在,如不存在会给出提示但仍尝试执行
- 成功后输出生成结果日志`,
RunE: commandBufE,
}
cmd.Flags().String("dir", ".", "Directory to run buf from") cmd.Flags().String("dir", ".", "Directory to run buf from")
cmd.Flags().Bool("dry-run", false, "Preview buf command without executing") cmd.Flags().Bool("dry-run", false, "Preview buf command without executing")

View File

@@ -10,11 +10,20 @@ import (
) )
func CommandFmt(root *cobra.Command) { func CommandFmt(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "fmt", Use: "fmt",
Short: "fmt codes", Short: "fmt codes",
RunE: commandFmtE, Long: `使用 gofumpt -extra 对代码进行格式化;若本机未安装,将自动 go install mvdan.cc/gofumpt@latest。
}
Flags:
- --check 仅检查不写入,输出未格式化文件列表
- --path 指定格式化路径(默认 .
说明:
- 正常格式化等价于gofumpt -l -extra -w <path>
- 检查模式等价于gofumpt -l -extra <path>`,
RunE: commandFmtE,
}
cmd.Flags().Bool("check", false, "Check formatting without writing changes") cmd.Flags().Bool("check", false, "Check formatting without writing changes")
cmd.Flags().String("path", ".", "Path to format (default .)") cmd.Flags().String("path", ".", "Path to format (default .)")

View File

@@ -3,11 +3,18 @@ package cmd
import "github.com/spf13/cobra" import "github.com/spf13/cobra"
func CommandGen(root *cobra.Command) { func CommandGen(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "gen", Use: "gen",
Short: "Generate code", Short: "Generate code",
PersistentPostRunE: commandFmtE, Long: `代码生成命令组:包含 route、provider、model、enum、service 等。
}
持久化参数:
- -c, --config 数据库配置文件(默认 config.toml供 gen model 使用
说明:
- 子命令执行完成后会自动运行 atomctl fmt 进行格式化`,
PersistentPostRunE: commandFmtE,
}
cmd.PersistentFlags().StringP("config", "c", "config.toml", "database config file") cmd.PersistentFlags().StringP("config", "c", "config.toml", "database config file")
cmds := []func(*cobra.Command){ cmds := []func(*cobra.Command){

View File

@@ -19,23 +19,22 @@ func CommandGenEnum(root *cobra.Command) {
Use: "enum", Use: "enum",
Aliases: []string{"e"}, Aliases: []string{"e"},
Short: "Generate enums", Short: "Generate enums",
Long: `Generate enums from Go files that contain both ENUM(...) and swagger:enum. Long: `根据包含 ENUM(...) 且带有 swagger:enum 标记的 Go 文件生成枚举辅助代码。
Scans the project (recursively) for matching files and writes a corresponding 扫描工程(递归)查找匹配文件,并为每个文件生成对应的 *.gen.go。
*.gen.go per file with helpers.
Flags: 参数(Flags
- -f, --flag Generate flag.Value support (default: true) - -f, --flag 生成 flag.Value 支持(默认 true
- -m, --marshal Generate JSON marshal/unmarshal methods - -m, --marshal 生成 JSON 编解码方法
- -s, --sql Generate database/sql helpers (int, null types) (default: true) - -s, --sql 生成 database/sql 相关辅助整型、Null 类型等,默认 true
Behavior: 行为说明:
- Always generates Names() and Values() - 始终生成 Names() Values()
- With --marshal: adds JSON encoding/decoding - 指定 --marshal:增加 JSON 编解码
- With --flag: adds flag.Value support - 指定 --flag:增加 flag.Value 支持
- With --sql: adds SQL driver, int, NullInt, NullString helpers - 指定 --sql:增加 SQL driver、Int、NullIntNullString 等辅助
Examples: 示例:
atomctl gen enum -m -s atomctl gen enum -m -s
atomctl gen enum --flag=false`, atomctl gen enum --flag=false`,
RunE: commandGenEnumE, RunE: commandGenEnumE,

View File

@@ -18,6 +18,19 @@ func CommandGenModel(root *cobra.Command) {
Use: "model", Use: "model",
Aliases: []string{"m"}, Aliases: []string{"m"},
Short: "Generate models", Short: "Generate models",
Long: `根据数据库连接配置生成模型代码,输出到 ./database并支持基于 ./database/.transform.yaml 的类型/命名转换。
配置:通过 -c/--config 指定配置文件(默认 config.toml从 [Database] 段读取:
Username, Password, Database, Host, Port, Schema, SslMode, TimeZone
行为:
- 解析 go.mod 以识别项目模块名
- 连接 PostgreSQLgorm + postgres driver校验连通性
- 调用 go.ipao.vip/gen 生成模型与相关文件到 ./database
- 根据 .transform.yaml 应用转换规则
示例:
atomctl gen -c config.toml model`,
RunE: commandGenModelE, RunE: commandGenModelE,
} }

View File

@@ -18,10 +18,26 @@ func CommandGenProvider(root *cobra.Command) {
Use: "provider", Use: "provider",
Aliases: []string{"p"}, Aliases: []string{"p"},
Short: "Generate providers", Short: "Generate providers",
Long: `// @provider Long: `扫描源码中带有 @provider 注释的结构体,生成 provider.gen.go 实现依赖注入与分组注册。
// @provider(cronjob|job|event|grpc|model):[except|only] [returnType] [group]
// when except add tag: inject:"false" 注释语法:
// when only add tag: inject:"true"`, @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, RunE: commandGenProviderE,
} }

View File

@@ -15,12 +15,31 @@ import (
) )
func CommandGenRoute(root *cobra.Command) { func CommandGenRoute(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "route", Use: "route",
Short: "generate routes", Short: "generate routes",
RunE: commandGenRouteE, Long: `扫描项目控制器,解析注释生成 routes.gen.go。
PostRunE: commandGenProviderE,
} 用法与规则:
- 扫描根目录通过 --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)") cmd.Flags().String("path", ".", "Base path to scan (defaults to CWD)")

View File

@@ -16,6 +16,15 @@ func CommandGenService(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "service", Use: "service",
Short: "generate services", Short: "generate services",
Long: `扫描 --path 指定目录(默认 ./app/services下的 Go 文件,汇总服务名并渲染生成 services.gen.go。
规则:
- 跳过 *_test.go 与 *.gen.go 文件,仅处理普通 .go 文件
- 以文件名作为服务名来源:
- PascalCase 作为 CamelName用于导出类型名
- camelCase 作为 ServiceName用于变量/字段名
- 使用内置模板 services/services.go.tpl 渲染
- 生成完成后会自动运行 gen provider 以补全注入`,
RunE: commandGenServiceE, RunE: commandGenServiceE,
PostRunE: commandGenProviderE, PostRunE: commandGenProviderE,
} }

View File

@@ -17,6 +17,20 @@ func CommandMigrate(root *cobra.Command) {
Use: "migrate [up|up-by-one|up-to|create|down|down-to|fix|redo|reset|status|version]", Use: "migrate [up|up-by-one|up-to|create|down|down-to|fix|redo|reset|status|version]",
Aliases: []string{"m"}, Aliases: []string{"m"},
RunE: commandMigrate, RunE: commandMigrate,
Long: `基于 goose 的数据库迁移工具。
action
up|up-by-one|up-to|create|down|down-to|fix|redo|reset|status|version
参数:
-c, --config 数据库配置文件(默认 config.toml读取 [Database]
--dir 迁移目录(默认 database/migrations
--table 迁移版本表名(默认 migrations
说明:
- 执行 create 时会在缺省情况下追加 sql 类型
- 使用配置连接数据库,并通过 goose.Run 执行对应 action
- 可在代码中通过 goose.SetTableName 自定义版本表名`,
} }
cmd.Flags().StringP("config", "c", "config.toml", "database config file") cmd.Flags().StringP("config", "c", "config.toml", "database config file")
cmd.Flags().String("dir", "database/migrations", "migrations directory") cmd.Flags().String("dir", "database/migrations", "migrations directory")

View File

@@ -8,6 +8,14 @@ func CommandInit(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "new [project|module]", Use: "new [project|module]",
Short: "new project/module", Short: "new project/module",
Long: `脚手架命令组:创建项目与常用组件模板。
持久化参数(所有子命令通用):
- --force, -f 覆盖已存在文件/目录
- --dry-run 仅预览渲染与写入,不落盘
- --dir 指定输出基目录(默认 .
子命令project、provider、event、jobmodule 已弃用)`,
} }
cmd.PersistentFlags().BoolP("force", "f", false, "Force overwrite existing files or directories") cmd.PersistentFlags().BoolP("force", "f", false, "Force overwrite existing files or directories")

View File

@@ -20,6 +20,17 @@ func CommandNewEvent(root *cobra.Command) {
Use: "event", Use: "event",
Aliases: []string{"e"}, Aliases: []string{"e"},
Short: "创建新的 event publish & subscriber", Short: "创建新的 event publish & subscriber",
Long: `生成事件的发布者与订阅者模板,并在 app/events/topics.go 中维护事件常量。
行为:
- 根据名称转换:驼峰 -> snake 作为 topicPascal 作为导出名
- 生成 publishers/<snake>.go 与 subscribers/<snake>.go可通过 --only 选择一侧)
- 若 topics.go 不存在会自动创建,并追加 const Topic{Name}="<snake>"(避免重复)
- --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 .
示例:
atomctl new event UserCreated
atomctl new event UserCreated --only=publisher`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: commandNewEventE, RunE: commandNewEventE,
} }

View File

@@ -5,6 +5,7 @@ import (
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"text/template" "text/template"
"github.com/samber/lo" "github.com/samber/lo"
@@ -18,8 +19,17 @@ func CommandNewJob(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "job", Use: "job",
Short: "创建新的 job", Short: "创建新的 job",
Args: cobra.ExactArgs(1), Long: `在 app/jobs 下渲染创建任务模板文件。
RunE: commandNewJobE,
行为:
- 名称转换:输入名的 Snake 与 Pascal 形式分别用于文件名与导出名
- 输出到 app/jobs/<snake>.go
- --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 .
示例:
atomctl new job SendDailyReport`,
Args: cobra.ExactArgs(1),
RunE: commandNewJobE,
} }
root.AddCommand(cmd) root.AddCommand(cmd)
@@ -63,6 +73,10 @@ func commandNewJobE(cmd *cobra.Command, args []string) error {
return nil return nil
} }
if strings.HasPrefix(snakeName, "job_") {
snakeName = "job_" + snakeName
}
filePath := filepath.Join(basePath, snakeName+".go") filePath := filepath.Join(basePath, snakeName+".go")
tmpl, err := template.ParseFS(templates.Jobs, path) tmpl, err := template.ParseFS(templates.Jobs, path)
if err != nil { if err != nil {

View File

@@ -29,6 +29,19 @@ func CommandNewProject(root *cobra.Command) {
Use: "project", Use: "project",
Aliases: []string{"p"}, Aliases: []string{"p"},
Short: "new project", Short: "new project",
Long: `基于内置模板创建新项目,或在已有 go.mod 的目录中就地初始化。
行为:
- 在空目录:需传入模块名(如 github.com/acme/app
- 在已有 go.mod可省略模块名自动解析为就地初始化
- 模板渲染规则:支持 .tpl/.raw或通过文件内 atomctl:mode=tpl|raw 指示
- 隐藏文件占位:模板文件名以 - 开头会渲染为 . 前缀(-.gitignore -> .gitignore
- --force可覆盖存在的文件/目录;--dry-run仅打印渲染与写入动作
示例:
atomctl new project github.com/acme/demo
atomctl new -f --dir ./playground project github.com/acme/demo
atomctl new project # 在已有 go.mod 的项目中就地初始化`,
RunE: commandNewProjectE, RunE: commandNewProjectE,
} }

View File

@@ -19,6 +19,16 @@ func CommandNewProvider(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "provider", Use: "provider",
Short: "创建新的 provider", Short: "创建新的 provider",
Long: `在 providers/<name> 目录下渲染创建 Provider 模板。
行为:
- 从内置模板 templates/provider 渲染相关文件
- 使用 name 的 CamelCase 作为导出名
- --dry-run 仅打印渲染与写入动作;--dir 指定输出基目录(默认 .
示例:
atomctl new provider email
atomctl new --dry-run --dir ./demo provider cache`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: commandNewProviderE, RunE: commandNewProviderE,
} }

View File

@@ -6,6 +6,7 @@ func CommandSwag(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "swag", Use: "swag",
Short: "Generate swag docs", Short: "Generate swag docs",
Long: `Swagger 文档相关命令组:包含 init生成文档与 fmt格式化注释`,
} }
cmds := []func(*cobra.Command){ cmds := []func(*cobra.Command){
CommandSwagInit, CommandSwagInit,

View File

@@ -6,12 +6,17 @@ import (
) )
func CommandSwagFmt(root *cobra.Command) { func CommandSwagFmt(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "fmt", Use: "fmt",
Aliases: []string{"f"}, Aliases: []string{"f"},
Short: "swag format", Short: "swag format",
RunE: commandSwagFmtE, Long: `格式化接口注释并协助生成更规范的 Swagger 注释。
}
参数:
- --dir 扫描目录(默认 ./app/http
- --main 主入口文件(默认 main.go`,
RunE: commandSwagFmtE,
}
cmd.Flags().String("dir", "./app/http", "SearchDir for swag format") cmd.Flags().String("dir", "./app/http", "SearchDir for swag format")
cmd.Flags().String("main", "main.go", "MainFile for swag format") cmd.Flags().String("main", "main.go", "MainFile for swag format")

View File

@@ -11,12 +11,20 @@ import (
) )
func CommandSwagInit(root *cobra.Command) { func CommandSwagInit(root *cobra.Command) {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "init", Use: "init",
Short: "swag init", Short: "swag init",
Aliases: []string{"i"}, Aliases: []string{"i"},
RunE: commandSwagInitE, Long: `生成 Swagger 文档go/json/yaml
}
参数:
- --dir 项目根目录(默认 .
- --out 输出目录(默认 docs
- --main 主入口文件(默认 main.go
说明:基于 rogeecn/swag 的 gen 构建器,支持模板分隔符定制、依赖解析等配置。`,
RunE: commandSwagInitE,
}
cmd.Flags().String("dir", ".", "SearchDir (project root)") cmd.Flags().String("dir", ".", "SearchDir (project root)")
cmd.Flags().String("out", "docs", "Output dir for generated docs") cmd.Flags().String("out", "docs", "Output dir for generated docs")