From 55c201b36cfc555bc2ed109cfce0c5d306197293 Mon Sep 17 00:00:00 2001 From: Sean Hickey Date: Sat, 18 Jun 2022 12:44:10 -0700 Subject: [PATCH] Add ability to override values with cli flags --- Makefile | 6 +++--- Readme.md | 15 +++++++++++++- gosimpleconf.go | 47 ++++++++++++++++++++++++++++++++++++++++---- gosimpleconf_test.go | 43 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 99 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index b9d53b9..f1a96dd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: test +all: linter test -test: linter - go test +test: + go test ./ linter: golangci-lint run diff --git a/Readme.md b/Readme.md index 7c07d96..bd1bbe9 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ # gosimpleconf ```sh -go get gitea.wisellama.rocks/Wisellama/gosimpleconf@v0.0.2 +go get gitea.wisellama.rocks/Wisellama/gosimpleconf@v0.0.3 ``` This is a small library for parsing super simple configuration files. @@ -39,6 +39,19 @@ var piStr string = configMap["pi"] pi, err := strconv.ParseFloat(value, 64) ``` +To override values with cli flags, after parsing the conf file you can +use these functions to also parse the flags: +```go +flagMap := SetupFlagOverrides(configMap) +configMap = ParseFlags(configMap, flagmap) +``` + +Then you could, for example, override the url value without modifying +the config file: +```go +./program --url=newthing.wisellama.rocks +``` + ## Why? I've always seen configuration files similar to this show up in diff --git a/gosimpleconf.go b/gosimpleconf.go index f181f3e..b1eacea 100644 --- a/gosimpleconf.go +++ b/gosimpleconf.go @@ -2,13 +2,19 @@ package gosimpleconf import ( "bufio" + "flag" "fmt" "io" + "log" "os" + "strconv" "strings" ) -func Load(filename string) (map[string]string, error) { +type ConfigMap map[string]string +type FlagMap map[string]*string + +func Load(filename string) (ConfigMap, error) { var err error file, err := os.Open(filename) @@ -17,7 +23,7 @@ func Load(filename string) (map[string]string, error) { } defer file.Close() - parsedMap, err := parse(file) + parsedMap, err := parseFile(file) if err != nil { return nil, err } @@ -25,9 +31,42 @@ func Load(filename string) (map[string]string, error) { return parsedMap, nil } -func parse(config io.Reader) (map[string]string, error) { +func SetupFlagOverrides(configMap ConfigMap) FlagMap { + flagMap := make(FlagMap) + for k, v := range configMap { + f := flag.String(k, v, "") + flagMap[k] = f + } + + return flagMap +} + +func ParseFlags(configMap ConfigMap, flagMap FlagMap) ConfigMap { + flag.Parse() + + for k, v := range flagMap { + if v != nil && len(*v) > 0 { + configMap[k] = *v + } + } + + return configMap + +} + +func Bool(value string) bool { + v, err := strconv.ParseBool(value) + if err != nil { + log.Printf("error parsing bool %v - %v", v, err) + v = false + } + + return v +} + +func parseFile(config io.Reader) (ConfigMap, error) { var err error - parsedMap := make(map[string]string) + parsedMap := make(ConfigMap) scanner := bufio.NewScanner(config) for scanner.Scan() { diff --git a/gosimpleconf_test.go b/gosimpleconf_test.go index 95e981d..44d6e3c 100644 --- a/gosimpleconf_test.go +++ b/gosimpleconf_test.go @@ -1,6 +1,7 @@ package gosimpleconf import ( + "flag" "strings" "testing" ) @@ -25,7 +26,7 @@ technically valid = haha hmm... ` configFile := strings.NewReader(configFileStr) - expectedMap := make(map[string]string) + expectedMap := make(ConfigMap) expectedMap["foo"] = "bar" expectedMap["asdf"] = "1234" expectedMap["wat.wat"] = "thing" @@ -33,7 +34,7 @@ technically valid = haha hmm... expectedMap["immaempty"] = "" expectedMap["technically valid"] = "haha hmm..." - parsedMap, err := parse(configFile) + parsedMap, err := parseFile(configFile) if err != nil { t.Errorf("failed while parsing the file") } @@ -48,7 +49,7 @@ foo=bar=true ` configFile := strings.NewReader(configFileStr) - _, err = parse(configFile) + _, err = parseFile(configFile) if err == nil { t.Errorf("parse did not thrown an error when it was supposed to") } @@ -61,12 +62,46 @@ Something here with no equals to split on ` configFile := strings.NewReader(configFileStr) - _, err = parse(configFile) + _, err = parseFile(configFile) if err == nil { t.Errorf("parse did not thrown an error when it was supposed to") } } +func TestFlagOverrides(t *testing.T) { + var err error + configFileStr := ` +foo=bar +asdf = 1234 +foo.wat =stuff +immaempty= +` + configFile := strings.NewReader(configFileStr) + + expectedMap := make(ConfigMap) + expectedMap["foo"] = "bar" + expectedMap["asdf"] = "1234" + // expect to override the 'foo.wat' value with a cli flag + expectedMap["foo.wat"] = "iwasoverridden" + expectedMap["immaempty"] = "" + + configMap, err := parseFile(configFile) + if err != nil { + t.Errorf("failed while parsing the file") + } + + flagMap := SetupFlagOverrides(configMap) + + err = flag.Set("foo.wat", "iwasoverridden") + if err != nil { + t.Errorf("failed to set cli flag override") + } + + configMap = ParseFlags(configMap, flagMap) + + validateMap(t, configMap, expectedMap) +} + func validateMap(t *testing.T, given map[string]string, expected map[string]string) { if given == nil { t.Errorf("given map was nil")