fix(configs): refactor config loader to read default, db, configs, args in order
This commit is contained in:
parent
86b2672b01
commit
2f6aa33108
6 changed files with 113 additions and 45 deletions
2
go.mod
2
go.mod
|
@ -10,7 +10,7 @@ require (
|
|||
github.com/gin-gonic/gin v1.7.3
|
||||
github.com/go-playground/validator/v10 v10.9.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/ihexxa/gocfg v0.0.0-20220128082538-9e607ebed51b
|
||||
github.com/ihexxa/gocfg v0.0.1
|
||||
github.com/ihexxa/multipart v0.0.0-20210916083128-8584a3f00d1d
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -48,6 +48,10 @@ github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnn
|
|||
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/ihexxa/gocfg v0.0.0-20220128082538-9e607ebed51b h1:pzx3BC3+v38POQg9sJWhfs/a4xFaJfC0Ar4RRVnFIMo=
|
||||
github.com/ihexxa/gocfg v0.0.0-20220128082538-9e607ebed51b/go.mod h1:oqDTq1ywx4Qi9DdhFwwMHoPCYv6Txrfj2SY5WWcgiJs=
|
||||
github.com/ihexxa/gocfg v0.0.0-20220402060620-c43339e8d159 h1:gKVyKHtTaT9UJHFjMadZEk4KW+RyMLx9N/cIIviF/nk=
|
||||
github.com/ihexxa/gocfg v0.0.0-20220402060620-c43339e8d159/go.mod h1:oqDTq1ywx4Qi9DdhFwwMHoPCYv6Txrfj2SY5WWcgiJs=
|
||||
github.com/ihexxa/gocfg v0.0.1 h1:3zsCHY/SYdqKSoo3pwTBWMgivEB7/ctpPPHL3p43UBg=
|
||||
github.com/ihexxa/gocfg v0.0.1/go.mod h1:oqDTq1ywx4Qi9DdhFwwMHoPCYv6Txrfj2SY5WWcgiJs=
|
||||
github.com/ihexxa/multipart v0.0.0-20210916083128-8584a3f00d1d h1:+v33khYHVDPEuuWO/JE1IzhoIu5uNvEcSs5GmXc5Sjw=
|
||||
github.com/ihexxa/multipart v0.0.0-20210916083128-8584a3f00d1d/go.mod h1:rhOAe/52S/J1fq1VnXvKX8FHuo65I+IcYUozW4M7+wE=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
|
|
|
@ -20,38 +20,41 @@ type Args struct {
|
|||
Configs []string `short:"c" long:"configs" description:"config path"`
|
||||
}
|
||||
|
||||
// LoadCfg loads the default config, the config in database, config files and arguments in order.
|
||||
// All config values will be merged into one, and the latter overwrites the former.
|
||||
// Each config can be part of the whole ServerCfg
|
||||
func LoadCfg(args *Args) (*gocfg.Cfg, error) {
|
||||
defaultCfg, err := DefaultConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg, err := gocfg.New(NewConfig()).Load(gocfg.JSONStr(defaultCfg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg, err = mergeConfigFiles(cfg, args.Configs)
|
||||
tmpCfg := *cfg
|
||||
dbPath, err := getDbPath(&tmpCfg, args.Configs, args.DbPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbPath := cfg.GrabString("Db.DbPath")
|
||||
if args.DbPath != "" {
|
||||
dbPath = args.DbPath
|
||||
_, err := os.Stat(dbPath)
|
||||
if err == nil {
|
||||
cfg, err = mergeDbConfig(cfg, dbPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
} else {
|
||||
fmt.Printf("warning: Database does not exist in (%s), skipped", dbPath)
|
||||
}
|
||||
_, err = os.Stat(dbPath)
|
||||
if err == nil {
|
||||
cfg, err = mergeDbConfig(cfg, dbPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
} else {
|
||||
fmt.Printf("warning: Database does not exist in (%s), skipped", dbPath)
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err = mergeConfigFiles(cfg, args.Configs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mergeArgs(cfg, args)
|
||||
|
@ -83,6 +86,31 @@ func mergeDbConfig(cfg *gocfg.Cfg, dbPath string) (*gocfg.Cfg, error) {
|
|||
return cfg.Load(gocfg.JSONStr(cfgStr))
|
||||
}
|
||||
|
||||
// getDbPath returns db path from arguments, configs, default config in order
|
||||
// this is a little tricky
|
||||
func getDbPath(cfg *gocfg.Cfg, configPaths []string, argDbPath string) (string, error) {
|
||||
if argDbPath != "" {
|
||||
return argDbPath, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
for _, configPath := range configPaths {
|
||||
if strings.HasSuffix(configPath, ".yml") || strings.HasSuffix(configPath, ".yaml") {
|
||||
cfg, err = cfg.Load(gocfg.YAML(configPath))
|
||||
} else if strings.HasSuffix(configPath, ".json") {
|
||||
cfg, err = cfg.Load(gocfg.JSON(configPath))
|
||||
} else {
|
||||
return "", fmt.Errorf("unknown config file type (.yml .yaml .json are supported): %s", configPath)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return cfg.GrabString("Db.DbPath"), nil
|
||||
}
|
||||
|
||||
func mergeConfigFiles(cfg *gocfg.Cfg, configPaths []string) (*gocfg.Cfg, error) {
|
||||
var err error
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package server
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ihexxa/gocfg"
|
||||
|
@ -19,14 +20,28 @@ func TestLoadCfg(t *testing.T) {
|
|||
DbPath: "",
|
||||
Configs: []string{},
|
||||
},
|
||||
// default config + config_1
|
||||
// default config + db
|
||||
&Args{
|
||||
Host: "",
|
||||
Port: 0,
|
||||
DbPath: "testdata/test_quickshare.db",
|
||||
Configs: []string{},
|
||||
},
|
||||
// default config + db + config_1 (dbPath is from config_1)
|
||||
&Args{
|
||||
Host: "",
|
||||
Port: 0,
|
||||
DbPath: "",
|
||||
Configs: []string{"testdata/config_1.yml"},
|
||||
},
|
||||
// default config + config_1 + config_4
|
||||
// // default config + db + config_1 (dbPath is from args)
|
||||
&Args{
|
||||
Host: "",
|
||||
Port: 0,
|
||||
DbPath: "testdata/test_quickshare.db",
|
||||
Configs: []string{"testdata/config_1.yml"},
|
||||
},
|
||||
// default config + db + config_1 + config_4
|
||||
&Args{
|
||||
Host: "",
|
||||
Port: 0,
|
||||
|
@ -45,7 +60,7 @@ func TestLoadCfg(t *testing.T) {
|
|||
"testdata/config_partial_db.yml",
|
||||
},
|
||||
},
|
||||
// default config + config_1 + config_4 + db_partial + args(db)
|
||||
// default config + db + config_1 + config_4 + config_partial_users.yml + config_partial_db.yml + args(db)
|
||||
&Args{
|
||||
Host: "",
|
||||
Port: 0,
|
||||
|
@ -61,6 +76,21 @@ func TestLoadCfg(t *testing.T) {
|
|||
|
||||
cfgDefault := DefaultConfigStruct()
|
||||
|
||||
cfgDBOnly := *cfgDefault
|
||||
cfgDBOnly.Site = &db.SiteConfig{
|
||||
ClientCfg: &db.ClientConfig{
|
||||
SiteName: "Quickshare",
|
||||
SiteDesc: "quick and simple file sharing",
|
||||
Bg: &db.BgConfig{
|
||||
Url: "/static/img/textured_paper.png",
|
||||
Repeat: "repeat",
|
||||
Position: "center",
|
||||
Align: "fixed",
|
||||
BgColor: "#ccc",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg1 := &Config{
|
||||
Fs: &FSConfig{
|
||||
Root: "1",
|
||||
|
@ -111,19 +141,19 @@ func TestLoadCfg(t *testing.T) {
|
|||
},
|
||||
Site: &db.SiteConfig{
|
||||
ClientCfg: &db.ClientConfig{
|
||||
SiteName: "1",
|
||||
SiteDesc: "1",
|
||||
SiteName: "Quickshare",
|
||||
SiteDesc: "quick and simple file sharing",
|
||||
Bg: &db.BgConfig{
|
||||
Url: "1",
|
||||
Repeat: "1",
|
||||
Position: "1",
|
||||
Align: "1",
|
||||
BgColor: "1",
|
||||
Url: "/static/img/textured_paper.png",
|
||||
Repeat: "repeat",
|
||||
Position: "center",
|
||||
Align: "fixed",
|
||||
BgColor: "#ccc",
|
||||
},
|
||||
},
|
||||
},
|
||||
Db: &DbConfig{
|
||||
DbPath: "1",
|
||||
DbPath: "testdata/test_quickshare.db",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -259,7 +289,7 @@ func TestLoadCfg(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
cfgWithDB := &Config{
|
||||
cfgWithPartialCfg := &Config{
|
||||
Fs: &FSConfig{
|
||||
Root: "4",
|
||||
OpensLimit: 4,
|
||||
|
@ -321,16 +351,18 @@ func TestLoadCfg(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Db: &DbConfig{
|
||||
DbPath: "testdata/test_quickshare.db",
|
||||
DbPath: "5",
|
||||
},
|
||||
}
|
||||
|
||||
expects := []*Config{
|
||||
cfgDefault,
|
||||
&cfgDBOnly,
|
||||
cfg1,
|
||||
cfg1,
|
||||
cfg4,
|
||||
cfg5,
|
||||
cfgWithDB,
|
||||
cfgWithPartialCfg,
|
||||
}
|
||||
|
||||
testLoadCfg := func(t *testing.T) {
|
||||
|
@ -351,7 +383,11 @@ func TestLoadCfg(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !Equal(gotCfg, expectCfg) {
|
||||
if !reflect.DeepEqual(gotCfg.Template(), expectCfg.Template()) {
|
||||
gotJSON, _ := gotCfg.JSON()
|
||||
expectJSON, _ := expectCfg.JSON()
|
||||
fmt.Printf("\ngot\n%s\n", gotJSON)
|
||||
fmt.Printf("\nexpected\n%s\n", expectJSON)
|
||||
t.Fatalf("%d, cfgs are not identical", i)
|
||||
}
|
||||
}
|
||||
|
|
22
src/server/testdata/config_1.yml
vendored
22
src/server/testdata/config_1.yml
vendored
|
@ -37,16 +37,16 @@ workers:
|
|||
queueSize: 1
|
||||
sleepCyc: 1
|
||||
workerCount: 1
|
||||
site:
|
||||
clientCfg:
|
||||
siteName: "1"
|
||||
siteDesc: "1"
|
||||
bg:
|
||||
url: "1"
|
||||
repeat: "1"
|
||||
position: "1"
|
||||
align: "1"
|
||||
bgColor: "1"
|
||||
# site:
|
||||
# clientCfg:
|
||||
# siteName: "1"
|
||||
# siteDesc: "1"
|
||||
# bg:
|
||||
# url: "1"
|
||||
# repeat: "1"
|
||||
# position: "1"
|
||||
# align: "1"
|
||||
# bgColor: "1"
|
||||
db:
|
||||
dbPath: "1"
|
||||
dbPath: "testdata/test_quickshare.db"
|
||||
|
||||
|
|
BIN
src/server/testdata/test_quickshare.db
vendored
BIN
src/server/testdata/test_quickshare.db
vendored
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue