remove Handler feature for gcmd.Parser

This commit is contained in:
John Guo
2022-01-19 21:07:48 +08:00
parent 69935f3d1c
commit bb37e5ac88
6 changed files with 96 additions and 137 deletions

View File

@ -264,7 +264,7 @@ func newCommandFromMethod(object interface{}, method reflect.Value) (command *Co
}
} else {
// Read argument from command line option name.
if arg.Orphan && parser.ContainsOpt(arg.Name) {
if arg.Orphan && parser.GetOpt(arg.Name) != nil {
data[arg.Name] = "true"
}
}

View File

@ -101,7 +101,7 @@ func (c *Command) doRun(ctx context.Context, parser *Parser) (value interface{},
ctx = context.WithValue(ctx, CtxKeyCommand, c)
// Check built-in help command.
if parser.ContainsOpt(helpOptionName) || parser.ContainsOpt(helpOptionNameShort) {
if parser.GetOpt(helpOptionName) != nil || parser.GetOpt(helpOptionNameShort) != nil {
if c.HelpFunc != nil {
return nil, c.HelpFunc(ctx, parser)
}
@ -159,7 +159,7 @@ func (c *Command) reParse(ctx context.Context, parser *Parser) (*Parser, error)
configMap := value.Map()
for optionName, _ := range parser.passedOptions {
// The command line has the high priority.
if parser.ContainsOpt(optionName) {
if parser.GetOpt(optionName) != nil {
continue
}
// Merge the config value into parser.

View File

@ -55,16 +55,16 @@ func Parse(supportedOptions map[string]bool, strict ...bool) (*Parser, error) {
parsedOptions: GetOptAll(),
}, nil
}
return ParseWithArgs(os.Args, supportedOptions, strict...)
return ParseArgs(os.Args, supportedOptions, strict...)
}
// ParseWithArgs creates and returns a new Parser with given arguments and supported options.
// ParseArgs creates and returns a new Parser with given arguments and supported options.
//
// Note that the parameter `supportedOptions` is as [option name: need argument], which means
// the value item of `supportedOptions` indicates whether corresponding option name needs argument or not.
//
// The optional parameter `strict` specifies whether stops parsing and returns error if invalid option passed.
func ParseWithArgs(args []string, supportedOptions map[string]bool, strict ...bool) (*Parser, error) {
func ParseArgs(args []string, supportedOptions map[string]bool, strict ...bool) (*Parser, error) {
if supportedOptions == nil {
command.Init(args...)
return &Parser{
@ -198,12 +198,6 @@ func (p *Parser) GetOptAll() map[string]string {
return p.parsedOptions
}
// ContainsOpt checks whether option named `name` exist in the arguments.
func (p *Parser) ContainsOpt(name string) bool {
_, ok := p.parsedOptions[name]
return ok
}
// GetArg returns the argument at `index` as gvar.Var.
func (p *Parser) GetArg(index int, def ...string) *gvar.Var {
if index < len(p.parsedArgs) {

View File

@ -1,59 +0,0 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
//
package gcmd
import (
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
)
// BindHandle registers callback function `f` with `cmd`.
func (p *Parser) BindHandle(cmd string, f func()) error {
if _, ok := p.commandFuncMap[cmd]; ok {
return gerror.NewCode(gcode.CodeInvalidOperation, "duplicated handle for command:"+cmd)
} else {
p.commandFuncMap[cmd] = f
}
return nil
}
// BindHandleMap registers callback function with map `m`.
func (p *Parser) BindHandleMap(m map[string]func()) error {
var err error
for k, v := range m {
if err = p.BindHandle(k, v); err != nil {
return err
}
}
return err
}
// RunHandle executes the callback function registered by `cmd`.
func (p *Parser) RunHandle(cmd string) error {
if handle, ok := p.commandFuncMap[cmd]; ok {
handle()
} else {
return gerror.NewCode(gcode.CodeMissingConfiguration, "no handle found for command:"+cmd)
}
return nil
}
// AutoRun automatically recognizes and executes the callback function
// by value of index 0 (the first console parameter).
func (p *Parser) AutoRun() error {
if cmd := p.GetArg(1); !cmd.IsEmpty() {
if handle, ok := p.commandFuncMap[cmd.String()]; ok {
handle()
} else {
return gerror.NewCode(gcode.CodeMissingConfiguration, "no handle found for command:"+cmd.String())
}
} else {
return gerror.NewCode(gcode.CodeMissingParameter, "no command found")
}
return nil
}

View File

@ -0,0 +1,70 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gcmd_test
import (
"fmt"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/genv"
)
func ExampleInit() {
gcmd.Init("gf", "build", "main.go", "-o=gf.exe", "-y")
fmt.Printf(`%#v`, gcmd.GetArgAll())
// Output:
// []string{"gf", "build", "main.go"}
}
func ExampleGetArg() {
gcmd.Init("gf", "build", "main.go", "-o=gf.exe", "-y")
fmt.Printf(
`Arg[0]: "%v", Arg[1]: "%v", Arg[2]: "%v", Arg[3]: "%v"`,
gcmd.GetArg(0), gcmd.GetArg(1), gcmd.GetArg(2), gcmd.GetArg(3),
)
// Output:
// Arg[0]: "gf", Arg[1]: "build", Arg[2]: "main.go", Arg[3]: ""
}
func ExampleGetArgAll() {
gcmd.Init("gf", "build", "main.go", "-o=gf.exe", "-y")
fmt.Printf(`%#v`, gcmd.GetArgAll())
// Output:
// []string{"gf", "build", "main.go"}
}
func ExampleGetOpt() {
gcmd.Init("gf", "build", "main.go", "-o=gf.exe", "-y")
fmt.Printf(
`Opt["o"]: "%v", Opt["y"]: "%v", Opt["d"]: "%v"`,
gcmd.GetOpt("o"), gcmd.GetOpt("y"), gcmd.GetOpt("d", "default value"),
)
// Output:
// Opt["o"]: "gf.exe", Opt["y"]: "", Opt["d"]: "default value"
}
func ExampleGetOptAll() {
gcmd.Init("gf", "build", "main.go", "-o=gf.exe", "-y")
fmt.Printf(`%#v`, gcmd.GetOptAll())
// May Output:
// map[string]string{"o":"gf.exe", "y":""}
}
func ExampleGetOptWithEnv() {
fmt.Printf("Opt[gf.test]:%s\n", gcmd.GetOptWithEnv("gf.test"))
_ = genv.Set("GF_TEST", "YES")
fmt.Printf("Opt[gf.test]:%s\n", gcmd.GetOptWithEnv("gf.test"))
// Output:
// Opt[gf.test]:
// Opt[gf.test]:YES
}

View File

@ -12,7 +12,6 @@ import (
"os"
"testing"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/test/gtest"
)
@ -40,21 +39,21 @@ func Test_Parse(t *testing.T) {
t.Assert(p.GetOpt("prefix"), "www")
t.Assert(p.GetOpt("prefix").String(), "www")
t.Assert(p.ContainsOpt("n"), true)
t.Assert(p.ContainsOpt("name"), true)
t.Assert(p.ContainsOpt("p"), true)
t.Assert(p.ContainsOpt("prefix"), true)
t.Assert(p.ContainsOpt("f"), true)
t.Assert(p.ContainsOpt("force"), true)
t.Assert(p.ContainsOpt("q"), true)
t.Assert(p.ContainsOpt("quiet"), true)
t.Assert(p.ContainsOpt("none"), false)
t.Assert(p.GetOpt("n") != nil, true)
t.Assert(p.GetOpt("name") != nil, true)
t.Assert(p.GetOpt("p") != nil, true)
t.Assert(p.GetOpt("prefix") != nil, true)
t.Assert(p.GetOpt("f") != nil, true)
t.Assert(p.GetOpt("force") != nil, true)
t.Assert(p.GetOpt("q") != nil, true)
t.Assert(p.GetOpt("quiet") != nil, true)
t.Assert(p.GetOpt("none") != nil, false)
})
}
func Test_ParseWithArgs(t *testing.T) {
func Test_ParseArgs(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
p, err := gcmd.ParseWithArgs(
p, err := gcmd.ParseArgs(
[]string{"gf", "--force", "remove", "-fq", "-p=www", "path", "-n", "root"},
map[string]bool{
"n, name": true,
@ -76,59 +75,14 @@ func Test_ParseWithArgs(t *testing.T) {
t.Assert(p.GetOpt("prefix"), "www")
t.Assert(p.GetOpt("prefix").String(), "www")
t.Assert(p.ContainsOpt("n"), true)
t.Assert(p.ContainsOpt("name"), true)
t.Assert(p.ContainsOpt("p"), true)
t.Assert(p.ContainsOpt("prefix"), true)
t.Assert(p.ContainsOpt("f"), true)
t.Assert(p.ContainsOpt("force"), true)
t.Assert(p.ContainsOpt("q"), true)
t.Assert(p.ContainsOpt("quiet"), true)
t.Assert(p.ContainsOpt("none"), false)
})
}
func Test_Handler(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
p, err := gcmd.ParseWithArgs(
[]string{"gf", "--force", "remove", "-fq", "-p=www", "path", "-n", "root"},
map[string]bool{
"n, name": true,
"p, prefix": true,
"f,force": false,
"q,quiet": false,
})
t.Assert(err, nil)
array := garray.New()
err = p.BindHandle("remove", func() {
array.Append(1)
})
t.Assert(err, nil)
err = p.BindHandle("remove", func() {
array.Append(1)
})
t.AssertNE(err, nil)
err = p.BindHandle("test", func() {
array.Append(1)
})
t.Assert(err, nil)
err = p.RunHandle("remove")
t.Assert(err, nil)
t.Assert(array.Len(), 1)
err = p.RunHandle("none")
t.AssertNE(err, nil)
t.Assert(array.Len(), 1)
err = p.RunHandle("test")
t.Assert(err, nil)
t.Assert(array.Len(), 2)
err = p.AutoRun()
t.Assert(err, nil)
t.Assert(array.Len(), 3)
t.Assert(p.GetOpt("n") != nil, true)
t.Assert(p.GetOpt("name") != nil, true)
t.Assert(p.GetOpt("p") != nil, true)
t.Assert(p.GetOpt("prefix") != nil, true)
t.Assert(p.GetOpt("f") != nil, true)
t.Assert(p.GetOpt("force") != nil, true)
t.Assert(p.GetOpt("q") != nil, true)
t.Assert(p.GetOpt("quiet") != nil, true)
t.Assert(p.GetOpt("none") != nil, false)
})
}