Skip to content

Commit

Permalink
refactor: add SetValueFunc and case fold region values
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrombley committed Jul 12, 2021
1 parent 3b1c54f commit b5a0d10
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
2 changes: 1 addition & 1 deletion internal/config/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func SetConfigValue(key config.FieldKey, value interface{}) error {
}

// DeleteConfigValue deletes a config value for the given key.
func DeleteConfigValue(key config.FieldKey, value interface{}) error {
func DeleteConfigValue(key config.FieldKey) error {
return config.ConfigStore.DeleteKey(key)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/config/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The set command sets a persistent configuration value for the New Relic CLI.
log.Fatalf("%s is not a valid config field. valid values are %s", key, configAPI.GetValidConfigFieldKeys())
}

if err := configAPI.DeleteConfigValue(config.FieldKey(key), value); err != nil {
if err := configAPI.SetConfigValue(config.FieldKey(key), value); err != nil {
log.Fatal(err)
}

Expand Down
5 changes: 3 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const (
LogLevel FieldKey = "loglevel"
PluginDir FieldKey = "plugindir"
PreReleaseFeatures FieldKey = "prereleasefeatures"
SendUsageData FieldKey = "sendusagedata"
SendUsageData FieldKey = "sendUsageData"

DefaultProfileName = "default"

Expand Down Expand Up @@ -73,7 +73,8 @@ func InitializeCredentialsStore() {
region.US.String(),
region.EU.String(),
),
Default: region.US.String(),
Default: region.US.String(),
SetValueFunc: ToLower(),
},
FieldDefinition{
Key: AccountID,
Expand Down
30 changes: 30 additions & 0 deletions internal/config/json_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,21 @@ type FieldDefinition struct {
// is performed for the underlying value. If the func returns an error, the
// set operation will not succeed.
SetValidationFunc FieldValueValidationFunc

// SetValueFunc is a translation func that is run when a set operation
// is performed for the underlying value. The value provided will be run
// through the func provided and the resulting value will be set.
SetValueFunc FieldValueTranslationFunc
}

// FieldValueValidationFunc is a configurable validation func that will ensure a field
// value conforms to some constraints before being set.
type FieldValueValidationFunc func(key FieldKey, value interface{}) error

// FieldValueTranslationFunc is a configurable translation func that will modify
// a value before setting it in the underlying config instance.
type FieldValueTranslationFunc func(key FieldKey, value interface{}) (interface{}, error)

// IntGreaterThan is a FieldValueValidationFunc ins a validation func that ensures
// the field value is an integer greater than 0.
func IntGreaterThan(greaterThan int) func(key FieldKey, value interface{}) error {
Expand Down Expand Up @@ -117,6 +126,18 @@ func StringInStrings(caseSensitive bool, allowedValues ...string) func(key Field
}
}

// ToLower is a FieldValueTranslationFunc translation func that ensures the provided
// value is case-folded to lowercase before writing to the underlying config.
func ToLower() func(key FieldKey, value interface{}) (interface{}, error) {
return func(key FieldKey, value interface{}) (interface{}, error) {
if s, ok := value.(string); ok {
return strings.ToLower(s), nil
}

return nil, fmt.Errorf("the value %s provided for %s is not a string", value, key)
}
}

// JSONStoreOption is a func for supplying options when creating a new JSONStore.
type JSONStoreOption func(*JSONStore) error

Expand Down Expand Up @@ -391,6 +412,15 @@ func (p *JSONStore) SetWithScope(scope string, key FieldKey, value interface{})
// use the case convention from the field definition
key = v.Key
}

if v.SetValueFunc != nil {
var err error
value, err = v.SetValueFunc(key, value)
if err != nil {
return err
}
}

} else if p.explicitValues {
return fmt.Errorf("key '%s' is not valid, valid keys are: %v", key, p.getConfigValueKeys())
}
Expand Down
23 changes: 23 additions & 0 deletions internal/config/json_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,26 @@ func TestStore_Set_ValidationFunc_StringInStrings_WrongType(t *testing.T) {
require.Error(t, err)
require.Contains(t, err.Error(), "is not a string")
}

func TestStore_Set_ValueFunc_ToLower(t *testing.T) {
f, err := ioutil.TempFile("", "newrelic-cli.config_provider_test.*.json")
require.NoError(t, err)
defer f.Close()

p, err := NewJSONStore(
ConfigureFields(FieldDefinition{
Key: "testString",
SetValueFunc: ToLower(),
}),
PersistToFile(f.Name()),
)
require.NoError(t, err)

err = p.Set("testString", "TEST_VALUE")
require.NoError(t, err)

v, err := p.GetString("testString")
require.NoError(t, err)

require.Equal(t, "test_value", v)
}

0 comments on commit b5a0d10

Please sign in to comment.