mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-08 05:09:46 -06:00
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package config
|
|
|
|
import (
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
gofig "github.com/gookit/config/v2"
|
|
goojson "github.com/gookit/config/v2/json"
|
|
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.
|
|
supportedExtensions = []string{
|
|
"yaml",
|
|
"yml",
|
|
"json",
|
|
}
|
|
)
|
|
|
|
// 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 {
|
|
dirFS := os.DirFS(defaultLocations[i])
|
|
pattern := filename + ".*"
|
|
matched, _ := fs.Glob(dirFS, 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{}) (*gofig.Config, error) {
|
|
sources := DefaultConfigSources(extension, supportedExtensions)
|
|
cnf := gofig.NewWithOptions(extension)
|
|
cnf.WithOptions(func(options *gofig.Options) {
|
|
options.DecoderConfig.TagName = "ocisConfig"
|
|
})
|
|
cnf.AddDriver(gooyaml.Driver)
|
|
cnf.AddDriver(goojson.Driver)
|
|
_ = cnf.LoadFiles(sources...)
|
|
|
|
err := cnf.BindStruct("", &dst)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return cnf, nil
|
|
}
|