diff --git a/VERSION b/VERSION index cea0e15..d8ba80f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.6 +v2.0.7 diff --git a/figs.go b/figs.go index 53af31b..6e2be35 100644 --- a/figs.go +++ b/figs.go @@ -74,6 +74,8 @@ func With(opts Options) Plant { problems: make([]error, 0), figs: make(map[string]*figFruit), withered: make(map[string]witheredFig), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, mu: sync.RWMutex{}, mutationsCh: make(chan Mutation), flagSet: flag.NewFlagSet(os.Args[0], flag.ContinueOnError), diff --git a/internals_test.go b/internals_test.go index a879d41..e064697 100644 --- a/internals_test.go +++ b/internals_test.go @@ -17,14 +17,16 @@ func TestTree_checkAndSetFromEnv(t *testing.T) { // create a new fig tree var figs *figTree figs = &figTree{ - harvest: 1, - figs: make(map[string]*figFruit), - tracking: false, - withered: make(map[string]witheredFig), - flagSet: flag.NewFlagSet(os.Args[0], flag.ContinueOnError), - mu: sync.RWMutex{}, - mutationsCh: make(chan Mutation, 1), - filterTests: true, + harvest: 1, + figs: make(map[string]*figFruit), + tracking: false, + withered: make(map[string]witheredFig), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, + flagSet: flag.NewFlagSet(os.Args[0], flag.ContinueOnError), + mu: sync.RWMutex{}, + mutationsCh: make(chan Mutation, 1), + filterTests: true, } // assign an int to k @@ -61,6 +63,8 @@ func TestTree_setValue(t *testing.T) { ConfigFilePath string figs map[string]*figFruit withered map[string]witheredFig + sources map[string]SourceConfig + sourceLocker sync.RWMutex mu sync.RWMutex tracking bool mutationsCh chan Mutation @@ -79,9 +83,11 @@ func TestTree_setValue(t *testing.T) { { name: "Set int value", fields: fields{ - figs: make(map[string]*figFruit), - withered: make(map[string]witheredFig), - mutationsCh: make(chan Mutation, 1), + figs: make(map[string]*figFruit), + withered: make(map[string]witheredFig), + mutationsCh: make(chan Mutation, 1), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, }, args: args{ flagVal: new(int), @@ -93,9 +99,11 @@ func TestTree_setValue(t *testing.T) { { name: "Set string value", fields: fields{ - figs: make(map[string]*figFruit), - withered: make(map[string]witheredFig), - mutationsCh: make(chan Mutation, 1), + figs: make(map[string]*figFruit), + withered: make(map[string]witheredFig), + mutationsCh: make(chan Mutation, 1), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, }, args: args{ flagVal: new(string), @@ -107,9 +115,11 @@ func TestTree_setValue(t *testing.T) { { name: "Invalid type", fields: fields{ - figs: make(map[string]*figFruit), - withered: make(map[string]witheredFig), - mutationsCh: make(chan Mutation, 1), + figs: make(map[string]*figFruit), + withered: make(map[string]witheredFig), + mutationsCh: make(chan Mutation, 1), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, }, args: args{ flagVal: new(float32), // Unsupported type @@ -150,13 +160,15 @@ func TestTree_setValue(t *testing.T) { func TestTree_setValuesFromMap(t *testing.T) { tree := &figTree{ - figs: make(map[string]*figFruit), - withered: make(map[string]witheredFig), - mu: sync.RWMutex{}, - tracking: false, - mutationsCh: make(chan Mutation, 1), - flagSet: flag.NewFlagSet(os.Args[0], flag.ContinueOnError), - filterTests: true, + figs: make(map[string]*figFruit), + withered: make(map[string]witheredFig), + sources: make(map[string]SourceConfig), + sourceLocker: sync.RWMutex{}, + mu: sync.RWMutex{}, + tracking: false, + mutationsCh: make(chan Mutation, 1), + flagSet: flag.NewFlagSet(os.Args[0], flag.ContinueOnError), + filterTests: true, } m := map[string]interface{}{ "name": "yahuah", diff --git a/list_flag.go b/list_flag.go index 01231b6..c56344a 100644 --- a/list_flag.go +++ b/list_flag.go @@ -34,12 +34,17 @@ func (l *ListFlag) String() string { return strings.Join(*l.values, ",") } +// PolicyListAppend will apply ListFlag.Set to the list of values and not append to any existing values in the ListFlag +var PolicyListAppend bool = false + // Set unpacks a comma separated value argument and appends items to the list of []string func (l *ListFlag) Set(value string) error { if l.values == nil { l.values = &[]string{} } items := strings.Split(value, ",") - *l.values = append(*l.values, items...) + if PolicyListAppend { + *l.values = append(*l.values, items...) + } return nil } diff --git a/source.go b/source.go new file mode 100644 index 0000000..24f8f18 --- /dev/null +++ b/source.go @@ -0,0 +1,42 @@ +package figtree + +type SourceKind int + +const ( + SourceKindUnknown SourceKind = iota + SourceKindEnv + SourceKindFile + SourceKindFlag + SourceKindFlagEnv +) + +type SourceConfig interface { + Fetch() (string, error) + Kind() SourceKind +} + +func (tree *figTree) WithSource(source SourceConfig) error { + return nil +} + +func (tree *figTree) Source(name string) error { + tree.mu.RLock() + source, exists := tree.sources[name] + tree.mu.RUnlock() + if !exists { + return ErrSourceNotFound{} + } + result, err := source.Fetch() + if err != nil { + return err + } + tree.StoreString(name, result) + + return nil +} + +type ErrSourceNotFound struct{} + +func (e ErrSourceNotFound) Error() string { + return "source not found" +} diff --git a/types.go b/types.go index 4e2476a..e5d2610 100644 --- a/types.go +++ b/types.go @@ -26,6 +26,9 @@ type Plant interface { // Fig returns a figFruit from the figTree by its name Fig(name string) Flesh + // Source runs the attached WithSource against the SourceConfig + Source(name string) error + // WithValidator binds a figValidatorFunc to a figFruit that returns Plant WithValidator(name string, validator func(interface{}) error) Plant @@ -142,6 +145,8 @@ type figTree struct { pollinate bool figs map[string]*figFruit withered map[string]witheredFig + sources map[string]SourceConfig + sourceLocker sync.RWMutex mu sync.RWMutex tracking bool problems []error