-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #84 from osspkg/add-config-resolvers
Add config resolvers
- Loading branch information
Showing
30 changed files
with
347 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Config Resolver | ||
|
||
Updating the config through resolver variables. | ||
|
||
## Config example | ||
|
||
update config via ENV | ||
|
||
```text | ||
@env(key#defaut value) | ||
``` | ||
|
||
```yaml | ||
envs: | ||
home: "@env(HOME#/tmp/home)" | ||
path: "@env(PATH#/usr/local/bin)" | ||
``` | ||
|
||
```go | ||
import ( | ||
"go.osspkg.com/goppy/config" | ||
) | ||
|
||
type ( | ||
ConfigItem struct { | ||
Home string `yaml:"home"` | ||
Path string `yaml:"path"` | ||
} | ||
Config struct { | ||
Envs testConfigItem `yaml:"envs"` | ||
} | ||
) | ||
|
||
func main() { | ||
conf := Config{} | ||
|
||
res := config.NewConfigResolve( | ||
config.EnvResolver(), // env resolver | ||
) | ||
res.OpenFile("./config.yaml") // open config file | ||
res.Build() // prepare config with resolvers | ||
res.Decode(&conf) // decoding config | ||
|
||
fmt.Println(conf.Envs.Home) | ||
fmt.Println(conf.Envs.Path) | ||
} | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright (c) 2022-2024 Mikhail Knyazhev <markus621@yandex.com>. All rights reserved. | ||
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file. | ||
*/ | ||
|
||
package config | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
"regexp" | ||
|
||
"gopkg.in/yaml.v3" | ||
) | ||
|
||
type ( | ||
Resolver interface { | ||
Name() string | ||
Value(name string) (string, bool) | ||
} | ||
|
||
Config struct { | ||
blob []byte | ||
resolvers []Resolver | ||
} | ||
) | ||
|
||
func NewConfigResolve(rs ...Resolver) *Config { | ||
return &Config{ | ||
blob: nil, | ||
resolvers: rs, | ||
} | ||
} | ||
|
||
func (v *Config) OpenFile(filename string) error { | ||
b, err := os.ReadFile(filename) | ||
if err != nil { | ||
return err | ||
} | ||
v.blob = b | ||
return nil | ||
} | ||
|
||
func (v *Config) Decode(cs ...interface{}) error { | ||
for _, c := range cs { | ||
if err := yaml.Unmarshal(v.blob, c); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
var rexName = regexp.MustCompile(`(?m)^[a-z][a-z0-9]+$`) | ||
|
||
func (v *Config) Build() error { | ||
for _, resolver := range v.resolvers { | ||
if !rexName.MatchString(resolver.Name()) { | ||
return fmt.Errorf("resolver '%s' has invalid name, must like regexp [a-z][a-z0-9]+", resolver.Name()) | ||
} | ||
rex := regexp.MustCompile(fmt.Sprintf(`(?mUsi)@%s\((.+)#(.*)\)`, resolver.Name())) | ||
submatchs := rex.FindAllSubmatch(v.blob, -1) | ||
|
||
for _, submatch := range submatchs { | ||
pattern, key, defval := submatch[0], submatch[1], submatch[2] | ||
|
||
if val, ok := resolver.Value(string(key)); ok && len(val) > 0 { | ||
defval = []byte(val) | ||
} | ||
|
||
v.blob = bytes.ReplaceAll(v.blob, pattern, defval) | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (c) 2022-2024 Mikhail Knyazhev <markus621@yandex.com>. All rights reserved. | ||
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file. | ||
*/ | ||
|
||
package config_test | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"go.osspkg.com/goppy/config" | ||
"go.osspkg.com/goppy/xtest" | ||
) | ||
|
||
type ( | ||
testConfigItem struct { | ||
Home string `yaml:"home"` | ||
Path string `yaml:"path"` | ||
} | ||
testConfig struct { | ||
Envs testConfigItem `yaml:"envs"` | ||
} | ||
) | ||
|
||
func TestUnit_ConfigResolve(t *testing.T) { | ||
filename := "/tmp/TestUnit_ConfigResolve.yaml" | ||
data := ` | ||
envs: | ||
home: "@env(HOME#fail)" | ||
path: "@env(PATH#fail)" | ||
` | ||
err := os.WriteFile(filename, []byte(data), 0755) | ||
xtest.NoError(t, err) | ||
|
||
res := config.NewConfigResolve(config.EnvResolver()) | ||
|
||
err = res.OpenFile(filename) | ||
xtest.NoError(t, err) | ||
err = res.Build() | ||
xtest.NoError(t, err) | ||
|
||
tc := &testConfig{} | ||
|
||
err = res.Decode(tc) | ||
xtest.NoError(t, err) | ||
xtest.NotEqual(t, "fail", tc.Envs.Home) | ||
xtest.NotEqual(t, "fail", tc.Envs.Path) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module go.osspkg.com/goppy/config | ||
|
||
go 1.20 | ||
|
||
replace go.osspkg.com/goppy/xtest => ./../xtest | ||
|
||
require ( | ||
go.osspkg.com/goppy/xtest v0.3.0 | ||
gopkg.in/yaml.v3 v3.0.1 | ||
) | ||
|
||
require ( | ||
github.com/kr/pretty v0.3.1 // indirect | ||
github.com/rogpeppe/go-internal v1.10.0 // indirect | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= | ||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= | ||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
Oops, something went wrong.