Skip to content

GNU 命令行参数解析器

License

MIT license 48 stars 1 fork

这个库 argp 提供了一个遵循 GNU 标准的命令行参数解析器。

./test -vo out.png --size 256 input.txt

它具有以下特性:

GNU 命令行参数规则:

另请参阅github.com/tdewolff/prompt,这是一个命令行提示器。

安装

确保已安装 GitGo (1.22 或更高版本),运行以下命令:

mkdir Project
cd Project
go mod init
go get -u github.com/tdewolff/argp

然后添加以下导入:

import (
  "github.com/tdewolff/argp"
)

示例

默认用法

一个包含短选项和长选项的常规命令。 参见 cmd/test/main.go

package main

import "github.com/tdewolff/argp"

func main() {
  var verbose int
  var input string
  var output string
  var files []string
  size := 512 // 默认值

  cmd := argp.New("CLI tool description")
  cmd.AddOpt(argp.Count{&verbose}, "v", "verbose", "Increase verbosity, eg. -vvv")
  cmd.AddOpt(&output, "o", "output", "Output file name")
  cmd.AddOpt(&size, "", "size", "Image size")
  cmd.AddArg(&input, "input", "Input file name")
  cmd.AddRest(&files, "files", "Additional files")
  cmd.Parse()

  // ...
}

帮助输出:

Usage: test [options] input files...
Options:
 -h, --help     Help
 -o, --output string Output file name
   --size=512 int Image size
 -v, --verbose int  Increase verbosity, eg. -vvv
Arguments:
 input   Input file name
 files   Additional files

子命令

使用子命令的示例,当未使用子命令时使用主命令,以及名为 "cmd" 的子命令。 对于主命令,我们也可以使用 NewAddOpt 代替,并在 argp.Parse() 后处理该命令。

package main

import "github.com/tdewolff/argp"

func main() {
  cmd := argp.NewCmd(&Main{}, "CLI tool description")
  cmd.AddCmd(&Command{}, "cmd", "Sub command")
  cmd.Parse()
}

type Main struct {
  Version bool `short:"v"`
}

func (cmd *Main) Run() error {
  // ...
  return nil
}

type Command struct {
  Verbose bool `short:"v" name:""`
  Output string `short:"o" desc:"Output file name"`
  Size int `default:"512" desc:"Image size"`
}

func (cmd *Command) Run() error {
  // ...
  return nil
}

参数

var input string
cmd.AddArg(&input, "input", "Input file name")

var files []string
cmd.AddRest(&files, "files", "Additional input files")

选项

基本类型:

var v string = "default"
cmd.AddOpt(&v, "v", "var", "description")

var v bool = true
cmd.AddOpt(&v, "v", "var", "description")

var v int = 42 // also: int8, int16, int32, int64
cmd.AddOpt(&v, "v", "var", "description")

var v uint = 42 // also: uint8, uint16, uint32, uint64
cmd.AddOpt(&v, "v", "var", "description")

var v float64 = 4.2 // also: float32
cmd.AddOpt(&v, "v", "var", "description")

复合类型:

v := [2]int{4, 2} // element can be any valid basic or composite type
cmd.AddOpt(&v, "v", "var", "description")
// --var [4 2] => [2]int{4, 2}
// or: --var 4,2 => [2]int{4, 2}

v := []int{4, 2, 1} // element can be any valid basic or composite type
cmd.AddOpt(&v, "v", "var", "description")
// --var [4 2 1] => []int{4, 2, 1}
// or: --var 4,2,1 => []int{4, 2, 1}

v := map[int]string{1:"one", 2:"two"} // key and value can be any valid basic or composite type
cmd.AddOpt(&v, "v", "var", "description")
// --var {1:one 2:two} => map[int]string{1:"one", 2:"two"}

v := struct { // fields can be any valid basic or composite type
  S string
  I int
  B [2]bool
}{"string", 42, [2]bool{0, 1}}
cmd.AddOpt(&v, "v", "var", "description")
// --var {string 42 [0 1]} => struct{S string, I int, B [2]bool}{"string", 42, false, true}

Count

统计标志被传递的次数。

var c int
cmd.AddOpt(argp.Count{&c}, "c", "count", "Count")
// Count the number of times flag is present
// -c -c / -cc / --count --count => 2
// or: -c 5 => 5

Append

将每个标志附加到列表中。

var v []int
cmd.AddOpt(argp.Append{&v}, "v", "value", "Values")
// Append values for each flag
// -v 1 -v 2 => [1 2]

Config

从配置文件加载所有参数。 目前仅支持 TOML。

cmd.AddOpt(&argp.Config{cmd, "config.toml"}, "", "config", "Configuration file")

List

使用指定为 type:list 的列表源。 默认支持的类型有:inline。

list := argp.NewList(il)
defer list.Close()
cmd.AddOpt(&list, "", "list", "List")

您可以添加 MySQL 源:

type mysqlList struct {
	Hosts  string
	User   string
	Password string
	Dbname  string
	Query  string
}

func newMySQLList(s []string) (argp.ListSource, error) {
	if len(s) != 1 {
		return nil, fmt.Errorf("invalid path")
	}
	t := mysqlList{}
	if err := argp.LoadConfigFile(&t, s[0]); err != nil {
		return nil, err
	}
	uri := fmt.Sprintf("%s:%s@%s/%s", t.User, t.Password, t.Hosts, t.Dbname)
	db, err := sqlx.Open("mysql", uri)
	if err != nil {
		return nil, err
	}
	db.SetConnMaxLifetime(time.Minute)
	db.SetConnMaxIdleTime(time.Minute)
	db.SetMaxOpenConns(10)
	db.SetMaxIdleConns(10)
	return argp.NewSQLList(db, t.Query, "")
}

// ...
list.AddSource("mysql", newMySQLList)
// ...

使用方式:./bin -list mysql:list-config.toml

Dict

使用指定为 type:dict 的字典源。 默认支持的类型有:static 和 inline。

dict := argp.NewDict([]string{"static:value"})
defer dict.Close()
cmd.AddOpt(&dict, "", "dict", "Dict")

您可以像上面的 mysqlList 示例一样添加自定义源。

选项标签

以下结构将接受以下选项和参数:

type Command struct {
  Var1 int `short:"v" name:"var" default:"42" desc:"Description"`
  Var2 float64 `name:"first" index:"0" default:"4.2"`
  Var3 []string `name:"rest" index:"*"`
}

func (cmd *Command) Run() error {
  // run command
  return nil
}

License

MIT license 下发布。