Skip to content

Commit

Permalink
调整版本功能 (#102)
Browse files Browse the repository at this point in the history
* 优化usage显示信息

* 更新版本信息显示功能,去除进程名显示

* 更新测试用例

* 调整about信息显示

* 调整about显示模板

* 输出版本号时增加换行

* 调整版本功能
  • Loading branch information
Greyh4t authored Jan 7, 2023
1 parent 93dd7c8 commit 1b203ed
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 26 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func main() {

h := Hello{}
clop.SetVersion("v0.2.0")
clop.SetVersionOption("", "version")
clop.SetAbout("这是一个简单的示例demo")
clop.Bind(&h)
fmt.Printf("%#v\n", h)
Expand Down
97 changes: 72 additions & 25 deletions clop.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ var (
)

const (
defautlVersion = "v0.0.1"
defautlCallbackName = "Parse"
defaultSubMain = "SubMain"
)
Expand Down Expand Up @@ -68,8 +67,9 @@ type Clop struct {
unparsedArgs []unparsedArg //没有解析的args参数
allStruct map[interface{}]struct{} //所有注册过的结构体

about string //about信息
version string //版本信息
about string //about信息
version string //版本信息
versionOption *Option //版本选项

subMain reflect.Value //子命令带SubMain方法, 就会自动调用
structAddr reflect.Value
Expand All @@ -87,9 +87,43 @@ type Clop struct {
// 设置版本相关信息
func (c *Clop) SetVersion(version string) *Clop {
c.version = version
if c.versionOption == nil {
c.SetVersionOption("V", "version")
}

return c
}

// 设置版本相关信息
func (c *Clop) SetVersionOption(short, long string) *Clop {
var opt Option

if short != "" {
opt.showShort = []string{short}
}
if long != "" {
opt.showLong = []string{long}
}

c.versionOption = &opt

return c
}

func (c *Clop) versionShort() string {
if c.versionOption != nil && len(c.versionOption.showShort) > 0 {
return c.versionOption.showShort[0]
}
return ""
}

func (c *Clop) versionLong() string {
if c.versionOption != nil && len(c.versionOption.showLong) > 0 {
return c.versionOption.showLong[0]
}
return ""
}

// 设置about相关信息
func (c *Clop) SetAbout(about string) *Clop {
c.about = about
Expand Down Expand Up @@ -201,6 +235,25 @@ func (c *Clop) setOption(name string, option *Option, m map[string]*Option, long
return fmt.Errorf("%w:%s:unsupported characters found(%c)", ErrOptionName, name, c)
}

if c.version != "" && (name == c.versionShort() || name == c.versionLong()) {
name = "-" + name
if long {
name = "-" + name
}

versionOpt := ""
if c.versionShort() != "" {
versionOpt = "-" + c.versionShort()
}
if c.versionLong() != "" {
if versionOpt != "" {
versionOpt += ","
}
versionOpt += "--" + c.versionLong()
}
return fmt.Errorf("%s %w, duplicate definition with version option %s", name, ErrDuplicateOptions, versionOpt)
}

if o, ok := m[name]; ok {
name = "-" + name
if long {
Expand Down Expand Up @@ -260,9 +313,6 @@ func setBoolAndBoolSliceDefval(pointer reflect.Value, value *string) {
*value = "true"
}
}

return

}

func (c *Clop) parseEqualValue(arg string) (value string, option *Option, err error) {
Expand Down Expand Up @@ -367,8 +417,6 @@ func (c *Clop) parseLong(arg string, index *int) (err error) {
return nil
}
}

return nil
}

// 设置环境变量和参数
Expand Down Expand Up @@ -552,11 +600,9 @@ func (c *Clop) getOptionAndSet(arg string, index *int, numMinuses int) error {
}

// 显示版本信息
if arg == "V" || arg == "version" {
if _, ok := c.shortAndLong[arg]; !ok {
c.showVersion()
return nil
}
if c.version != "" && (arg == c.versionShort() || arg == c.versionLong()) {
c.showVersion()
return nil
}
// 取出option对象
switch numMinuses {
Expand Down Expand Up @@ -596,16 +642,21 @@ func (c *Clop) showShortAndLong(v *Option) string {
}

func (c *Clop) genHelpMessage(h *Help) {

// shortAndLong多个key指向一个option,需要used map去重
used := make(map[*Option]struct{}, len(c.shortAndLong))

if c.shortAndLong["h"] == nil && c.shortAndLong["help"] == nil {
c.shortAndLong["h"] = &Option{usage: "print the help information", showShort: []string{"h"}, showLong: []string{"help"}}
}

if c.shortAndLong["V"] == nil && c.shortAndLong["version"] == nil {
c.shortAndLong["V"] = &Option{usage: "print version information", showShort: []string{"V"}, showLong: []string{"version"}}
if c.version != "" {
if c.versionShort() != "" && c.versionLong() != "" {
c.shortAndLong[c.versionShort()] = &Option{usage: "print version information", showShort: []string{c.versionShort()}, showLong: []string{c.versionLong()}}
} else if c.versionShort() != "" {
c.shortAndLong[c.versionShort()] = &Option{usage: "print version information", showShort: []string{c.versionShort()}}
} else {
c.shortAndLong[c.versionLong()] = &Option{usage: "print version information", showLong: []string{c.versionLong()}}
}
}

saveHelp := func(options map[string]*Option) {
Expand Down Expand Up @@ -698,7 +749,6 @@ func (c *Clop) printHelpMessage() {
if err != nil {
panic(err)
}

}

func (c *Clop) getRoot() (root *Clop) {
Expand Down Expand Up @@ -847,7 +897,6 @@ func (c *Clop) parseTagAndSetOption(clop string, usage string, def string, field
if strings.HasPrefix(opt, "-") && len(name) == 0 {
return fmt.Errorf("Illegal command line option:%s", opt)
}

}

if flags&isShort == 0 && flags&isLong == 0 && flags&isEnv == 0 && flags&isArgs == 0 {
Expand Down Expand Up @@ -875,7 +924,6 @@ func (c *Clop) registerCore(v reflect.Value, sf reflect.StructField) error {
}

if v.Kind() != reflect.Struct {

def := Tag(sf.Tag).Get("default")
def = strings.TrimSpace(def)
if len(def) > 0 {
Expand Down Expand Up @@ -1019,7 +1067,6 @@ func (c *Clop) bindEnvAndArgs() error {

// bind结构体
func (c *Clop) bindStruct() error {

for i := 0; i < len(c.args); i++ {

if err := c.parseOneOption(&i); err != nil {
Expand All @@ -1032,11 +1079,6 @@ func (c *Clop) bindStruct() error {
}

func (c *Clop) Bind(x interface{}) (err error) {
// 如果c.version为空就给一个默认值
if c.version == "" {
c.version = defautlVersion
}

defer func() {
if err != nil {
fmt.Fprintln(c.w, err)
Expand Down Expand Up @@ -1119,6 +1161,11 @@ func SetVersion(version string) {
CommandLine.SetVersion(version)
}

// 设置版本号选项,覆盖默认的V和Version
func SetVersionOption(short, long string) {
CommandLine.SetVersionOption(short, long)
}

func SetAbout(about string) {
CommandLine.SetAbout(about)
}
Expand Down
24 changes: 23 additions & 1 deletion clop_version_about_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ func Test_Version_Option_Long(t *testing.T) {
assert.NotEqual(t, strings.Index(buf.String(), version), -1)
}

// 测试自定义version短选项
func Test_Version_Option_Short_Custom(t *testing.T) {
var buf bytes.Buffer
procName := "Test_Version_Option_Short_Custom"
version := "v0.2.0"
cmd := New([]string{"-v"}).SetProcName(procName).SetVersion(version).SetVersionOption("v", "").SetExit(false).SetOutput(&buf)
cmd.MustBind(&git{})

assert.NotEqual(t, strings.Index(buf.String(), version), -1)
}

// 测试自定义version长选项
func Test_Version_Option_Long_Custom(t *testing.T) {
var buf bytes.Buffer
procName := "Test_Version_Option_Long_Custom"
version := "v0.2.0"
cmd := New([]string{"--version"}).SetProcName(procName).SetVersion(version).SetVersionOption("", "version").SetExit(false).SetOutput(&buf)
cmd.MustBind(&git{})

assert.NotEqual(t, strings.Index(buf.String(), version), -1)
}

// 测试-V
func Test_Version_Option_Short_Replace(t *testing.T) {
type dup struct {
Expand All @@ -66,7 +88,7 @@ func Test_Version_Option_Short_Replace(t *testing.T) {
var buf bytes.Buffer
procName := "Test_Version_Option_Short"
version := "v0.2.0"
cmd := New([]string{"-V", "1"}).SetProcName(procName).SetVersion(version).SetExit(false).SetOutput(&buf)
cmd := New([]string{"-V", "1"}).SetProcName(procName).SetVersion(version).SetVersionOption("v", "version").SetExit(false).SetOutput(&buf)
cmd.MustBind(d)

assert.Equal(t, d.Version, "1")
Expand Down

0 comments on commit 1b203ed

Please sign in to comment.