forked from spf13/viper
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add FlagValue interface to support other flag systems.
Using an interface allows people to use their favourite flag system with viper without being restricted to the semantics of pflag or the standard library. This change introduce two new functions `BindFlagValues` and `BindFlagValue` that behave like `BindFlags` and `BindFlag` but using the new interface as values. This change also introduces two internal structures to transform `*pflag.FlagSet` and `*pflag.Flag` into the new interface. This way, viper keeps working as expected for people that are currently using the pflag package without breaking backwards compatibility. Signed-off-by: David Calavera <[email protected]>
- Loading branch information
Showing
3 changed files
with
159 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package viper | ||
|
||
import "github.com/spf13/pflag" | ||
|
||
// FlagValueSet is an interface that users can implement | ||
// to bind a set of flags to viper. | ||
type FlagValueSet interface { | ||
VisitAll(fn func(FlagValue)) | ||
} | ||
|
||
// FlagValue is an interface that users can implement | ||
// to bind different flags to viper. | ||
type FlagValue interface { | ||
HasChanged() bool | ||
Name() string | ||
ValueString() string | ||
ValueType() string | ||
} | ||
|
||
// pflagValueSet is a wrapper around *pflag.ValueSet | ||
// that implements FlagValueSet. | ||
type pflagValueSet struct { | ||
flags *pflag.FlagSet | ||
} | ||
|
||
// VisitAll iterates over all *pflag.Flag inside the *pflag.FlagSet. | ||
func (p pflagValueSet) VisitAll(fn func(flag FlagValue)) { | ||
p.flags.VisitAll(func(flag *pflag.Flag) { | ||
fn(pflagValue{flag}) | ||
}) | ||
} | ||
|
||
// pflagValue is a wrapper aroung *pflag.flag | ||
// that implements FlagValue | ||
type pflagValue struct { | ||
flag *pflag.Flag | ||
} | ||
|
||
// HasChanges returns whether the flag has changes or not. | ||
func (p pflagValue) HasChanged() bool { | ||
return p.flag.Changed | ||
} | ||
|
||
// Name returns the name of the flag. | ||
func (p pflagValue) Name() string { | ||
return p.flag.Name | ||
} | ||
|
||
// ValueString returns the value of the flag as a string. | ||
func (p pflagValue) ValueString() string { | ||
return p.flag.Value.String() | ||
} | ||
|
||
// ValueType returns the type of the flag as a string. | ||
func (p pflagValue) ValueType() string { | ||
return p.flag.Value.Type() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package viper | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/spf13/pflag" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBindFlagValueSet(t *testing.T) { | ||
flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError) | ||
|
||
var testValues = map[string]*string{ | ||
"host": nil, | ||
"port": nil, | ||
"endpoint": nil, | ||
} | ||
|
||
var mutatedTestValues = map[string]string{ | ||
"host": "localhost", | ||
"port": "6060", | ||
"endpoint": "/public", | ||
} | ||
|
||
for name, _ := range testValues { | ||
testValues[name] = flagSet.String(name, "", "test") | ||
} | ||
|
||
flagValueSet := pflagValueSet{flagSet} | ||
|
||
err := BindFlagValues(flagValueSet) | ||
if err != nil { | ||
t.Fatalf("error binding flag set, %v", err) | ||
} | ||
|
||
flagSet.VisitAll(func(flag *pflag.Flag) { | ||
flag.Value.Set(mutatedTestValues[flag.Name]) | ||
flag.Changed = true | ||
}) | ||
|
||
for name, expected := range mutatedTestValues { | ||
assert.Equal(t, Get(name), expected) | ||
} | ||
} | ||
|
||
func TestBindFlagValue(t *testing.T) { | ||
var testString = "testing" | ||
var testValue = newStringValue(testString, &testString) | ||
|
||
flag := &pflag.Flag{ | ||
Name: "testflag", | ||
Value: testValue, | ||
Changed: false, | ||
} | ||
|
||
flagValue := pflagValue{flag} | ||
BindFlagValue("testvalue", flagValue) | ||
|
||
assert.Equal(t, testString, Get("testvalue")) | ||
|
||
flag.Value.Set("testing_mutate") | ||
flag.Changed = true //hack for pflag usage | ||
|
||
assert.Equal(t, "testing_mutate", Get("testvalue")) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters