diff --git a/cli.go b/cli.go index 0f0dd1c..3e251a4 100644 --- a/cli.go +++ b/cli.go @@ -21,6 +21,7 @@ import ( "io" "reflect" "strconv" + "strings" "time" "unsafe" ) @@ -190,8 +191,8 @@ func NewCliWith( // Init analyzes the given structure interface, extracts cli definitions from // its tag and installs command flagset by flag APIs. The interface must be a // structure pointer, otherwise will return an error -func (c *Command) Init(i interface{}) error { - ptrRef := reflect.ValueOf(i) +func (c *Command) Init(in interface{}) error { + ptrRef := reflect.ValueOf(in) if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { return fmt.Errorf("%w: %s", @@ -207,6 +208,38 @@ func (c *Command) Init(i interface{}) error { return c.parseValue(valueOfStruct) } +// Capture filter config args and return rest args +func (c *Command) Capture(args []string) []string { + var ( + result []string + expectValue bool + ) + + for _, arg := range args { + if !strings.HasPrefix(arg, "-") { + if expectValue { + c.Args = append(c.Args, arg) + expectValue = false + } else { + result = append(result, arg) + } + + continue + } + + name := strings.TrimPrefix(strings.TrimPrefix(arg, "-"), "-") + + if c.FlagSet.Lookup(name) != nil { + c.Args = append(c.Args, arg) + expectValue = true + } else { + result = append(result, arg) + } + } + + return result +} + // parseValue parses a reflect.Value object and extracts cli definitions func (c *Command) parseValue(value reflect.Value) error { var err error diff --git a/cli_test.go b/cli_test.go index 8b25ced..ba6e4d1 100644 --- a/cli_test.go +++ b/cli_test.go @@ -275,6 +275,9 @@ func TestDuration(t *testing.T) { cmd := NewCLI("Config") assert.NoError(cmd.Init(&conf), "init config command") - args := []string{"--interval", "5s"} - assert.NoError(cmd.Parse(args)) + args := []string{"-v", "--interval", "5s", "help"} + + assert.ElementsMatch([]string{"-v", "help"}, cmd.Capture(args)) + assert.ElementsMatch([]string{"--interval", "5s"}, cmd.Args) + assert.NoError(cmd.Parse(cmd.Args)) }