name: cobra-scaffolder description: 生成基于Cobra/Viper的Go CLI应用程序,包含持久化标志、子命令和配置管理。使用现代模式创建生产就绪的Go CLI。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep
Cobra 脚手架工具
生成一个完整的Cobra CLI应用程序,包含Viper配置、规范的Go模块结构和最佳实践。
功能
- 生成基于Go的Cobra CLI项目
- 创建包含持久化和局部标志的命令层级结构
- 集成Viper进行配置管理
- 设置自动环境变量绑定
- 实现Shell自动补全生成
- 配置go.mod和构建工作流
使用场景
在以下情况调用此技能:
- 使用Cobra引导一个新的CLI应用程序
- 创建具有层级命令的Go CLI
- 集成Viper实现多源配置
- 构建跨平台原生二进制文件
输入参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| projectName | string | 是 | CLI项目名称(kebab-case格式) |
| modulePath | string | 是 | Go模块路径(例如:github.com/user/project) |
| description | string | 是 | CLI的简短描述 |
| commands | array | 否 | 要搭建的命令列表 |
| useViper | boolean | 否 | 集成Viper配置(默认:true) |
| useCobra | boolean | 否 | 使用cobra-cli生成器模式(默认:true) |
命令结构
{
"commands": [
{
"name": "serve",
"description": "启动服务器",
"persistentFlags": [
{ "name": "config", "shorthand": "c", "type": "string", "usage": "配置文件路径" }
],
"flags": [
{ "name": "port", "shorthand": "p", "type": "int", "default": 8080, "usage": "监听端口" }
],
"subcommands": ["start", "stop", "status"]
}
]
}
输出结构
<projectName>/
├── go.mod
├── go.sum
├── main.go
├── README.md
├── .goreleaser.yaml
├── cmd/
│ ├── root.go # 根命令(含Viper)
│ ├── serve.go # Serve命令
│ ├── version.go # 版本命令
│ └── completion.go # 自动补全命令
├── internal/
│ ├── config/
│ │ └── config.go # 配置结构
│ ├── server/
│ │ └── server.go # 服务器实现
│ └── logger/
│ └── logger.go # 日志设置
├── pkg/
│ └── utils/
│ └── helpers.go # 公共工具
└── tests/
└── cmd/
└── root_test.go
生成的代码模式
根命令 (cmd/root.go)
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
var rootCmd = &cobra.Command{
Use: "<projectName>",
Short: "<description>",
Long: `<详细描述>`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return initConfig()
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "",
"配置文件(默认为 $HOME/.<projectName>.yaml)")
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "详细输出")
viper.BindPFlag("verbose", rootCmd.PersistentFlags().Lookup("verbose"))
}
func initConfig() error {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, err := os.UserHomeDir()
cobra.CheckErr(err)
viper.AddConfigPath(home)
viper.SetConfigType("yaml")
viper.SetConfigName(".<projectName>")
}
viper.AutomaticEnv()
viper.SetEnvPrefix("<PROJECT_NAME>")
if err := viper.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "使用配置文件:", viper.ConfigFileUsed())
}
return nil
}
命令模板 (cmd/serve.go)
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var serveCmd = &cobra.Command{
Use: "serve",
Short: "启动服务器",
Long: `使用指定配置启动服务器。`,
RunE: func(cmd *cobra.Command, args []string) error {
port := viper.GetInt("port")
host := viper.GetString("host")
fmt.Printf("在 %s:%d 上启动服务器
", host, port)
return nil
},
}
func init() {
rootCmd.AddCommand(serveCmd)
serveCmd.Flags().IntP("port", "p", 8080, "监听端口")
serveCmd.Flags().String("host", "localhost", "绑定主机")
viper.BindPFlag("port", serveCmd.Flags().Lookup("port"))
viper.BindPFlag("host", serveCmd.Flags().Lookup("host"))
}
依赖项
module github.com/user/<projectName>
go 1.21
require (
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.18.0
)
工作流程
- 验证输入 - 检查项目名称、模块路径
- 创建目录结构 - 设置Go项目布局
- 生成go.mod - 配置模块和依赖项
- 创建根命令 - Viper集成和全局标志
- 生成命令 - 单个命令文件
- 创建内部包 - 配置、日志等
- 设置goreleaser - 跨平台构建配置
- 创建测试 - 使用cobra测试的命令测试
应用的最佳实践
- 标准Go项目布局
- Viper配置管理
- 共享选项的持久化标志
- 环境变量绑定
- 内置自动补全生成
- Goreleaser用于分发
参考资料
- Cobra文档:https://cobra.dev/
- Cobra GitHub:https://github.com/spf13/cobra
- Viper GitHub:https://github.com/spf13/viper
- Go项目布局:https://github.com/golang-standards/project-layout
目标流程
- cli-application-bootstrap
- cli-command-structure-design
- configuration-management-system