summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-05-11 12:20:29 +0300
committerPaul Buetow <paul@buetow.org>2024-05-11 12:20:29 +0300
commit248e4919501a472b90505c0ada6a47113acd6688 (patch)
treea5719a8fb833ec2cd64b15472f13661a5a1dedf9
parentd26c0c93b35cbc12db0c57d546d0426d49bbc1f3 (diff)
add config package
-rw-r--r--internal/config/config.go90
-rw-r--r--internal/config/config_test.go52
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")
+}