Skip to content
Snippets Groups Projects
Verified Commit 158f14bb authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat add path value #1

parent 01a4863d
No related branches found
No related tags found
No related merge requests found
......@@ -360,6 +360,7 @@ C:
})
}
func addSample2() {
e := &mockFile{}
......
......@@ -6,6 +6,7 @@ package configuration
import (
"bytes"
"encoding/json"
"reflect"
"github.com/imdario/mergo"
"github.com/magiconair/properties"
......@@ -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 err error
......@@ -79,6 +80,12 @@ func (s *Settings[C]) importStream(r reader) {
s.errors = append(s.errors, err)
}
if f != nil {
for _, fn := range f {
fn(&c)
}
}
if err := mergo.Merge(&s.config, c); err != nil {
s.errors = append(s.errors, err)
}
......@@ -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() {
s.fileWatch.Lock()
......@@ -116,7 +159,9 @@ func (s *Settings[C]) importFiles() {
}
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()
}
......@@ -129,7 +174,10 @@ func (s *Settings[C]) importFiles() {
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()
}
......
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)
}
}
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))
}
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())
}
})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment