refactor around config parsing

This commit is contained in:
A.Unger
2021-11-02 14:19:14 +01:00
parent 10731c3878
commit ab1703c2e8
5 changed files with 82 additions and 51 deletions
@@ -1,7 +0,0 @@
log:
level: info
color: true
pretty: true
repo:
cs3:
provider_addr: "localhost:9214"
+1 -20
View File
@@ -4,9 +4,6 @@ import (
"context"
"os"
gofig "github.com/gookit/config/v2"
gooyaml "github.com/gookit/config/v2/yaml"
"github.com/owncloud/ocis/accounts/pkg/config"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
@@ -76,23 +73,7 @@ func NewLogger(cfg *config.Config) log.Logger {
// ParseConfig loads accounts configuration from known paths.
func ParseConfig(c *cli.Context, cfg *config.Config) error {
// create a new config and load files and env values onto it since this needs to be thread-safe.
cnf := gofig.NewWithOptions("accounts", gofig.ParseEnv)
// TODO(refs) add ENV + toml + json
cnf.AddDriver(gooyaml.Driver)
// TODO(refs) load from expected locations with the expected name
err := cnf.LoadFiles("/Users/aunger/code/owncloud/ocis/accounts/pkg/command/accounts_example_config.yaml")
if err != nil {
// we have to swallow the error, since it is not mission critical a
// config file is missing and default values are loaded instead.
//return err
}
err = cnf.BindStruct("", cfg)
return nil
return ociscfg.BindSourcesToStructs("accounts", cfg)
}
// SutureService allows for the accounts command to be embedded and supervised by a suture supervisor tree.
+80
View File
@@ -0,0 +1,80 @@
package config
import (
"io/fs"
"os"
"path/filepath"
"strings"
gofig "github.com/gookit/config/v2"
gooyaml "github.com/gookit/config/v2/yaml"
)
var (
defaultLocations = []string{
filepath.Join(os.Getenv("HOME"), "/.ocis/config"),
"/etc/ocis",
".config/",
}
// supportedExtensions is determined by gookit/config. For the purposes of the PR MVP we will focus on yaml, looking
// into extending it to all supported drivers.
supportedExtensions = []string{
"yaml",
"yml",
}
)
// DefaultConfigSources returns a slice with matched expected config files. It sugars coat several aspects of config file
// management by assuming there are 3 default locations a config file could be.
// It uses globbing to match a config file by name, and retrieve any supported extension supported by our drivers.
// It sanitizes the output depending on the list of drivers provided.
func DefaultConfigSources(filename string, drivers []string) []string {
var sources []string
for i := range defaultLocations {
_fs := os.DirFS(defaultLocations[i])
pattern := filename + ".*"
matched, _ := fs.Glob(_fs, pattern)
if len(matched) > 0 {
// prepend path to results
for j := 0; j < len(matched); j++ {
matched[j] = filepath.Join(defaultLocations[i], matched[j])
}
}
sources = append(sources, matched...)
}
return sanitizeExtensions(sources, drivers, func(a, b string) bool {
return strings.HasSuffix(filepath.Base(a), b)
})
}
// sanitizeExtensions removes elements from "set" which extensions are not in "ext".
func sanitizeExtensions(set []string, ext []string, f func(a, b string) bool) []string {
var r []string
for i := 0; i < len(set); i++ {
for j := 0; j < len(ext); j++ {
if f(filepath.Base(set[i]), ext[j]) {
r = append(r, set[i])
}
}
}
return r
}
// BindSourcesToStructs assigns any config value from a config file / env variable to struct `dst`. Its only purpose
// is to solely modify `dst`, not dealing with the config structs; and do so in a thread safe manner.
func BindSourcesToStructs(extension string, dst interface{}) error {
sources := DefaultConfigSources(extension, supportedExtensions)
cnf := gofig.NewWithOptions("proxy", gofig.ParseEnv)
cnf.AddDriver(gooyaml.Driver)
_ = cnf.LoadFiles(sources...)
err := cnf.BindStruct("", &dst)
if err != nil {
return err
}
return nil
}
@@ -1,6 +0,0 @@
log:
level: info
color: true
pretty: true
http:
addr: "${PROXY_HTTP_ADDR|localhost:2222}"
+1 -18
View File
@@ -4,8 +4,6 @@ import (
"context"
"os"
gofig "github.com/gookit/config/v2"
gooyaml "github.com/gookit/config/v2/yaml"
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/version"
@@ -69,22 +67,7 @@ func NewLogger(cfg *config.Config) log.Logger {
// ParseConfig loads proxy configuration from known paths.
func ParseConfig(c *cli.Context, cfg *config.Config) error {
// create a new config and load files and env values onto it since this needs to be thread-safe.
cnf := gofig.NewWithOptions("proxy", gofig.ParseEnv)
// TODO(refs) add ENV + toml + json
cnf.AddDriver(gooyaml.Driver)
// TODO(refs) load from expected locations with the expected name
err := cnf.LoadFiles("/Users/aunger/code/owncloud/ocis/proxy/pkg/command/proxy_example_config.yaml")
if err != nil {
return err
}
// bind all keys to cfg, as we expect an entire proxy.[yaml, toml...] to define all keys and not only sub values.
err = cnf.BindStruct("", cfg)
return nil
return ociscfg.BindSourcesToStructs("proxy", cfg)
}
// SutureService allows for the proxy command to be embedded and supervised by a suture supervisor tree.