parent
c14e0dfcab
commit
55c201b36c
6
Makefile
6
Makefile
|
@ -1,7 +1,7 @@
|
||||||
all: test
|
all: linter test
|
||||||
|
|
||||||
test: linter
|
test:
|
||||||
go test
|
go test ./
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
golangci-lint run
|
golangci-lint run
|
||||||
|
|
15
Readme.md
15
Readme.md
|
@ -1,7 +1,7 @@
|
||||||
# gosimpleconf
|
# gosimpleconf
|
||||||
|
|
||||||
```sh
|
```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.
|
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)
|
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?
|
## Why?
|
||||||
|
|
||||||
I've always seen configuration files similar to this show up in
|
I've always seen configuration files similar to this show up in
|
||||||
|
|
|
@ -2,13 +2,19 @@ package gosimpleconf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"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
|
var err error
|
||||||
|
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
|
@ -17,7 +23,7 @@ func Load(filename string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
parsedMap, err := parse(file)
|
parsedMap, err := parseFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -25,9 +31,42 @@ func Load(filename string) (map[string]string, error) {
|
||||||
return parsedMap, nil
|
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
|
var err error
|
||||||
parsedMap := make(map[string]string)
|
parsedMap := make(ConfigMap)
|
||||||
|
|
||||||
scanner := bufio.NewScanner(config)
|
scanner := bufio.NewScanner(config)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package gosimpleconf
|
package gosimpleconf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -25,7 +26,7 @@ technically valid = haha hmm...
|
||||||
`
|
`
|
||||||
configFile := strings.NewReader(configFileStr)
|
configFile := strings.NewReader(configFileStr)
|
||||||
|
|
||||||
expectedMap := make(map[string]string)
|
expectedMap := make(ConfigMap)
|
||||||
expectedMap["foo"] = "bar"
|
expectedMap["foo"] = "bar"
|
||||||
expectedMap["asdf"] = "1234"
|
expectedMap["asdf"] = "1234"
|
||||||
expectedMap["wat.wat"] = "thing"
|
expectedMap["wat.wat"] = "thing"
|
||||||
|
@ -33,7 +34,7 @@ technically valid = haha hmm...
|
||||||
expectedMap["immaempty"] = ""
|
expectedMap["immaempty"] = ""
|
||||||
expectedMap["technically valid"] = "haha hmm..."
|
expectedMap["technically valid"] = "haha hmm..."
|
||||||
|
|
||||||
parsedMap, err := parse(configFile)
|
parsedMap, err := parseFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed while parsing the file")
|
t.Errorf("failed while parsing the file")
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,7 @@ foo=bar=true
|
||||||
`
|
`
|
||||||
configFile := strings.NewReader(configFileStr)
|
configFile := strings.NewReader(configFileStr)
|
||||||
|
|
||||||
_, err = parse(configFile)
|
_, err = parseFile(configFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("parse did not thrown an error when it was supposed to")
|
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)
|
configFile := strings.NewReader(configFileStr)
|
||||||
|
|
||||||
_, err = parse(configFile)
|
_, err = parseFile(configFile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("parse did not thrown an error when it was supposed to")
|
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) {
|
func validateMap(t *testing.T, given map[string]string, expected map[string]string) {
|
||||||
if given == nil {
|
if given == nil {
|
||||||
t.Errorf("given map was nil")
|
t.Errorf("given map was nil")
|
||||||
|
|
Loading…
Reference in New Issue