golang基于结构体自动生成CLI应用参数配置插件库commandeer的使用
Golang基于结构体自动生成CLI应用参数配置插件库Commandeer的使用
Commandeer简介
Commandeer是一个基于结构体自动生成命令行参数的Go库,它可以根据结构体字段和标签自动设置命令行标志。
主要特点
- 将Go应用开发为库,保持main包简洁
- 自动保持命令行参数与代码同步
- 使用结构体字段注释作为帮助信息
- 最小化依赖污染,仅使用标准库
快速开始示例
1. 定义应用结构
package myapp
import "fmt"
type Main struct {
Num int `help:"How many does it take?"` // 数字参数,help标签提供帮助信息
Vehicle string `help:"What did they get?"` // 字符串参数
}
// 构造函数,设置默认值
func NewMain() *Main { return &Main{Num: 5, Vehicle: "jeep"} }
// 应用主逻辑
func (m *Main) Run() error {
if m.Num < 2 || m.Vehicle == "" {
return fmt.Errorf("Need more gophers and/or vehicles.")
}
fmt.Printf("%d gophers stole my %s!\n", m.Num, m.Vehicle)
return nil
}
2. 创建main包
package main
import (
"fmt"
"github.com/jaffee/commandeer"
"github.com/jaffee/commandeer/examples/myapp"
)
func main() {
// 使用commandeer运行应用
err := commandeer.Run(myapp.NewMain())
if err != nil {
fmt.Println(err)
}
}
3. 使用示例
$ ./myapp -h
Usage of ./myapp:
-num int
How many does it take? (default 5)
-vehicle string
What did they get? (default "jeep")
$ ./myapp
5 gophers stole my jeep!
$ ./myapp -num 3 -vehicle horse
3 gophers stole my horse!
高级功能
自定义标志名称
使用flag
标签覆盖默认生成的标志名称:
type Main struct {
Num int `flag:"number"` // 使用-number而不是默认的-num
}
忽略字段
使用flag:"-"
忽略结构体字段:
type Main struct {
Num int `flag:"-"` // 该字段不会生成命令行参数
}
嵌套结构体
嵌套结构体默认使用点号连接字段名:
type Main struct {
Vehicle struct {
Color string
Weight int
}
}
生成的标志:
-vehicle.color string
-vehicle.weight int
嵌入结构体字段
使用flag:"!embed"
将嵌套结构体字段提升到顶层:
type Main struct {
Vehicle struct {
Color string
Weight int
} `flag:"!embed"`
}
生成的标志:
-color string
-weight int
Cobra集成
如果你不介意外部依赖,可以使用github.com/jaffee/commandeer/cobrafy
集成Cobra和pflag,提供GNU/POSIX风格的标志和其他特性。
总结
Commandeer是一个简单而强大的库,可以自动从结构体生成命令行参数,减少样板代码,保持参数与代码同步。它特别适合那些希望将主要逻辑放在库中,而保持main包简洁的开发者。
更多关于golang基于结构体自动生成CLI应用参数配置插件库commandeer的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang基于结构体自动生成CLI应用参数配置插件库commandeer的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Commandeer自动生成Golang CLI应用参数配置
Commandeer是一个优秀的Go语言库,它能够基于结构体自动生成命令行接口(CLI)应用的参数配置。下面我将详细介绍如何使用Commandeer来简化CLI应用的开发。
基本概念
Commandeer通过结构体标签(struct tags)自动将结构体字段映射到命令行参数,无需手动编写参数解析代码。它支持:
- 自动生成帮助信息
- 支持子命令
- 环境变量绑定
- 配置文件支持
- 参数验证
安装
go get github.com/object88/commandeer
基础用法
1. 定义配置结构体
package main
import (
"fmt"
"log"
"github.com/object88/commandeer"
)
type Config struct {
Host string `help:"Server host" default:"localhost"`
Port int `help:"Server port" default:"8080"`
Debug bool `help:"Enable debug mode"`
Timeout int `help:"Request timeout in seconds" default:"30"`
}
2. 创建并运行CLI应用
func main() {
cfg := &Config{}
// 使用Commandeer解析命令行参数
err := commandeer.Run(cfg, func() error {
// 这里是应用的主要逻辑
fmt.Printf("Starting server on %s:%d (Debug: %v, Timeout: %ds)\n",
cfg.Host, cfg.Port, cfg.Debug, cfg.Timeout)
return nil
})
if err != nil {
log.Fatal(err)
}
}
高级特性
子命令支持
type RootConfig struct {
GlobalFlag string `help:"Global flag for all commands"`
}
type StartConfig struct {
Port int `help:"Port to listen on" default:"8080"`
}
type StopConfig struct {
Force bool `help:"Force stop"`
}
func main() {
root := &RootConfig{}
start := &StartConfig{}
stop := &StopConfig{}
p := commandeer.NewProgram(root)
p.AddCommand("start", "Start the server", start, func() error {
fmt.Printf("Starting on port %d (Global: %s)\n", start.Port, root.GlobalFlag)
return nil
})
p.AddCommand("stop", "Stop the server", stop, func() error {
fmt.Printf("Stopping (Force: %v, Global: %s)\n", stop.Force, root.GlobalFlag)
return nil
})
if err := p.ParseAndRun(); err != nil {
log.Fatal(err)
}
}
环境变量绑定
type Config struct {
DatabaseURL string `help:"Database connection URL" env:"DB_URL"`
APIKey string `help:"API key" env:"API_KEY"`
}
配置文件支持
type Config struct {
Server struct {
Host string `yaml:"host" help:"Server host"`
Port int `yaml:"port" help:"Server port"`
} `yaml:"server"`
Logging struct {
Level string `yaml:"level" help:"Log level" default:"info"`
} `yaml:"logging"`
}
func main() {
cfg := &Config{}
// 添加配置文件支持
p := commandeer.NewProgram(cfg)
p.WithConfigFile("config.yaml", "Path to config file")
err := p.ParseAndRun(func() error {
fmt.Printf("Server: %s:%d, Log Level: %s\n",
cfg.Server.Host, cfg.Server.Port, cfg.Logging.Level)
return nil
})
if err != nil {
log.Fatal(err)
}
}
验证参数
type Config struct {
Port int `help:"Port number" validate:"min=1024,max=65535"`
}
func main() {
cfg := &Config{}
p := commandeer.NewProgram(cfg)
p.WithValidation() // 启用验证
err := p.ParseAndRun(func() error {
fmt.Printf("Using port: %d\n", cfg.Port)
return nil
})
if err != nil {
log.Fatal(err)
}
}
自定义帮助信息
type Config struct {
// ... 其他字段 ...
}
func main() {
cfg := &Config{}
p := commandeer.NewProgram(cfg)
p.WithDescription("My Awesome CLI Tool")
p.WithVersion("1.0.0")
p.WithExamples([]string{
" tool --host example.com --port 9090",
" tool --help",
})
err := p.ParseAndRun(func() error {
// 应用逻辑
return nil
})
if err != nil {
log.Fatal(err)
}
}
实际应用示例
package main
import (
"fmt"
"log"
"time"
"github.com/object88/commandeer"
)
type ServerConfig struct {
Host string `help:"Server host" default:"0.0.0.0"`
Port int `help:"Server port" default:"8080"`
ReadTimeout time.Duration `help:"Read timeout" default:"30s"`
WriteTimeout time.Duration `help:"Write timeout" default:"30s"`
Debug bool `help:"Enable debug mode"`
}
func main() {
cfg := &ServerConfig{}
p := commandeer.NewProgram(cfg)
p.WithDescription("HTTP Server Application")
p.WithVersion("1.2.3")
err := p.ParseAndRun(func() error {
startServer(cfg)
return nil
})
if err != nil {
log.Fatal(err)
}
}
func startServer(cfg *ServerConfig) {
fmt.Printf("Starting server on %s:%d\n", cfg.Host, cfg.Port)
fmt.Printf("Timeouts - Read: %v, Write: %v\n", cfg.ReadTimeout, cfg.WriteTimeout)
fmt.Printf("Debug mode: %v\n", cfg.Debug)
// 实际服务器启动代码...
}
Commandeer极大地简化了Golang CLI应用的开发,通过结构体定义自动生成命令行参数解析,减少了样板代码,同时提供了丰富的功能如子命令、环境变量绑定、配置文件支持和参数验证等。这使得开发者可以更专注于业务逻辑的实现,而不是参数解析的细节。