summaryrefslogtreecommitdiff
path: root/internal/config
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-09-21 14:03:45 +0300
committerPaul Buetow <paul@buetow.org>2024-09-21 14:03:45 +0300
commitdff4d455e07d639b82a0bed814f41d0656e9b6d0 (patch)
tree56289a6fd80a00a9724992ab9cb8b3d7215ebedf /internal/config
parent780ade3dc066afb8a43be824373414f3d316ebd6 (diff)
cleanup
Diffstat (limited to 'internal/config')
-rw-r--r--internal/config/client/client.go41
-rw-r--r--internal/config/config.go38
-rw-r--r--internal/config/config_test.go195
-rw-r--r--internal/config/enver.go104
-rw-r--r--internal/config/server/mastodon.go1
-rw-r--r--internal/config/server/secrets.go44
-rw-r--r--internal/config/server/server.go62
7 files changed, 0 insertions, 485 deletions
diff --git a/internal/config/client/client.go b/internal/config/client/client.go
deleted file mode 100644
index f551686..0000000
--- a/internal/config/client/client.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package client
-
-import (
- "fmt"
- "log"
- "os"
-
- "codeberg.org/snonux/gos/internal/config"
-)
-
-type ClientConfig struct {
- Servers []string `json:"Servers,omitempty"`
- APIKey string `json:"APIKey,omitempty"`
- Editor string `json:"Editor,omitempty"`
- DataDir string `json:"StateDir,omitempty"`
- ComposeFile string `json:"ComposeFile,omitempty"`
- LogFile string `json:"LogFile,omitempty"`
-}
-
-func New(configFile string) (ClientConfig, error) {
- conf, err := config.FromFile[ClientConfig](configFile)
- if err != nil {
- if _, ok := err.(*os.PathError); !ok {
- return conf, err
- }
- log.Println("Skipping config file:", err)
- }
-
- conf.Servers = config.StrSlice("GOS_SERVERS", conf.Servers)
- conf.APIKey = config.Str("GOS_API_KEY", conf.APIKey)
- conf.Editor = config.Str("GOS_EDITOR", "EDITOR", conf.Editor, "vi")
-
- defaultDataDir := fmt.Sprintf("%s/.gos/data", os.Getenv("HOME"))
- conf.DataDir = config.Str("GOS_DATA_DIR", conf.DataDir, defaultDataDir)
- conf.ComposeFile = config.Str("GOS_COMPOSE_FILE", conf.ComposeFile, "compose.txt")
-
- defaultLogFile := fmt.Sprintf("%s/.gos/gos.log", os.Getenv("HOME"))
- conf.LogFile = config.Str("GOS_LOG_FILE", conf.LogFile, defaultLogFile)
-
- return conf, nil
-}
diff --git a/internal/config/config.go b/internal/config/config.go
deleted file mode 100644
index 6f697e7..0000000
--- a/internal/config/config.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package config
-
-import (
- "encoding/json"
- "io"
- "os"
- "unicode"
-)
-
-func FromFile[T any](configFile string) (T, error) {
- var conf T
-
- 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)
- return conf, err
-}
-
-func isAllUpperCase(s string) bool {
- for _, r := range s {
- if unicode.IsLetter(r) && !unicode.IsUpper(r) {
- return false
- }
- if unicode.IsDigit(r) {
- return false
- }
- }
- return true
-}
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
deleted file mode 100644
index eca163f..0000000
--- a/internal/config/config_test.go
+++ /dev/null
@@ -1,195 +0,0 @@
-package config
-
-import (
- "os"
- "slices"
- "testing"
-)
-
-func TestEnvToStr(t *testing.T) {
- t.Parallel()
-
- os.Unsetenv("NON_EXISTENT_ENV")
- os.Setenv("GOS_TEST_FROM_ENV", "foobarbaz")
-
- var (
- expected = "foobarbaz"
- got = Str("GOS_TEST_FROM_ENV")
- )
-
- if got != expected {
- t.Errorf("got '%s' but expected '%s'", got, expected)
- }
-
- expected = "default value"
- got = Str("NON_EXISTENT_ENV", expected)
- if got != expected {
- t.Errorf("got '%s' but expected '%s'", got, expected)
- }
-
- if got = Str("NON_EXISTENT_ENV"); got != "" {
- t.Errorf("got '%s' but expected empty string", got)
- }
-
- expected = "casio g-shock"
- os.Setenv("GOS_WATCH", expected)
- got = Str("GOS_WATCH", "", "", "", expected, "")
- if got != expected {
- t.Errorf("got '%s' but expected '%s'", got, expected)
- }
-}
-
-func TestEnvToStrSlice(t *testing.T) {
- t.Parallel()
-
- os.Setenv("GOS_TEST_SLICE_FROM_ENV", "foo,bar,baz")
-
- var (
- expected = []string{"foo", "bar", "baz"}
- got = StrSlice("GOS_TEST_SLICE_FROM_ENV")
- )
- if !slices.Equal(got, expected) {
- t.Errorf("got '%v' but expected '%v'", got, expected)
- }
-
- expected = []string{"default value"}
- got = StrSlice("NON_EXISTENT_ENV_SLICE", "default value")
- if !slices.Equal(got, expected) {
- t.Errorf("got '%v' but expected '%v'", got, expected)
- }
-
- os.Unsetenv("NON_EXISTENT_ENV")
- if got = StrSlice("NON_EXISTENT_ENV"); len(got) > 0 {
- t.Errorf("got '%s' of len '%d' but expected empty slice", got, len(got))
- }
-
- expected = []string{"casio", "g-shock"}
- got = StrSlice("NON_EXISTENT_ENV", "", "", "", "casio,g-shock", "")
- if !slices.Equal(got, expected) {
- t.Errorf("got '%v' but expected '%v'", got, expected)
- }
-}
-
-func TestEnvToInt(t *testing.T) {
- t.Parallel()
-
- os.Unsetenv("NON_EXISTENT_ENV")
- os.Setenv("GOS_TEST_INT_FROM_ENV", "1")
-
- var (
- expected = 1
- got = Int(t, "GOS_TEST_INT_FROM_ENV")
- )
-
- if got != expected {
- t.Errorf("got '%d' but expected '%d'", got, expected)
- }
-
- expected = 999
- got = Int("NON_EXISTENT_ENV", expected)
- if got != expected {
- t.Errorf("got '%d' but expected '%d'", got, expected)
- }
-
- if got = Int("NON_EXISTENT_ENV"); got != 0 {
- t.Errorf("got '%d' but expected zero", got)
- }
-
- expected = 1234
- got = Int("GOS_WATCH", "", "", "", expected, "")
- if got != expected {
- t.Errorf("got '%d' but expected '%d'", got, expected)
- }
-}
-
-func TestEnvToBool(t *testing.T) {
- t.Parallel()
-
- os.Unsetenv("NON_EXISTENT_ENV")
- os.Setenv("GOS_TEST_BOOL_FROM_ENV", "true")
-
- var (
- expected = true
- got = Bool("GOS_TEST_BOOL_FROM_ENV")
- )
-
- if got != expected {
- t.Errorf("got '%t' but expected '%t'", got, expected)
- }
-
- expected = false
- got = Bool("NON_EXISTENT_ENV", expected)
- if got != expected {
- t.Errorf("got '%t' but expected '%t'", got, expected)
- }
-
- if got = Bool("NON_EXISTENT_ENV"); got {
- t.Errorf("got '%t' but expected false", got)
- }
-
- expected = true
- got = Bool("NON_EXISTENT_ENV", "", "", "", expected, "")
- if got != expected {
- t.Errorf("got '%t' but expected '%t'", got, expected)
- }
-}
-
-func TestSecondENV(t *testing.T) {
- t.Parallel()
-
- os.Unsetenv("GOS_NONEXISTANT")
- os.Setenv("EDITOR", "hx")
-
- var (
- expected = "hx"
- got = Str("GOS_NONEXISTANT", "EDITOR", "notepad.exe")
- )
-
- if expected != got {
- t.Errorf("got '%s' but expected '%s'", got, expected)
- }
-}
-
-func TestIsAllUpperCase(t *testing.T) {
- if isAllUpperCase("foo_bar") {
- t.Errorf("lowercas letters in test case")
- }
- if isAllUpperCase("FOO123") {
- t.Errorf("numbers in string should not evaluate to is all upper")
- }
- if !isAllUpperCase("FOO_BAR") {
- t.Errorf("should be all upper")
- }
-}
-
-func TestDefaultStrCB(t *testing.T) {
- t.Parallel()
- os.Unsetenv("GOS_NONEXISTANT")
-
- var (
- expected = "hello"
- got = Str("GOS_NONEXISTANT", func() string {
- return "hello"
- })
- )
-
- if expected != got {
- t.Errorf("got '%s' but expected '%s'", got, expected)
- }
-}
-
-func TestDefaultIntCB(t *testing.T) {
- t.Parallel()
- os.Unsetenv("GOS_NONEXISTANT")
-
- var (
- expected = 666
- got = Int("GOS_NONEXISTANT", func() int {
- return 666
- })
- )
-
- if expected != got {
- t.Errorf("got '%d' but expected '%d'", got, expected)
- }
-}
diff --git a/internal/config/enver.go b/internal/config/enver.go
deleted file mode 100644
index f3f8d29..0000000
--- a/internal/config/enver.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package config
-
-import (
- "os"
- "strconv"
- "strings"
-)
-
-type configTypes interface {
- ~int | ~bool | ~string | []string
-}
-
-type enver[T configTypes] interface {
- fromStr(value string) (T, error) // Return T value from input string
- zero() T // Return T's zero value
-}
-
-func Str(keys ...any) string {
- return fromEnv[toStr](keys...)
-}
-
-func StrSlice(keys ...any) []string {
- return fromEnv[toStrSlice](keys...)
-}
-
-func Int(keys ...any) int {
- return fromEnv[toInt](keys...)
-}
-
-func Bool(keys ...any) bool {
- return fromEnv[toBool](keys...)
-}
-
-func fromEnv[U enver[T], T configTypes](keys ...any) T {
- var enver U
-
- for _, key := range keys {
- switch key := key.(type) {
- case string:
- if key == "" {
- continue
- }
- if !isAllUpperCase(key) {
- if val, err := enver.fromStr(key); err == nil {
- return val
- }
- } else if strVal := os.Getenv(key); strVal != "" {
- if val, err := enver.fromStr(strVal); err == nil {
- return val
- }
- }
- case T:
- return key
- case func() T:
- return key()
- }
- }
-
- return enver.zero()
-}
-
-type toStr struct{}
-
-func (toStr) fromStr(str string) (string, error) {
- return str, nil
-}
-
-func (toStr) zero() string {
- return ""
-}
-
-type toStrSlice struct{}
-
-func (s toStrSlice) fromStr(str string) ([]string, error) {
- result := strings.Split(str, ",")
- if len(result) == 1 && result[0] == "" {
- return s.zero(), nil
- }
- return result, nil
-}
-
-func (toStrSlice) zero() []string {
- return []string{}
-}
-
-type toInt struct{}
-
-func (toInt) fromStr(str string) (int, error) {
- return strconv.Atoi(str)
-}
-
-func (toInt) zero() int {
- return 0
-}
-
-type toBool struct{}
-
-func (toBool) fromStr(str string) (bool, error) {
- return strconv.ParseBool(str)
-}
-
-func (toBool) zero() bool {
- return false
-}
diff --git a/internal/config/server/mastodon.go b/internal/config/server/mastodon.go
deleted file mode 100644
index abb4e43..0000000
--- a/internal/config/server/mastodon.go
+++ /dev/null
@@ -1 +0,0 @@
-package server
diff --git a/internal/config/server/secrets.go b/internal/config/server/secrets.go
deleted file mode 100644
index 0e8aab2..0000000
--- a/internal/config/server/secrets.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package server
-
-import (
- "fmt"
- "log"
- "os"
-
- "codeberg.org/snonux/gos/internal/config"
-)
-
-type SecretsConfig struct {
- MastodonEnable bool `json:"MastodonEnable,omitempty"`
- MastodonDomain string `json:"MastodonDomain,omitempty"`
- MastodonAccessToken string `json:"MastodonAccessToken,omitempty"`
-}
-
-func newSecretsConfig(secretsFile string) (SecretsConfig, error) {
- if isWorldReadable(secretsFile) {
- return SecretsConfig{}, fmt.Errorf("config '%s' is world readable", secretsFile)
- }
-
- conf, err := config.FromFile[SecretsConfig](secretsFile)
- if err != nil {
- if _, ok := err.(*os.PathError); !ok {
- return conf, err
- }
- log.Println("Skipping config file:", err)
- }
-
- conf.MastodonEnable = config.Bool("GOS_MASTODON_ENABLE", conf.MastodonEnable)
- conf.MastodonDomain = config.Str("GOS_MASTODON_DOMAIN", conf.MastodonDomain)
- conf.MastodonAccessToken = config.Str("GOS_MASTODON_ACCESS_TOKEN", conf.MastodonAccessToken)
-
- return conf, nil
-}
-
-func isWorldReadable(file string) bool {
- fileInfo, err := os.Stat(file)
- if err != nil {
- return false
- }
-
- return fileInfo.Mode().Perm()&00004 != 0
-}
diff --git a/internal/config/server/server.go b/internal/config/server/server.go
deleted file mode 100644
index 16da14c..0000000
--- a/internal/config/server/server.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package server
-
-import (
- "fmt"
- "log"
- "os"
-
- "codeberg.org/snonux/gos/internal/config"
- "codeberg.org/snonux/gos/internal/types"
-)
-
-type ServerConfig struct {
- ListenAddr string `json:"ListenAddr,omitempty"`
- Partners []string `json:"Partners,omitempty"`
- APIKey string `json:"APIKey,omitempty"`
- DataDir string `json:"StateDir,omitempty"`
- EmailTo string `json:"EmailTo,omitempty"`
- EmailFrom string `json:"EmailFrom,omitempty"`
- SMTPServer string `json:"SMTPServer,omitempty"`
- MergeIntervalS int `json:"MergeInterval,omitempty"`
- ScheduleIntervalS int `json:"ScheduleInterval,omitempty"`
- SocialPlatformsEnabled []string `json:"SocialPlatformsEnabled,omitempty"`
- PostsPerWeek int `json:"PostsPerWeek,omitempty"`
- Secrets SecretsConfig `json:"Secrets,omitempty"`
-}
-
-func New(configFile, secretsFile string) (ServerConfig, error) {
- conf, err := config.FromFile[ServerConfig](configFile)
- if err != nil {
- if _, ok := err.(*os.PathError); !ok {
- return conf, err
- }
- log.Println("Skipping config file:", err)
- }
-
- if conf.Secrets, err = newSecretsConfig(secretsFile); err != nil {
- return conf, err
- }
-
- conf.ListenAddr = config.Str("GOS_LISTEN_ADDR", conf.ListenAddr, "localhost:8080")
- conf.Partners = config.StrSlice("GOS_PARTNERS", conf.Partners)
- conf.APIKey = config.Str("GOS_API_KEY", conf.APIKey)
- conf.DataDir = config.Str("GOS_DATA_DIR", conf.DataDir, "data")
- conf.EmailTo = config.Str("GOS_EMAIL_TO", conf.EmailTo)
- conf.EmailFrom = config.Str("GOS_EMAIL_FROM", conf.EmailFrom)
- conf.SocialPlatformsEnabled = config.StrSlice("GOS_SOCIAL_PLATFORMS_ENABLED",
- []string{types.Mastodon, types.LinkedIn, types.Textfile})
- conf.PostsPerWeek = config.Int("GOS_POSTS_PER_WEEK", conf.PostsPerWeek, 2)
- conf.SMTPServer = config.Str("GOS_SMTP_SERVER", conf.SMTPServer, func() string {
- hostname, err := os.Hostname()
- if err != nil {
- log.Fatal(err)
- }
- return fmt.Sprintf("%s:25", hostname)
- })
-
- const oneHour = 3600
- conf.MergeIntervalS = config.Int("GOS_MERGE_INTERVAL", oneHour)
- conf.ScheduleIntervalS = config.Int("GOS_SCHEDULER_INTERVAL", oneHour*6)
-
- return conf, nil
-}