acmd - 简单实用的Golang命令行工具插件库
acmd是一个轻量级的Golang命令行工具库,它提供了简单易用的API来构建命令行应用程序。下面我将介绍acmd的基本用法和示例代码。
安装
go get github.com/cristalhq/acmd
基本用法
1. 创建简单命令
package main
import (
"fmt"
"log"
"os"
"github.com/cristalhq/acmd"
)
func main() {
// 定义命令
cmds := []acmd.Command{
{
Name: "hello",
Description: "打印欢迎信息",
ExecFunc: func(ctx acmd.Context) error {
fmt.Println("Hello, World!")
return nil
},
},
}
// 配置运行器
r := acmd.RunnerOf(cmds, acmd.Config{
AppName: "myapp",
AppDescription: "一个简单的命令行应用",
Version: "v1.0.0",
Args: os.Args[1:],
})
// 运行命令
if err := r.Run(); err != nil {
log.Fatal(err)
}
}
2. 带参数的命令
cmds := []acmd.Command{
{
Name: "greet",
Description: "向某人问好",
ExecFunc: func(ctx acmd.Context) error {
if len(ctx.Args) == 0 {
return fmt.Errorf("请提供要问候的人名")
}
fmt.Printf("Hello, %s!\n", ctx.Args[0])
return nil
},
},
}
3. 子命令
cmds := []acmd.Command{
{
Name: "user",
Description: "用户管理",
SubCommands: []acmd.Command{
{
Name: "add",
Description: "添加用户",
ExecFunc: func(ctx acmd.Context) error {
if len(ctx.Args) < 2 {
return fmt.Errorf("需要提供用户名和邮箱")
}
fmt.Printf("添加用户: 用户名=%s 邮箱=%s\n", ctx.Args[0], ctx.Args[1])
return nil
},
},
{
Name: "list",
Description: "列出用户",
ExecFunc: func(ctx acmd.Context) error {
fmt.Println("用户列表:")
fmt.Println("- Alice")
fmt.Println("- Bob")
return nil
},
},
},
},
}
4. 标志(flags)支持
cmds := []acmd.Command{
{
Name: "serve",
Description: "启动服务",
ExecFunc: func(ctx acmd.Context) error {
// 创建flag集
fs := flag.NewFlagSet("serve", flag.ContinueOnError)
port := fs.Int("port", 8080, "服务监听端口")
debug := fs.Bool("debug", false, "启用调试模式")
// 解析flags
if err := fs.Parse(ctx.Args); err != nil {
return err
}
fmt.Printf("启动服务: 端口=%d 调试模式=%v\n", *port, *debug)
return nil
},
},
}
高级特性
1. 自定义帮助信息
r := acmd.RunnerOf(cmds, acmd.Config{
AppName: "myapp",
AppDescription: "一个高级命令行应用",
Version: "v1.0.0",
Args: os.Args[1:],
// 自定义帮助模板
HelpOptions: acmd.HelpOptions{
Template: `{{.AppName}} - {{.AppDescription}}
版本: {{.Version}}
用法:
{{.AppName}} [命令] [参数]
命令:
{{range .Commands}} {{.Name}}\t{{.Description}}
{{end}}
使用 "{{.AppName}} [命令] --help" 获取命令详情
`,
},
})
2. 错误处理
cmds := []acmd.Command{
{
Name: "divide",
Description: "除法运算",
ExecFunc: func(ctx acmd.Context) error {
if len(ctx.Args) != 2 {
return acmd.ErrorWithUsage{
Err: fmt.Errorf("需要提供两个数字参数"),
Cmd: ctx.Command,
}
}
a, err := strconv.Atoi(ctx.Args[0])
if err != nil {
return fmt.Errorf("第一个参数必须是数字")
}
b, err := strconv.Atoi(ctx.Args[1])
if err != nil {
return fmt.Errorf("第二个参数必须是数字")
}
if b == 0 {
return fmt.Errorf("除数不能为零")
}
fmt.Printf("结果: %d\n", a/b)
return nil
},
},
}
完整示例
package main
import (
"fmt"
"log"
"os"
"github.com/cristalhq/acmd"
)
func main() {
cmds := []acmd.Command{
{
Name: "hello",
Description: "打印欢迎信息",
ExecFunc: func(ctx acmd.Context) error {
fmt.Println("Hello, World!")
return nil
},
},
{
Name: "calc",
Description: "计算器",
SubCommands: []acmd.Command{
{
Name: "add",
Description: "加法",
ExecFunc: func(ctx acmd.Context) error {
if len(ctx.Args) < 2 {
return fmt.Errorf("需要至少两个数字")
}
sum := 0
for _, arg := range ctx.Args {
num, err := strconv.Atoi(arg)
if err != nil {
return fmt.Errorf("无效数字: %s", arg)
}
sum += num
}
fmt.Printf("总和: %d\n", sum)
return nil
},
},
},
},
}
r := acmd.RunnerOf(cmds, acmd.Config{
AppName: "myapp",
AppDescription: "多功能命令行工具",
Version: "v1.0.0",
Args: os.Args[1:],
})
if err := r.Run(); err != nil {
log.Printf("错误: %v\n", err)
os.Exit(1)
}
}
总结
acmd是一个简单实用的Golang命令行工具库,它具有以下特点:
- 轻量级且易于使用
- 支持子命令和参数
- 内置帮助系统
- 可自定义帮助模板
- 良好的错误处理机制
对于需要快速构建命令行工具的场景,acmd是一个不错的选择。它比标准库flag更灵活,又不像cobra那么复杂,非常适合中小型命令行应用开发。