add config loader
This commit is contained in:
parent
cae32c512c
commit
7bd6e4d49f
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
|||
module gitea.meta-tech.academy/go/config-loader
|
||||
|
||||
go 1.20
|
||||
|
||||
require gopkg.in/yaml.v3 v3.0.1
|
3
go.sum
Normal file
3
go.sum
Normal file
|
@ -0,0 +1,3 @@
|
|||
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=
|
110
loader.go
Normal file
110
loader.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Cfg interface {
|
||||
GetVar() []VarConfig
|
||||
}
|
||||
|
||||
type VarConfig struct {
|
||||
Name string `yaml:"name"`
|
||||
Value string `yaml:"value"`
|
||||
}
|
||||
|
||||
type ConfigLoader struct {
|
||||
Var []VarConfig
|
||||
Config interface{}
|
||||
varDef *VarPattern
|
||||
refstr []*reflect.Value
|
||||
}
|
||||
|
||||
func LoadConfig(path string, out Cfg, varPattern *VarPattern) {
|
||||
cl := &ConfigLoader{varDef: varPattern, refstr: []*reflect.Value{}}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err = yaml.Unmarshal(data, out); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cl.Var = out.GetVar()
|
||||
cl.Config = out
|
||||
cl.parse()
|
||||
cl.refstr = []*reflect.Value{}
|
||||
// cl.setConfigPtr(outi)
|
||||
}
|
||||
|
||||
func (cl *ConfigLoader) findVarName(match string) string {
|
||||
re := regexp.MustCompile(cl.varDef.getPatternCaptureName())
|
||||
parts := re.FindStringSubmatch(match)
|
||||
if len(parts) > 0 {
|
||||
match = parts[1]
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
func (cl *ConfigLoader) findVarValue(v string) string {
|
||||
names := strings.SplitN(v, ".", 2)
|
||||
if names[0] == "var" {
|
||||
for _, varConfig := range cl.Var {
|
||||
if varConfig.Name == names[1] {
|
||||
v = varConfig.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (cl *ConfigLoader) findStringRef(ref reflect.Value) {
|
||||
switch ref.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
cl.findStringRef(ref.Elem())
|
||||
case reflect.Struct:
|
||||
for i := 0; i < ref.NumField(); i++ {
|
||||
refc := ref.Field(i)
|
||||
cl.findStringRef(refc)
|
||||
}
|
||||
case reflect.Slice:
|
||||
if !ref.IsNil() {
|
||||
for i := 0; i < ref.Len(); i++ {
|
||||
refc := ref.Index(i)
|
||||
cl.findStringRef(refc)
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
if ref.Len() > 0 {
|
||||
cl.refstr = append(cl.refstr, &ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *ConfigLoader) parse() {
|
||||
var name string
|
||||
var tmp string
|
||||
var parts []string
|
||||
var re2 *regexp.Regexp
|
||||
|
||||
cl.findStringRef(reflect.ValueOf(&cl))
|
||||
|
||||
re := regexp.MustCompile(cl.varDef.getPatternVar())
|
||||
for _, ref := range cl.refstr {
|
||||
tmp = ref.String()
|
||||
parts = re.FindStringSubmatch(tmp)
|
||||
if len(parts) > 0 {
|
||||
s := strings.SplitAfter(parts[1], cl.varDef.Close)
|
||||
for _, part := range s {
|
||||
name = cl.findVarName(part)
|
||||
re2 = regexp.MustCompile(cl.varDef.getPatternVarName(name))
|
||||
tmp = re2.ReplaceAllString(tmp, cl.findVarValue(name))
|
||||
}
|
||||
ref.SetString(tmp)
|
||||
}
|
||||
}
|
||||
}
|
31
varpattern.go
Normal file
31
varpattern.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type VarPattern struct {
|
||||
Open string
|
||||
Close string
|
||||
}
|
||||
|
||||
func (vp *VarPattern) getPatternCaptureName() string {
|
||||
return fmt.Sprintf("%s([^%s]+)%s", regexp.QuoteMeta(vp.Open), regexp.QuoteMeta(string(vp.Close[:1])), regexp.QuoteMeta((vp.Close)))
|
||||
}
|
||||
|
||||
func (vp *VarPattern) getPatternVar() string {
|
||||
return fmt.Sprintf("(%s.+%s)", regexp.QuoteMeta(vp.Open), regexp.QuoteMeta(vp.Close))
|
||||
}
|
||||
|
||||
func (vp *VarPattern) getPatternVarName(name string) string {
|
||||
return fmt.Sprintf("%s%s%s", regexp.QuoteMeta(vp.Open), name, regexp.QuoteMeta(vp.Close))
|
||||
}
|
||||
|
||||
func NewVarPattern(open string, close string) *VarPattern {
|
||||
return &VarPattern{open, close}
|
||||
}
|
||||
|
||||
func DefaultVarPattern() *VarPattern {
|
||||
return NewVarPattern("{%", "%}")
|
||||
}
|
Loading…
Reference in New Issue
Block a user