Skip to content

Commit

Permalink
Add count option for bool flags
Browse files Browse the repository at this point in the history
  • Loading branch information
dearchap authored and Naveen Gogineni committed Mar 23, 2021
1 parent 13ded1e commit 1abf95b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
50 changes: 47 additions & 3 deletions flag_bool.go
@@ -1,6 +1,7 @@
package cli

import (
"errors"
"flag"
"fmt"
"strconv"
Expand All @@ -19,8 +20,49 @@ type BoolFlag struct {
DefaultText string
Destination *bool
HasBeenSet bool
Count int
}

// boolValue needs to implement the boolFlag internal interface in flag
// to be able to capture bool fields and values
// type boolFlag interface {
// Value
// IsBoolFlag() bool
// }
type boolValue struct {
destination *bool
count *int
}

func newBoolValue(val bool, p *bool, count *int) *boolValue {
*p = val
return &boolValue{
destination: p,
count: count,
}
}

func (b *boolValue) Set(s string) error {
v, err := strconv.ParseBool(s)
if err != nil {
err = errors.New("parse error")
}
*b.destination = v
*b.count = *b.count + 1
return err
}

func (b *boolValue) Get() interface{} { return *b.destination }

func (b *boolValue) String() string {
if b.destination != nil {
return strconv.FormatBool(*b.destination)
}
return strconv.FormatBool(false)
}

func (b *boolValue) IsBoolFlag() bool { return true }

// IsSet returns whether or not the flag has been set through env or file
func (f *BoolFlag) IsSet() bool {
return f.HasBeenSet
Expand Down Expand Up @@ -74,11 +116,13 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
}

for _, name := range f.Names() {
var value flag.Value
if f.Destination != nil {
set.BoolVar(f.Destination, name, f.Value, f.Usage)
continue
value = newBoolValue(f.Value, f.Destination, &f.Count)
} else {
value = newBoolValue(f.Value, &f.Value, &f.Count)
}
set.Bool(name, f.Value, f.Usage)
set.Var(value, name, f.Usage)
}

return nil
Expand Down
12 changes: 12 additions & 0 deletions flag_test.go
Expand Up @@ -51,6 +51,18 @@ func TestBoolFlagApply_SetsAllNames(t *testing.T) {
expect(t, v, true)
}

func TestBoolFlagApply_SetsCount(t *testing.T) {
v := false
fl := BoolFlag{Name: "wat", Aliases: []string{"W", "huh"}, Destination: &v}
set := flag.NewFlagSet("test", 0)
_ = fl.Apply(set)

err := set.Parse([]string{"--wat", "-W", "--huh"})
expect(t, err, nil)
expect(t, v, true)
expect(t, fl.Count, 3)
}

func TestFlagsFromEnv(t *testing.T) {
newSetIntSlice := func(defaults ...int) IntSlice {
s := NewIntSlice(defaults...)
Expand Down

0 comments on commit 1abf95b

Please sign in to comment.