diff options
| author | Paul Buetow <paul@buetow.org> | 2024-05-11 12:20:29 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-05-11 12:20:29 +0300 |
| commit | 248e4919501a472b90505c0ada6a47113acd6688 (patch) | |
| tree | a5719a8fb833ec2cd64b15472f13661a5a1dedf9 | |
| parent | d26c0c93b35cbc12db0c57d546d0426d49bbc1f3 (diff) | |
add config package
| -rw-r--r-- | internal/config/config.go | 90 | ||||
| -rw-r--r-- | internal/config/config_test.go | 52 |
2 files changed, 142 insertions, 0 deletions
diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..ab9ee7a --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,90 @@ +package config + +import ( + "encoding/json" + "fmt" + "io" + "log" + "os" + "strings" + "unicode" +) + +type config struct { + EmailTo string `json:"EmailTo,omitempty"` + EmailFrom string `json:"EmailFrom,omitempty"` + SMTPServer string `json:"SMTPServer,omitempty"` + DataDir string `json:"StateDir,omitempty"` + Partner string `json:"Partner,omitempty"` +} + +func newConfig(configFile string) (config, error) { + conf := config{ + EmailTo: fromEnv("EmailTo"), + EmailFrom: fromEnv("EmailFrom"), + SMTPServer: fromEnv("SMTPServer"), + DataDir: fromEnv("DataDir", "data"), + Partner: fromEnv("Partner"), + } + + file, err := os.Open(configFile) + if err != nil { + return conf, err + } + defer file.Close() + + bytes, err := io.ReadAll(file) + if err != nil { + return conf, err + } + + err = json.Unmarshal(bytes, &conf) + if err != nil { + return conf, err + } + + if conf.SMTPServer == "" { + hostname, err := os.Hostname() + if err != nil { + log.Fatal(err) + } + conf.SMTPServer = fmt.Sprintf("%s:25", hostname) + log.Println("Set SMTPServer to " + conf.SMTPServer) + } + + if conf.DataDir == "" { + conf.DataDir = "data" + log.Println("Set data dir to " + conf.DataDir) + } + + return conf, nil +} + +// Set config from envoronment variable if present, e.g. hansWurst from GOS_HANS_WURST +func fromEnv(configKey string, defaultValue ...string) string { + envKey := camelToSnakeWithPrefix("GOS", configKey) + if value := os.Getenv(envKey); value != "" { + return value + } + + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" +} + +// camelToSnaeWithPrefix converts camelCase strings to UPPER_SNAKE_CASE with a prefix. +func camelToSnakeWithPrefix(prefix, s string) string { + var builder strings.Builder + builder.WriteString(strings.ToUpper(prefix)) + builder.WriteRune('_') + + for i, r := range s { + if unicode.IsUpper(r) && i > 0 { + builder.WriteRune('_') + } + builder.WriteRune(unicode.ToUpper(r)) + } + + return builder.String() +} diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..5c429c9 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,52 @@ +package config + +import ( + "os" + "testing" +) + +func TestCamelToSnake(t *testing.T) { + t.Parallel() + + var ( + expected = "GOS_FOO_BAR_BAZ" + got = camelToSnakeWithPrefix("GOS", "fooBarBaz") + ) + + if got != expected { + t.Errorf("got '%s' but expected '%s'", got, expected) + return + } + t.Logf("got '%s' as expected", expected) +} + +func TestFromEnv(t *testing.T) { + t.Parallel() + + os.Setenv("GOS_TEST_FROM_ENV", "foobarbaz") + + var ( + expected = "foobarbaz" + got = fromEnv("testFromEnv") + ) + + if got != expected { + t.Errorf("got '%s' but expected '%s'", got, expected) + return + } + t.Logf("got '%s' as expected", expected) + + expected = "default value" + got = fromEnv("jajaja", expected) + if got != expected { + t.Errorf("got '%s' but expected '%s'", got, expected) + return + } + t.Logf("got '%s' as expected", expected) + + if got = fromEnv("jujuju"); got != "" { + t.Errorf("got '%s' but expected empty string", got) + return + } + t.Logf("got empty string as expected") +} |
