Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • oss/libraries/go/application/configuration
1 result
Select Git revision
Show changes
Commits on Source (4)
<a name="v1.14.0"></a>
## [v1.14.0] - 2022-10-24
### Add Features
- feat add path value [#1](https://gitlab.schukai.com/oss/libraries/go/application/configuration/issues/1)
### Changes
- chore add licenses
<a name="v1.13.0"></a> <a name="v1.13.0"></a>
## [v1.13.0] - 2022-10-24 ## [v1.13.0] - 2022-10-24
### Bug Fixes ### Bug Fixes
...@@ -152,6 +161,7 @@ ...@@ -152,6 +161,7 @@
<a name="v1.0.0"></a> <a name="v1.0.0"></a>
## v1.0.0 - 2022-09-18 ## v1.0.0 - 2022-09-18
[v1.14.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.13.0...v1.14.0
[v1.13.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.12.0...v1.13.0 [v1.13.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.12.0...v1.13.0
[v1.12.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.11.4...v1.12.0 [v1.12.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.11.4...v1.12.0
[v1.11.4]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.11.3...v1.11.4 [v1.11.4]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.11.3...v1.11.4
......
...@@ -360,6 +360,7 @@ C: ...@@ -360,6 +360,7 @@ C:
}) })
} }
func addSample2() { func addSample2() {
e := &mockFile{} e := &mockFile{}
......
...@@ -23,10 +23,14 @@ github.com/r3labs/diff/v3 v3.0.0 h1:ZhPwNxn9gW5WLPBV9GCYaVbMdLOSmJ0DeKdCiSbOLUI= ...@@ -23,10 +23,14 @@ github.com/r3labs/diff/v3 v3.0.0 h1:ZhPwNxn9gW5WLPBV9GCYaVbMdLOSmJ0DeKdCiSbOLUI=
github.com/r3labs/diff/v3 v3.0.0/go.mod h1:wCkTySAiDnZao1sZrVTDIzuzgLZ+cNPGn3LC8DlIg5g= github.com/r3labs/diff/v3 v3.0.0/go.mod h1:wCkTySAiDnZao1sZrVTDIzuzgLZ+cNPGn3LC8DlIg5g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
gitlab.schukai.com/oss/libraries/go/application/xflags v1.9.0 h1:bSnwEV56JZQWBQCasMtCLXTkaSgdFhnoefJB4/2KN8c= gitlab.schukai.com/oss/libraries/go/application/xflags v1.9.0 h1:bSnwEV56JZQWBQCasMtCLXTkaSgdFhnoefJB4/2KN8c=
......
...@@ -6,6 +6,7 @@ package configuration ...@@ -6,6 +6,7 @@ package configuration
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"reflect"
"github.com/imdario/mergo" "github.com/imdario/mergo"
"github.com/magiconair/properties" "github.com/magiconair/properties"
...@@ -46,7 +47,7 @@ func importProperties[C any](config *C, reader io.Reader) error { ...@@ -46,7 +47,7 @@ func importProperties[C any](config *C, reader io.Reader) error {
} }
func (s *Settings[C]) importStream(r reader) { func (s *Settings[C]) importStream(r reader, f ...func(n *C)) {
var c C var c C
var err error var err error
...@@ -79,6 +80,12 @@ func (s *Settings[C]) importStream(r reader) { ...@@ -79,6 +80,12 @@ func (s *Settings[C]) importStream(r reader) {
s.errors = append(s.errors, err) s.errors = append(s.errors, err)
} }
if f != nil {
for _, fn := range f {
fn(&c)
}
}
if err := mergo.Merge(&s.config, c); err != nil { if err := mergo.Merge(&s.config, c); err != nil {
s.errors = append(s.errors, err) s.errors = append(s.errors, err)
} }
...@@ -90,6 +97,42 @@ func (s *Settings[C]) importStreams() { ...@@ -90,6 +97,42 @@ func (s *Settings[C]) importStreams() {
} }
} }
func replacePath(p string, c any) {
if reflect.TypeOf(c).Kind() != reflect.Ptr {
panic("c must be a pointer")
}
if reflect.TypeOf(c).Elem().Kind() != reflect.Struct {
panic("c must be a pointer to a struct")
}
fields := reflect.VisibleFields(reflect.TypeOf(c).Elem())
for _, field := range fields {
r := reflect.ValueOf(c).Elem().FieldByName(field.Name)
if field.Type.Kind() == reflect.Struct {
if r.CanAddr() {
replacePath(p, r.Addr().Interface())
}
continue
}
_, ok := r.Interface().(pathInterface)
if ok {
if r.CanSet() {
if !path.IsAbs(r.String()) {
r.SetString(path.Join(p, r.String()))
}
}
}
}
}
func (s *Settings[C]) importFiles() { func (s *Settings[C]) importFiles() {
s.fileWatch.Lock() s.fileWatch.Lock()
...@@ -116,7 +159,9 @@ func (s *Settings[C]) importFiles() { ...@@ -116,7 +159,9 @@ func (s *Settings[C]) importFiles() {
} }
r := (io.Reader)(f) r := (io.Reader)(f)
s.importStream(reader{s.files.format, r}) s.importStream(reader{s.files.format, r}, func(c *C) {
replacePath(d, c)
})
f.Close() f.Close()
} }
...@@ -129,7 +174,10 @@ func (s *Settings[C]) importFiles() { ...@@ -129,7 +174,10 @@ func (s *Settings[C]) importFiles() {
continue continue
} }
s.importStream(reader{f.format, r}) s.importStream(reader{f.format, r}, func(c *C) {
d := path.Dir(f.path)
replacePath(d, c)
})
r.Close() r.Close()
} }
......
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package configuration
import (
"bytes"
"github.com/stretchr/testify/assert"
"path"
"testing"
"time"
)
type ConfigIssue1SubStruct struct {
DA PathValue `yaml:"DA"`
}
type ConfigIssue1Struct struct {
A string `yaml:"A"`
B PathValue `yaml:"B"`
C PathValue `yaml:"C"`
D ConfigIssue1SubStruct `yaml:"D"`
}
func addSampleIssue1() {
e := &mockFile{}
content := []byte(
`---
A: "Hello!"
B: "/tmp"
C: "xyz.html"
D:
DA: "tmp.xyz"
...
`)
e.buffer = bytes.NewBuffer(content)
e.FileInfo = mockFileInfo{
name: "test",
size: int64(len(content)),
mode: 0,
mod: time.Now(),
dir: false,
sys: nil,
}
fileSamples = append(fileSamples, fileSample{
file: e,
})
}
func TestIssue1(t *testing.T) {
fileSamples = []fileSample{}
defer func() { fileSamples = nil }()
addSampleIssue1()
defaults := ConfigIssue1Struct{}
mockFs := mockFS{}
c := New(defaults)
c.SetMnemonic("test")
c.SetFileFormat(Yaml)
c.SetFilesystem(mockFs)
// setDefaultdirectories can be returned errors
c.SetDefaultDirectories().ResetErrors()
c.Import()
if c.HasErrors() {
t.Error("Expected not error", c.Errors())
}
assert.Equal(t, c.Config().A, "Hello!")
assert.Equal(t, c.Config().B, PathValue("/tmp"))
if !path.IsAbs(string(c.Config().C)) {
t.Error("Expected absolute path got ", c.Config().C)
}
if !path.IsAbs(string(c.Config().D.DA)) {
t.Error("Expected absolute path got ", c.Config().D.DA)
}
}
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package configuration
import "path"
type pathInterface interface {
String() string
Dir() string
Ext() string
Base() string
}
type PathValue string
func (p PathValue) Dir() string {
return path.Dir(string(p))
}
func (p PathValue) Ext() string {
return path.Ext(string(p))
}
func (p PathValue) String() string {
return string(p)
}
func (p PathValue) Base() string {
return path.Base(string(p))
}
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package configuration
import (
"path"
"testing"
)
func TestPathValue(t *testing.T) {
data := []struct {
path string
expected string
base string
}{
{"/a/b/c", "/a/b", "c"},
{"/a/b/c/", "/a/b/c", "c"}, // trailing slash are ignored
{"/a/b/c/d.txt", "/a/b/c", "d.txt"},
{"/a/b/c/d/", "/a/b/c/d", "d"},
{"/a/b/c/d/e", "/a/b/c/d", "e"},
{"/a/b/../c/d/e", "/a/c/d", "e"},
}
for _, d := range data {
t.Run("Dir-"+d.path, func(t *testing.T) {
p := PathValue(d.path)
if p.Dir() != d.expected {
t.Errorf("Expected %s, got %s", d.expected, p.Dir())
}
})
}
for _, d := range data {
t.Run("Base-"+d.path, func(t *testing.T) {
p := PathValue(d.path)
if p.Base() != d.base {
t.Errorf("Expected %s, got %s", d.base, p.Base())
}
})
}
for _, d := range data {
t.Run("String-"+d.path, func(t *testing.T) {
p := PathValue(d.path)
if p.String() != string(p) {
t.Errorf("Expected %s, got %s", string(p), p.String())
}
})
}
for _, d := range data {
t.Run("Ext-"+d.path, func(t *testing.T) {
p := PathValue(d.path)
if p.Ext() != path.Ext(d.path) {
t.Errorf("Expected %s, got %s", path.Ext(d.path), p.Ext())
}
})
}
}
{"version":"1.13.0"} {"version":"1.14.0"}