Skip to content

Commit

Permalink
make only specific keys configurable by validating them (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
craftamap committed Sep 3, 2021
1 parent 2dda3bd commit 3c56a9c
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 5 deletions.
17 changes: 12 additions & 5 deletions cmd/commands/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/craftamap/bb/cmd/options"
"github.com/craftamap/bb/config"
bbgit "github.com/craftamap/bb/git"
"github.com/craftamap/bb/util/logging"
"github.com/kirsle/configdir"
Expand Down Expand Up @@ -37,6 +38,16 @@ func Add(rootCmd *cobra.Command, _ *options.GlobalOptions) {
if Get {
// TODO: code here
} else {
key := args[0]
inputValue := args[1]

newValue, err := config.BbConfigurationValidation.ValidateEntry(key, inputValue)

if err != nil {
logging.Error(fmt.Sprintf("failed to validate %s: %s", inputValue, err))
return
}

var configDirectory string
var filename string
if Local {
Expand Down Expand Up @@ -75,9 +86,6 @@ func Add(rootCmd *cobra.Command, _ *options.GlobalOptions) {
tmpVp.SetConfigFile(path)
tmpVp.ReadInConfig()

key := args[0]
newValue := args[1]

isSetAlready := tmpVp.IsSet(key)
oldValue := tmpVp.Get(key)

Expand Down Expand Up @@ -122,7 +130,6 @@ func Add(rootCmd *cobra.Command, _ *options.GlobalOptions) {
return
}


logging.SuccessExclamation(fmt.Sprintf("Successfully updated configuration %s", path))
}
},
Expand All @@ -137,7 +144,7 @@ func Add(rootCmd *cobra.Command, _ *options.GlobalOptions) {
func copyFileContent(src string, dst string) error {
sourceFileStat, err := os.Stat(src)
if err != nil {
return err
return err
}

if !sourceFileStat.Mode().IsRegular() {
Expand Down
79 changes: 79 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package config

import (
"fmt"
"strings"
)

type Validator func(interface{}) (interface{}, error)

// Enum is just a string of a list
func EnumValidator(validValues ...string) Validator {
return func(inputValue interface{}) (interface{}, error) {
_, ok := inputValue.(string)
if !ok {
return "", fmt.Errorf("value \"%s\" is not a string, but of type %T", inputValue, inputValue)
}
isInList := false
for _, validValue := range validValues {
if inputValue == validValue {
isInList = true
break
}
}
if !isInList {
return "", fmt.Errorf("value \"%s\" is not a valid value. Valid Values are %s", inputValue, validValues)
}

return inputValue, nil
}
}

// SimpleStringValidator validates if a input is a "simple" string - only single-line strings are supported
func SimpleStringValidator() Validator {
return func(inputValue interface{}) (interface{}, error) {
_, ok := inputValue.(string)
if !ok {
return "", fmt.Errorf("value \"%s\" is not a string, but of type %T", inputValue, inputValue)
}

if strings.ContainsAny(inputValue.(string), "\r\n") {
return "", fmt.Errorf("value \"%s\" contains illegal line break", inputValue)
}

return inputValue, nil
}
}

// Entry contains all the data required for Validation and Convertion
type Entry struct {
Validator Validator
}

type Configuration map[string]Entry

func (c Configuration) ValidateEntry(key string, value interface{}) (interface{}, error) {
e, ok := c[key]
if !ok {
return "", fmt.Errorf("key \"%s\" is not a valid key", key)
}
return e.Validator(value)
}

var BbConfigurationValidation Configuration = map[string]Entry{
"username": {
Validator: SimpleStringValidator(),
},
"password": {
Validator: SimpleStringValidator(),
},
"remote": {
Validator: SimpleStringValidator(),
},
"git_protocol": {
Validator: EnumValidator("ssh", "https"),
},
"sync-method": {
Validator: EnumValidator("merge", "rebase"),
},
}

0 comments on commit 3c56a9c

Please sign in to comment.