Skip to content

Commit

Permalink
initial LinkFlags() impl
Browse files Browse the repository at this point in the history
  • Loading branch information
gobwas committed Sep 20, 2021
1 parent 18d540a commit 465da5a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
66 changes: 65 additions & 1 deletion flagutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,71 @@ func SetActual(fs *flag.FlagSet, name string) {
}
fs.Set(name, "dummy")
if !didSet {
panic("flagutil: make specified didn't work well")
panic("flagutil: set actual didn't work well")
}
}

// LinkFlags links flags named as n0 and n1 in existing flag set fs.
// If any of the flags doesn't exist LinkFlags() will create one.
func LinkFlags(fs *flag.FlagSet, n0, n1 string) {
var (
u0 string
u1 string
v0 flag.Value
v1 flag.Value
)
f0 := fs.Lookup(n0)
if f0 != nil {
v0 = f0.Value
u0 = f0.Usage
}
f1 := fs.Lookup(n1)
if f1 != nil {
v1 = f1.Value
u1 = f1.Usage
}

usage := mergeUsage(n0+","+n1, u0, u1)

v := value{
doSet: func(s string) (err error) {
if err == nil && v0 != nil {
err = v0.Set(s)
}
if err == nil && v1 != nil {
err = v1.Set(s)
}
return err
},
doIsBoolFlag: func() bool {
if v0 == nil || v1 == nil {
// Can't guess in advance.
return false
}
return isBoolValue(v0) && isBoolValue(v1)
},
doString: func() string {
if v0 == nil || v1 == nil {
// Can't guess in advance.
return ""
}
s0 := v0.String()
s1 := v1.String()
if s0 == s1 {
return s0
}
return ""
},
}
if f0 != nil {
f0.Value = v
} else {
fs.Var(v, n0, usage)
}
if f1 != nil {
f1.Value = v
} else {
fs.Var(v, n1, usage)
}
}

Expand Down
40 changes: 40 additions & 0 deletions flagutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,46 @@ func TestCombineFlags(t *testing.T) {
}
}

func TestLinkFlags(t *testing.T) {
for _, test := range []struct {
name string
flags [2]flag.Flag
}{
{
name: "basic",
flags: [2]flag.Flag{
stringFlag("foo", "def#0", "desc#0"),
stringFlag("bar", "def#1", "desc#1"),
},
},
} {
for i := 0; i < 2; i++ {
t.Run(test.name, func(t *testing.T) {
fs := flag.NewFlagSet("", flag.PanicOnError)
for _, f := range test.flags {
fs.Var(f.Value, f.Name, f.Usage)
}
LinkFlags(fs,
test.flags[0].Name,
test.flags[1].Name,
)

exp := fmt.Sprintf("%x", rand.Int63())
fs.Set(test.flags[i].Name, exp)

for _, f := range test.flags {
if act := f.Value.String(); act != exp {
t.Errorf(
"unexpected flag %q value: %s; want %s",
f.Name, act, exp,
)
}
}
})
}
}
}

func stringFlag(name, def, desc string) flag.Flag {
fs := flag.NewFlagSet("", flag.PanicOnError)
fs.String(name, def, desc)
Expand Down

0 comments on commit 465da5a

Please sign in to comment.