clop v0.1.0 发布,Go 实现的纯结构体命令行解析器

栏目: 软件资讯 · 发布时间: 3年前

内容简介:clop v0.1.0 已经发布,这是一个 Go 实现的纯结构体命令行解析器。 地址 https://gitee.com/guonaihong/clop https://github.com/guonaihong/clop 更新内容 修复使用tag且使用数据校验提示信息不对的问题 featur...

clop v0.1.0 已经发布,这是一个 Go 实现的纯结构体命令行解析器。

地址

    https://gitee.com/guonaihong/clop

    https://github.com/guonaihong/clop

更新内容

    修复使用tag且使用数据校验提示信息不对的问题

feature

  • 支持环境变量绑定 env DEBUG=xx ./proc
  • 支持参数搜集 cat a.txt b.txt,可以把a.txt, b.txt散装成员归归类,收集到你指定的结构体成员里
  • 支持短选项proc -d 或者长选项proc --debug不在话下
  • posix风格命令行支持,支持命令组合ls -ltrls -l -t -r简写形式,方便实现普通posix 标准命令
  • 子命令支持,方便实现git风格子命令git add ,简洁的子命令注册方式,只要会写结构体就行,3,4,5到无穷尽子命令也支持,只要你喜欢,用上clop就可以实现
  • 默认值支持default:"1",支持多种数据类型,让你省去类型转换的烦恼
  • 贴心的重复命令报错
  • 严格的短选项,长选项报错。避免二义性选项诞生
  • 效验模式支持,不需要写一堆的if x!= "" or if 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

base type

int

package main

import (
        "fmt"

        "github.com/guonaihong/clop"
)

type IntDemo struct {
        Int int `clop:"short;long" usage:"int"`
}

func main() {
        id := &IntDemo{}
        clop.Bind(id)
        fmt.Printf("id = %v\n", id)
}
//  ./int -i 3
// id = &{3}
// ./int --int 3
// id = &{3}

float64

package main

import (
        "fmt"

        "github.com/guonaihong/clop"
)

type Float64Demo struct {
        Float64 float64 `clop:"short;long" usage:"float64"`
}

func main() {
        fd := &Float64Demo{}
        clop.Bind(fd)
        fmt.Printf("fd = %v\n", fd)
}
// ./float64 -f 3.14
// fd = &{3.14}
// ./float64 --float64 3.14
// fd = &{3.14}

duration

package main

import (
        "fmt"
        "time"

        "github.com/guonaihong/clop"
)

type DurationDemo struct {
        Duration time.Duration `clop:"short;long" usage:"duration"`
}

func main() {
        dd := &DurationDemo{}
        clop.Bind(dd)
        fmt.Printf("dd = %v\n", dd)
}
// ./duration -d 1h
// dd = &{1h0m0s}
// ./duration --duration 1h
// dd = &{1h0m0s}

string

package main

import (
        "fmt"

        "github.com/guonaihong/clop"
)

type StringDemo struct {
        String string `clop:"short;long" usage:"string"`
}

func main() {
        s := &StringDemo{}
        clop.Bind(s)
        fmt.Printf("s = %v\n", s)
}
// ./string --string hello
// s = &{hello}
// ./string -s hello
// s = &{hello}

array

similar to curl command

package main

import (
        "fmt"

        "github.com/guonaihong/clop"
)

type ArrayDemo struct {
        Header []string `clop:"-H;long" usage:"header"`
}

func main() {
        h := &ArrayDemo{}
        clop.Bind(h)
        fmt.Printf("h = %v\n", h)
}
// ./array -H session:sid --header token:my
// h = &{[session:sid token:my]}

similar to join command

加上greedy属性,就支持数组贪婪写法。类似join命令。

package main

import (
    "fmt"

    "github.com/guonaihong/clop"
)

type test struct {
    A []int `clop:"-a;greedy" usage:"test array"`
    B int   `clop:"-b" usage:"test int"`
}

func main() {
    a := &test{}
    clop.Bind(a)
    fmt.Printf("%#v\n", a)
}

/*
运行
./use_array -a 12 34 56 78 -b 100
输出
&main.test{A:[]int{12, 34, 56, 78}, B:100}
*/

required flag

package main

import (
	"github.com/guonaihong/clop"
)

type curl struct {
	Url string `clop:"-u; --url" usage:"url" valid:"required"`
}

func main() {

	c := curl{}
	clop.Bind(&c)
}

// ./required 
// error: -u; --url must have a value!
// For more information try --help

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"))

	switch {
	case clop.IsSetSubcommand("mv"):
		fmt.Printf("subcommand mv\n")
	case clop.IsSetSubcommand("add"):
		fmt.Printf("subcommand add\n")
	}
}

// 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)
// subcommand add

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

Can only be set once

指定选项只能被设置一次,如果命令行选项,使用两次则会报错。

package main

import (
    "github.com/guonaihong/clop"
)

type Once struct {
    Debug bool `clop:"-d; --debug; once" usage:"debug mode"`
}

func main() {
    o := Once{}
    clop.Bind(&o)
}
/*
./once -debug -debug
error: The argument '-d' was provided more than once, but cannot be used multiple times
For more information try --help
*/

quick write

快速写法,通过使用固定的short, long tag生成短,长选项。可以和 cat 例子直观比较下。命令行选项越多,越能节约时间,提升效率。

package main

import (
    "fmt"
    "github.com/guonaihong/clop"
)

type cat struct {
	NumberNonblank bool `clop:"-c;long" 
	                     usage:"number nonempty output lines, overrides"`

	ShowEnds bool `clop:"-E;long" 
	               usage:"display $ at end of each line"`

	Number bool `clop:"-n;long" 
	             usage:"number all output lines"`

	SqueezeBlank bool `clop:"-s;long" 
	                   usage:"suppress repeated empty output lines"`

	ShowTab bool `clop:"-T;long" 
	              usage:"display TAB characters as ^I"`

	ShowNonprinting bool `clop:"-v;long" 
	                      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)
}

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>
*/

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据分析技术白皮书

数据分析技术白皮书

伍海凤、刘鹏、杨佳静、马师慧Sara、李博、Shirley Song、Zinc、李晓艳 / 2016-8-11 / 0

关于数据分析技术白皮书(Analytics Book 中文版),主要内容围绕: 1. 分析(Analytics):网站分析 & APP分析 2. 谷歌分析工具的原理、部署与使用 3. 开源网站分析工具的原理、部署与使用 4. Log日志分析原理 5. 网站分析的维度与指标定义 6. 如何炼成为一个互联网数据分析师 请访问书的数据分析技术白皮书官网“免费”阅......一起来看看 《数据分析技术白皮书》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具