~mna/webparts-flag

cc751e643bdb42732c11231ead1bf654f2b45ca8 — Martin Angers 4 years ago 3c18849 master
support flags after non-flag arguments
2 files changed, 61 insertions(+), 17 deletions(-)

M flag.go
M flag_test.go
M flag.go => flag.go +41 -17
@@ 72,6 72,8 @@ func (p *Parser) Parse(args []string, v interface{}) error {
	return nil
}

var durationType = reflect.TypeOf(time.Duration(0))

func (p *Parser) parseFlags(args []string, v interface{}) error {
	if len(args) == 0 {
		return nil


@@ 83,8 85,6 @@ func (p *Parser) parseFlags(args []string, v interface{}) error {
	fs.SetOutput(ioutil.Discard)
	fs.Usage = nil

	durationType := reflect.TypeOf(time.Duration(0))

	// extract the flags from the struct
	val := reflect.ValueOf(v).Elem()
	str := reflect.TypeOf(v).Elem()


@@ 116,26 116,50 @@ func (p *Parser) parseFlags(args []string, v interface{}) error {
		}
	}

	if err := fs.Parse(args[1:]); err != nil {
		return err
	var (
		nonFlags []string
		flagSet  map[string]bool
	)
	args = args[1:]
	for len(args) > 0 {
		if err := fs.Parse(args); err != nil {
			return err
		}

		args = nil
		curNonFlags := fs.Args()
		for i, nf := range curNonFlags {
			if nf == "--" {
				// ignore this one, but treat all subsequent as non-flags
				nonFlags = append(nonFlags, curNonFlags[i+1:]...)
				break
			}
			if ((strings.HasPrefix(nf, "-") && len(nf) > 1) ||
				(strings.HasPrefix(nf, "--") && len(nf) > 2)) &&
				!strings.HasPrefix(nf, "---") {

				// this is a flag, stop non-flags here
				args = curNonFlags[i:]
				break
			}
			nonFlags = append(nonFlags, nf)
		}

		if _, ok := v.(interface{ SetFlags(map[string]bool) }); ok {
			fs.Visit(func(fl *stdflag.Flag) {
				if flagSet == nil {
					flagSet = make(map[string]bool)
				}
				flagSet[fl.Name] = true
			})
		}
	}

	if sa, ok := v.(interface{ SetArgs([]string) }); ok {
		args := fs.Args()
		if len(args) == 0 {
			args = nil
		}
		sa.SetArgs(args)
		sa.SetArgs(nonFlags)
	}
	if sf, ok := v.(interface{ SetFlags(map[string]bool) }); ok {
		set := make(map[string]bool)
		fs.Visit(func(fl *stdflag.Flag) {
			set[fl.Name] = true
		})
		if len(set) == 0 {
			set = nil
		}
		sf.SetFlags(set)
		sf.SetFlags(flagSet)
	}

	return nil

M flag_test.go => flag_test.go +20 -0
@@ 107,6 107,26 @@ func TestParseFlags(t *testing.T) {
			want: &F{},
			err:  "invalid value",
		},
		{
			args: []string{"arg1", "-i", "1", "arg2", "-b"},
			want: &F{
				I:     1,
				B:     true,
				args:  []string{"arg1", "arg2"},
				flags: map[string]bool{"i": true, "b": true},
			},
		},
		{
			args: []string{"arg1", "-z", "arg2"},
			want: &F{},
			err:  "not defined: -z",
		},
		{
			args: []string{"arg1", "--", "-i", "2"},
			want: &F{
				args: []string{"arg1", "-i", "2"},
			},
		},
	}

	var p Parser