Migrate to go.akpain.net/cfger from homebrew configuration loader

This commit is contained in:
akp 2024-11-09 22:02:06 +00:00
parent 279a90327d
commit af6bb96c4d
No known key found for this signature in database
GPG key ID: CF8D58F3DEB20755
4 changed files with 29 additions and 141 deletions

17
go.mod
View file

@ -3,15 +3,10 @@ module github.com/codemicro/palmatum
go 1.20
require (
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.30.0
)
require (
github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b // indirect
golang.org/x/sys v0.1.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/jmoiron/sqlx v1.4.0
github.com/julienschmidt/httprouter v1.3.0
github.com/mattn/go-sqlite3 v1.14.24
go.akpain.net/cfger v0.2.1
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
gopkg.in/yaml.v3 v3.0.1
)

30
go.sum
View file

@ -1,23 +1,21 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
go.akpain.net/cfger v0.2.1 h1:EXbJqxIAJWuYvYX/HqaG85u2Ikk2Xs1foLTUsnIz7bQ=
go.akpain.net/cfger v0.2.1/go.mod h1:uaeo30IdnyNNBIEAT0SwvGIWGBauxMI+THVbk8L0oTs=
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,6 +1,7 @@
package config
import (
"go.akpain.net/cfger"
"golang.org/x/exp/slog"
)
@ -26,23 +27,23 @@ type Config struct {
}
func Load() (*Config, error) {
cl := new(configLoader)
if err := cl.load("config.yml"); err != nil {
cl := new(cfger.ConfigLoader)
if err := cl.Load("config.yml"); err != nil {
return nil, err
}
conf := &Config{
Debug: asBool(cl.withDefault("debug", false)),
Debug: cl.Get("debug").WithDefault(false).AsBool(),
HTTP: &HTTP{
Host: asString(cl.withDefault("http.host", "127.0.0.1")),
Port: asInt(cl.withDefault("http.port", 8080)),
Host: cl.Get("http.host").WithDefault("127.0.0.1").AsString(),
Port: cl.Get("http.port").WithDefault(8080).AsInt(),
},
Database: &Database{
DSN: asString(cl.withDefault("database.dsn", "website.db")),
DSN: cl.Get("database.dsn").WithDefault("palmatum.db").AsString(),
},
Platform: &Platform{
SitesDirectory: asString(cl.required("platform.sitesDirectory")),
MaxUploadSizeMegabytes: asInt(cl.withDefault("platform.maxUploadSizeMegabytes", 512)),
SitesDirectory: cl.Get("platform.sitesDirectory").Required().AsString(),
MaxUploadSizeMegabytes: cl.Get("platform.maxUploadSizeMegabytes").WithDefault(512).AsInt(),
},
}

View file

@ -1,106 +0,0 @@
package config
import (
"fmt"
"golang.org/x/exp/slog"
"gopkg.in/yaml.v3"
"os"
"regexp"
"strconv"
"strings"
)
type configLoader struct {
rawConfigFileContents map[string]any
lastKey string
}
func (cl *configLoader) load(fname string) error {
cl.rawConfigFileContents = make(map[string]any)
fcont, err := os.ReadFile(fname)
if err != nil {
slog.Warn("cannot load config file", "filename", fname)
return nil
}
if err := yaml.Unmarshal(fcont, &cl.rawConfigFileContents); err != nil {
return fmt.Errorf("unmarshaling config file: %w", err)
}
return nil
}
type optionalItem struct {
item any
found bool
}
var indexedPartRegexp = regexp.MustCompile(`(?m)([a-zA-Z]+)(?:\[(\d+)\])?`)
func (cl *configLoader) get(key string) optionalItem {
// httpcore[2].bananas
cl.lastKey = key
parts := strings.Split(key, ".")
var cursor any = cl.rawConfigFileContents
for _, part := range parts {
components := indexedPartRegexp.FindStringSubmatch(part)
key := components[1]
index, _ := strconv.ParseInt(components[2], 10, 32)
isIndexed := components[2] != ""
item, found := cursor.(map[string]any)[key]
if !found {
return optionalItem{nil, false}
}
if isIndexed {
arr, conversionOk := item.([]any)
if !conversionOk {
slog.Error(fmt.Sprintf("attempted to index non-indexable config item %s", key))
os.Exit(1)
}
cursor = arr[index]
} else {
cursor = item
}
}
return optionalItem{cursor, true}
}
func (cl *configLoader) required(key string) optionalItem {
opt := cl.get(key)
if !opt.found {
slog.Error(fmt.Sprintf("required key %s not found in config file", key))
os.Exit(1)
}
return opt
}
func (cl *configLoader) withDefault(key string, defaultValue any) optionalItem {
opt := cl.get(key)
if !opt.found {
return optionalItem{item: defaultValue, found: true}
}
return opt
}
func asInt(x optionalItem) int {
if !x.found {
return 0
}
return x.item.(int)
}
func asString(x optionalItem) string {
if !x.found {
return ""
}
return x.item.(string)
}
func asBool(x optionalItem) bool {
if !x.found {
return false
}
return x.item.(bool)
}