golang基于结构体标签的声明式CLI框架插件goopt的使用

golang基于结构体标签的声明式CLI框架插件goopt的使用

goopt简介

goopt是一个灵活且强大的Go语言命令行选项解析器。它提供了一种基于结构体标签的声明式方法来构建CLI应用程序,具有健壮性、可维护性和用户友好性。

该库设计简单直观,适合简单工具,同时也能扩展用于复杂应用。主要特性包括:

  • 高级帮助系统
  • 可组合的验证引擎
  • 命令生命周期钩子
  • 全面的国际化(i18n)支持

安装(v2)

推荐所有新项目使用v2版本:

go get github.com/napalu/goopt/v2

快速入门(v2)

下面是一个完整的示例demo,展示如何使用goopt v2定义CLI结构:

package main

import (
    "fmt"
    "os"
    "github.com/napalu/goopt/v2"
)

// Config 定义整个CLI结构
type Config struct {
    // 全局标志
    Verbose bool `goopt:"short:v;desc:启用详细输出"`

    // 'create'命令及其子命令
    Create struct {
        Force bool `goopt:"short:f;desc:强制创建"`
        User struct {
            Username string `goopt:"short:u;desc:用户名;required:true"`
            Password string `goopt:"short:p;desc:密码;secure:true"`
        } `goopt:"kind:command;name:user;desc:创建用户"`
    } `goopt:"kind:command;name:create;desc:创建资源"`
}

func main() {
    cfg := &Config{}
    // 从结构体创建解析器
    parser, err := goopt.NewParserFromStruct(cfg)
    if err != nil {
        fmt.Fprintf(os.Stderr, "创建解析器错误: %v\n", err)
        os.Exit(1)
    }

    // 解析命令行参数,失败或请求--help时返回false
    if !parser.Parse(os.Args) {
        // goopt默认会打印错误和帮助文本
        os.Exit(1)
    }

    // 应用程序逻辑
    if parser.HasCommand("create", "user") {
        fmt.Printf("正在创建用户: %s\n", cfg.Create.User.Username)
    }
}

结构体标签说明

goopt使用结构体标签定义CLI参数:

  • short: 短选项名称(如-v)
  • desc: 参数描述
  • required: 是否必需(true/false)
  • secure: 敏感参数(如密码)
  • kind:command: 标记为命令
  • name: 命令名称

旧版(v1.x)

v1版本已进入维护模式,新项目推荐使用v2版本。

安装v1:

go get github.com/napalu/goopt@v1

v1示例代码与v2类似,主要区别在于解析器创建方式:

parser, _ := goopt.NewCmdLineFromStruct(cfg)

许可证

goopt使用MIT许可证。

贡献

欢迎贡献代码,请基于开放的问题进行贡献(可以自由提出问题)。


更多关于golang基于结构体标签的声明式CLI框架插件goopt的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于结构体标签的声明式CLI框架插件goopt的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Goopt: 基于结构体标签的声明式Golang CLI框架

Goopt是一个轻量级的Golang命令行工具框架,它利用结构体标签实现声明式的命令行参数定义,让开发者能够快速构建CLI应用。

基本使用

安装

go get github.com/kballard/goopt

基本示例

package main

import (
	"fmt"
	"github.com/kballard/goopt"
)

type Options struct {
	Name    string `goopt:"-n --name 姓名"`
	Age     int    `goopt:"-a --age 年龄"`
	Verbose bool   `goopt:"-v --verbose 显示详细信息"`
}

func main() {
	opts := &Options{}
	goopt.Parse(opts)
	
	fmt.Printf("姓名: %s\n", opts.Name)
	fmt.Printf("年龄: %d\n", opts.Age)
	fmt.Printf("详细模式: %v\n", opts.Verbose)
}

结构体标签语法

Goopt使用结构体标签定义命令行参数:

`goopt:"[短选项] [长选项] [描述] [默认值]"`
  • 短选项:单个字母,前面加-,如-n
  • 长选项:多个字母,前面加--,如--name
  • 描述:参数的帮助信息
  • 默认值:可选,格式为default=值

标签示例

type Config struct {
	Host     string `goopt:"-h --host 服务器地址 default=localhost"`
	Port     int    `goopt:"-p --port 端口号 default=8080"`
	Debug    bool   `goopt:"-d --debug 调试模式"`
	Timeout  int    `goopt:"--timeout 超时时间(秒)"`
}

高级功能

必需参数

type RequiredOptions struct {
	Input  string `goopt:"-i --input 输入文件 required"`
	Output string `goopt:"-o --output 输出文件 required"`
}

枚举值

type EnumOptions struct {
	LogLevel string `goopt:"-l --level 日志级别 [debug|info|warn|error] default=info"`
}

子命令

type Command struct {
	Init    *InitCommand    `goopt:"init 初始化"`
	Build   *BuildCommand   `goopt:"build 构建项目"`
	Version *VersionCommand `goopt:"version 显示版本"`
}

type InitCommand struct {
	Force bool `goopt:"-f --force 强制初始化"`
}

type BuildCommand struct {
	Output string `goopt:"-o --output 输出文件"`
}

type VersionCommand struct {
	Verbose bool `goopt:"-v --verbose 详细信息"`
}

func main() {
	cmd := &Command{}
	goopt.Parse(cmd)
	
	if cmd.Init != nil {
		fmt.Println("执行初始化命令", cmd.Init.Force)
	} else if cmd.Build != nil {
		fmt.Println("执行构建命令", cmd.Build.Output)
	} else if cmd.Version != nil {
		fmt.Println("显示版本信息", cmd.Version.Verbose)
	} else {
		goopt.Usage()
	}
}

自定义帮助信息

func main() {
	goopt.Description = "这是一个示例程序"
	goopt.Version = "1.0.0"
	goopt.Author = "Your Name"
	
	opts := &Options{}
	goopt.Parse(opts)
	
	// 程序逻辑...
}

验证参数

type ValidatedOptions struct {
	Port int `goopt:"-p --port 端口号"`
}

func (o *ValidatedOptions) Validate() error {
	if o.Port < 1 || o.Port > 65535 {
		return fmt.Errorf("端口号必须在1-65535之间")
	}
	return nil
}

func main() {
	opts := &ValidatedOptions{}
	goopt.Parse(opts)
	
	if err := opts.Validate(); err != nil {
		fmt.Println("参数错误:", err)
		goopt.Usage()
		return
	}
	
	// 程序逻辑...
}

总结

Goopt通过结构体标签提供了一种简洁的方式来定义命令行参数,主要特点包括:

  1. 声明式参数定义
  2. 支持短选项和长选项
  3. 自动生成帮助信息
  4. 支持子命令
  5. 内置参数验证

这种基于结构体的方式使得CLI应用的开发更加直观和类型安全,适合中小型命令行工具的开发。

回到顶部