Skip to content

Commit

Permalink
👔 up: update the cli option binding logic
Browse files Browse the repository at this point in the history
- add new method for quick add option
  • Loading branch information
inhere committed Jan 21, 2023
1 parent ac59105 commit 24474f7
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 17 deletions.
13 changes: 8 additions & 5 deletions builtin/gen_auto_complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package builtin

import (
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/gookit/color"
Expand Down Expand Up @@ -34,8 +34,8 @@ var shellTpls = map[string]string{
}

// GenAutoComplete create command
func GenAutoComplete() *gcli.Command {
c := gcli.Command{
func GenAutoComplete(fns ...func(c *gcli.Command)) *gcli.Command {
c := &gcli.Command{
Func: doGen,
Name: "genac",
Aliases: []string{"gen-ac"},
Expand Down Expand Up @@ -71,7 +71,10 @@ func GenAutoComplete() *gcli.Command {
"output shell auto completion script file name.",
)

return &c
for _, fn := range fns {
fn(c)
}
return c
}

func doGen(c *gcli.Command, _ []string) (err error) {
Expand Down Expand Up @@ -125,7 +128,7 @@ func doGen(c *gcli.Command, _ []string) (err error) {
}

// Open the file for reading and writing, if it does not exist, create it
err = ioutil.WriteFile(genOpts.output, []byte(str), 0664)
err = os.WriteFile(genOpts.output, []byte(str), 0664)
if err != nil {
return c.NewErrf("Write file error: %s", err.Error())
}
Expand Down
60 changes: 49 additions & 11 deletions gflag/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
"github.com/gookit/goutil/strutil"
)

const (
shortSepRune = ','
shortSepChar = ","
)

// CliOpts cli options management
type CliOpts struct {
// name inherited from gcli.Command
Expand Down Expand Up @@ -143,7 +148,20 @@ func (ops *CliOpts) StrOpt(p *string, name, shorts string, defValAndDesc ...stri
}
}

ops.strOpt(p, newCliOpt(name, desc, defVal, shorts))
ops.StrOpt2(p, name, desc, func(opt *CliOpt) {
opt.DefVal = defVal
opt.Shorts = strings.Split(shorts, shortSepChar)
})
}

// StrOpt2 binding a string option, and allow with CliOptFn for config option.
func (ops *CliOpts) StrOpt2(p *string, nameWithShorts, desc string, confFuncs ...CliOptFn) {
opt := &CliOpt{Name: nameWithShorts, Desc: desc, DefVal: ""}
for _, optFn := range confFuncs {
optFn(opt)
}

ops.strOpt(p, opt)
}

// binding option and shorts
Expand Down Expand Up @@ -171,11 +189,21 @@ func (ops *CliOpts) Int(name, shorts string, defVal int, desc string) *int {
}

// IntVar binding an int option flag
func (ops *CliOpts) IntVar(ptr *int, opt *CliOpt) { ops.intOpt(ptr, opt) }
func (ops *CliOpts) IntVar(p *int, opt *CliOpt) { ops.intOpt(p, opt) }

// IntOpt binding an int option
func (ops *CliOpts) IntOpt(ptr *int, name, shorts string, defVal int, desc string) {
ops.intOpt(ptr, newCliOpt(name, desc, defVal, shorts))
func (ops *CliOpts) IntOpt(p *int, name, shorts string, defVal int, desc string) {
ops.intOpt(p, newCliOpt(name, desc, defVal, shorts))
}

// IntOpt2 binding an int option and with config func.
func (ops *CliOpts) IntOpt2(p *int, nameWithShorts, desc string, confFuncs ...CliOptFn) {
opt := &CliOpt{Name: nameWithShorts, Desc: desc, DefVal: 0}
for _, optFn := range confFuncs {
optFn(opt)
}

ops.intOpt(p, opt)
}

func (ops *CliOpts) intOpt(ptr *int, opt *CliOpt) {
Expand Down Expand Up @@ -300,19 +328,19 @@ func (ops *CliOpts) varOpt(v flag.Value, opt *CliOpt) {

// check flag option name and short-names
func (ops *CliOpts) checkFlagInfo(opt *CliOpt) string {
// check flag name
name := opt.initCheck()
if _, ok := ops.opts[name]; ok {
helper.Panicf("redefined option flag '%s'", name)
}

// NOTICE: must init some required fields
if ops.names == nil {
ops.names = map[string]int{}
ops.opts = map[string]*CliOpt{}
ops.InitFlagSet("flags-" + opt.Name)
}

// check flag name
name := opt.initCheck()
if _, ok := ops.opts[name]; ok {
helper.Panicf("redefined option flag '%s'", name)
}

// is a short name
helpLen := opt.helpNameLen()
// fix: must exclude Hidden option
Expand Down Expand Up @@ -416,6 +444,9 @@ func (ops *CliOpts) Opts() map[string]*CliOpt { return ops.opts }
* flag options metadata
***********************************************************************/

// CliOptFn type
type CliOptFn func(opt *CliOpt)

// CliOpt define for a flag option
type CliOpt struct {
// go flag value
Expand Down Expand Up @@ -450,11 +481,18 @@ func newCliOpt(name, desc string, defVal any, shortcut string) *CliOpt {
Desc: desc,
// other info
DefVal: defVal,
Shorts: strings.Split(shortcut, ","),
Shorts: strings.Split(shortcut, shortSepChar),
}
}

func (m *CliOpt) initCheck() string {
// feat: support add shorts by option name. eg: "name,n"
if strings.ContainsRune(m.Name, shortSepRune) {
ss := strings.Split(m.Name, shortSepChar)
m.Name = ss[0]
m.Shorts = append(m.Shorts, ss[1:]...)
}

if m.Desc != "" {
desc := strings.Trim(m.Desc, "; ")
if strings.ContainsRune(desc, ';') {
Expand Down
5 changes: 5 additions & 0 deletions show/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ func (item *Item) Kind() reflect.Kind {
return item.rftVal.Kind()
}

// IsKind check
func (item *Item) IsKind(kind reflect.Kind) bool {
return item.rftVal.Kind() == kind
}

// IsArray get is array, slice
func (item *Item) IsArray() bool {
return item.rftVal.Kind() == reflect.Array || item.rftVal.Kind() == reflect.Slice
Expand Down
2 changes: 1 addition & 1 deletion show/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func (l *List) Format() {
f.SetOutput(l.buf)
}).Format()
l.buf.WriteByte('\n')
} else if item.Kind() == reflect.Map {
} else if item.IsKind(reflect.Map) {
maputil.NewFormatter(item.rftVal).WithFn(func(f *maputil.MapFormatter) {
f.Indent = mlIndent
f.ClosePrefix = " "
Expand Down

0 comments on commit 24474f7

Please sign in to comment.