Golang Go语言:拥抱结构体的命令行解析器, clop v0.0.2+v0.0.3 版本发布
Golang Go语言:拥抱结构体的命令行解析器, clop v0.0.2+v0.0.3 版本发布
clop
clop 是一款基于 struct 的命令行解析器,麻雀虽小,五脏俱全。(从零实现)
项目地址
https://github.com/guonaihong/clop
changlog
- bugfix
- 可以获取命令行优先级别,主要在 shell 里面设置 alias 会用到
feature
- 支持环境变量绑定
env DEBUG=xx ./proc
- 支持参数搜集
cat a.txt b.txt
,可以把a.txt, b.txt
散装成员归归类,收集到你指定的结构体成员里 - 支持短选项
proc -d
或者长选项proc --debug
不在话下 - posix 风格命令行支持,支持命令组合
ls -ltr
是ls -l -t -r
简写形式,方便实现普通 posix 标准命令 - 子命令支持,方便实现 git 风格子命令
git add
,简洁的子命令注册方式,只要会写结构提就行,3,4,5 到无穷尽子命令也支持,只要你喜欢,用上 clop 就可以实现 - 默认值支持
default:"1"
,支持多种数据类型,让你省去类型转换的烦恼 - 贴心的重复命令报错
- 严格的短选项,长选项报错。避免二义性选项诞生
- 效验模式支持,不需要写一堆的
if x!= ""
orif y!=0
浪费青春的代码 - 可以获取命令优先级别,方便设置命令别名
内容
Installation
go get github.com/guonaihong/clop
Quick start
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type Hello struct {
File string clop:"-f; --file" usage:"file"
}
func main() {
h := Hello{}
clop.Bind(&h)
fmt.Printf("%#v\n", h)
}
// ./one -f test
// main.Hello{File:“test”}
// ./one --file test
// main.Hello{File:“test”}
example
required flag
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type curl struct {
Url string clop:"-u; --url" usage:"url" valid:"required"
}
func main() {
c := curl{}
clop.Bind(&c)
}
set default value
可以使用 default tag 设置默认值,普通类型直接写,复合类型用 json 表示
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type defaultExample struct {
Int int default:"1"
Float64 float64 default:"3.64"
Float32 float32 default:"3.32"
SliceString []string default:"[\"one\", \"two\"]"
SliceInt []int default:"[1,2,3,4,5]"
SliceFloat64 []float64 default:"[1.1,2.2,3.3,4.4,5.5]"
}
func main() {
de := defaultExample{}
clop.Bind(&de)
fmt.Printf("%v\n", de)
}
// run
// ./use_def
// output:
// {1 3.64 3.32 [one two] [1 2 3 4 5] [1.1 2.2 3.3 4.4 5.5]}
Support environment variables
// file name use_env.go
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type env struct {
OmpNumThread string clop:"env=omp_num_thread" usage:"omp num thread"
Path string clop:"env=XPATH" usage:"xpath"
Max int clop:"env=MAX" usage:"max thread"
}
func main() {
e := env{}
clop.Bind(&e)
fmt.Printf("%#v\n", e)
}
// run
// env XPATH=pwd
omp_num_thread=3 MAX=4 ./use_env
// output
// main.env{OmpNumThread:“3”, Path:"/home/guo", Max:4}
subcommand
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type add struct {
All bool clop:"-A; --all" usage:"add changes from all tracked and untracked files"
Force bool clop:"-f; --force" usage:"allow adding otherwise ignored files"
Pathspec []string clop:"args=pathspec"
}
type mv struct {
Force bool clop:"-f; --force" usage:"allow adding otherwise ignored files"
}
type git struct {
Add add clop:"subcommand=add" usage:"Add file contents to the index"
Mv mv clop:"subcommand=mv" usage:"Move or rename a file, a directory, or a symlink"
}
func main() {
g := git{}
clop.Bind(&g)
fmt.Printf(“git:%#v\n”, g)
fmt.Printf(“git:set mv(%t) or set add(%t)\n”, clop.IsSetSubcommand(“mv”), clop.IsSetSubcommand(“add”))
}
// run:
// ./git add -f
// output:
// git:main.git{Add:main.add{All:false, Force:true, Pathspec:[]string(nil)}, Mv:main.mv{Force:false}}
// git:set mv(false) or set add(true)
Get command priority
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type cat struct {
NumberNonblank bool clop:"-b;--number-nonblank" usage:"number nonempty output lines, overrides"
ShowEnds bool `clop:"-E;--show-ends"
usage:"display $ at end of each line"`
}
func main() {
c := cat{}
clop.Bind(&c)
if clop.GetIndex("number-nonblank") < clop.GetIndex("show-ends") {
fmt.Printf("cat -b -E\n")
} else {
fmt.Printf("cat -E -b \n")
}
}
// cat -be
// 输出 cat -b -E
// cat -Eb
// 输出 cat -E -b
Implementing linux command options
cat
package main
import (
“fmt”
“github.com/guonaihong/clop”
)
type cat struct {
NumberNonblank bool clop:"-c;--number-nonblank" usage:"number nonempty output lines, overrides"
ShowEnds bool `clop:"-E;--show-ends"
usage:"display $ at end of each line"`
Number bool `clop:"-n;--number"
usage:"number all output lines"`
SqueezeBlank bool `clop:"-s;--squeeze-blank"
usage:"suppress repeated empty output lines"`
ShowTab bool `clop:"-T;--show-tabs"
usage:"display TAB characters as ^I"`
ShowNonprinting bool `clop:"-v;--show-nonprinting"
usage:"use ^ and M- notation, except for LFD and TAB" `
Files []string `clop:"args=files"`
}
func main() {
c := cat{}
err := clop.Bind(&c)
fmt.Printf("%#v, %s\n", c, err)
}
/*
Usage:
./cat [Flags] <files>
Flags:
-E,–show-ends display $ at end of each line
-T,–show-tabs display TAB characters as ^I
-c,–number-nonblank number nonempty output lines, overrides
-n,–number number all output lines
-s,–squeeze-blank suppress repeated empty output lines
-v,–show-nonprinting use ^ and M- notation, except for LFD and TAB
Args:
<files>
*/
更多关于Golang Go语言:拥抱结构体的命令行解析器, clop v0.0.2+v0.0.3 版本发布的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢。。。
和标准库的 flag 相比,有什么优势呢
感觉还不如写代码直观
可以开发 gnu 风格命令行。flag 库不行。
我一开始的观点和你一样。后面写了几十,几百个命令,最后得出这种方式比较爽。
针对您提到的“Golang Go语言:拥抱结构体的命令行解析器,clop v0.0.2+v0.0.3 版本发布”这一帖子,以下是我的专业回复:
clop作为一款基于struct的命令行解析器,为Go语言开发者提供了便捷、高效的命令行参数处理方案。在clop v0.0.2及后续v0.0.3版本中,虽然具体的新增功能和改进细节可能因版本迭代而有所变化,但通常这类工具会不断优化其解析性能、增强对复杂命令行参数的支持,并提升用户体验。
值得一提的是,clop支持纯结构体方式进行命令行参数的解析,这大大简化了代码编写和参数管理的复杂度。此外,它还支持环境变量绑定、参数搜集、短选项和长选项处理、POSIX风格命令行以及子命令等功能,这些特性使得clop成为构建高度可定制命令行工具的理想选择。
对于关注clop的Go语言开发者而言,建议查阅最新的官方文档或GitHub仓库以获取关于clop v0.0.2+v0.0.3版本的详细信息和更新日志。同时,也可以尝试在实际项目中应用clop,体验其带来的便捷和高效。