Skip to content

Commit

Permalink
allow override configs
Browse files Browse the repository at this point in the history
  • Loading branch information
joesonw committed May 9, 2024
1 parent a766b49 commit dcff70b
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 42 deletions.
28 changes: 14 additions & 14 deletions dotpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import (
"strconv"
)

type getPathPart struct {
key string
index int
type DotPath struct {
Key string
Index int
}

//nolint:gocyclo
func parseDotPath(path string) ([]*getPathPart, error) {
func ParseDotPath(path string) ([]*DotPath, error) {
if path == "" {
return nil, nil
}
var paths []*getPathPart
var paths []*DotPath
curr := ""
isInBracket := false
if path[0] == '.' || path[len(path)-1] == '.' { // cannot start with dot
Expand All @@ -28,13 +28,13 @@ func parseDotPath(path string) ([]*getPathPart, error) {
}

if curr == "" { // no key specified
if len(paths) > 0 && paths[len(paths)-1].key == "" {
if len(paths) > 0 && paths[len(paths)-1].Key == "" {
continue
}
return nil, fmt.Errorf("%s: %w", path, ErrInvalidPath)
}
paths = append(paths, &getPathPart{
key: curr,
paths = append(paths, &DotPath{
Key: curr,
})
curr = ""
continue
Expand All @@ -45,8 +45,8 @@ func parseDotPath(path string) ([]*getPathPart, error) {
return nil, fmt.Errorf("%s: %w", path, ErrInvalidPath)
}
if curr != "" {
paths = append(paths, &getPathPart{
key: curr,
paths = append(paths, &DotPath{
Key: curr,
})
curr = ""
}
Expand All @@ -69,8 +69,8 @@ func parseDotPath(path string) ([]*getPathPart, error) {
}

isInBracket = false
paths = append(paths, &getPathPart{
index: index,
paths = append(paths, &DotPath{
Index: index,
})
curr = ""
continue
Expand All @@ -84,8 +84,8 @@ func parseDotPath(path string) ([]*getPathPart, error) {
}

if curr != "" {
paths = append(paths, &getPathPart{
key: curr,
paths = append(paths, &DotPath{
Key: curr,
})
}

Expand Down
18 changes: 9 additions & 9 deletions dotpath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ import (

var _ = Describe("Dotpath", func() {
It("should parse path a.b[0].c[1].d", func() {
paths, err := parseDotPath("a.b[0].c[1].d")
paths, err := ParseDotPath("a.b[0].c[1].d")
Expect(err).To(BeNil())
Expect(paths).To(HaveLen(6))
Expect(paths[0].key).To(Equal("a"))
Expect(paths[1].key).To(Equal("b"))
Expect(paths[2].index).To(Equal(0))
Expect(paths[3].key).To(Equal("c"))
Expect(paths[4].index).To(Equal(1))
Expect(paths[5].key).To(Equal("d"))
Expect(paths[0].Key).To(Equal("a"))
Expect(paths[1].Key).To(Equal("b"))
Expect(paths[2].Index).To(Equal(0))
Expect(paths[3].Key).To(Equal("c"))
Expect(paths[4].Index).To(Equal(1))
Expect(paths[5].Key).To(Equal("d"))
})

It("should return nil if empty", func() {
paths, err := parseDotPath("")
paths, err := ParseDotPath("")
Expect(err).To(BeNil())
Expect(paths).To(BeNil())
})
})

var _ = DescribeTable("Dotpath failed scenarios", func(path string) {
_, err := parseDotPath(path)
_, err := ParseDotPath(path)
Expect(err).To(MatchError(path + ": invalid path"))
},
dotPathEntry(".b"),
Expand Down
9 changes: 9 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package gofigure

import (
"fmt"
)

func newNodeError(node *Node, err error) error {
return fmt.Errorf("%d:%d@%s: %w", node.line, node.column, node.Filepath(), err)
}
25 changes: 19 additions & 6 deletions feature/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package feature

import (
"context"
"errors"
"fmt"
iofs "io/fs"
"os"
"path/filepath"
"strings"

Expand All @@ -13,12 +15,12 @@ import (
)

type includeFeature struct {
fs iofs.FS
fs []iofs.FS
loadedContents map[string][]byte
loadedNodes map[string]bool
}

func Include(fs iofs.FS) gofigure.Feature {
func Include(fs ...iofs.FS) gofigure.Feature {
return &includeFeature{
fs: fs,
loadedContents: map[string][]byte{},
Expand Down Expand Up @@ -71,11 +73,22 @@ func (f *includeFeature) Resolve(ctx context.Context, loader *gofigure.Loader, n
path := strings.TrimSpace(pathNode.Value())
contents, ok := f.loadedContents[path]
if !ok {
contents, err = iofs.ReadFile(f.fs, path)
if err != nil {
return nil, gofigure.NewNodeError(pathNode, fmt.Errorf("unable to read file %q: %w", path, err))
found := false
for _, fs := range f.fs {
contents, err = iofs.ReadFile(fs, path)
if errors.Is(err, os.ErrNotExist) {
continue
}
if err != nil {
return nil, gofigure.NewNodeError(pathNode, fmt.Errorf("unable to read file %q: %w", path, err))
}
found = true
f.loadedContents[path] = contents
break
}
if !found {
return nil, gofigure.NewNodeError(pathNode, fmt.Errorf("unable to find file %q: %w", path, os.ErrNotExist))
}
f.loadedContents[path] = contents
}

if !parse {
Expand Down
19 changes: 10 additions & 9 deletions loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ func (l *Loader) Load(name string, contents []byte) error {

// root node is a document node, and the first child is a map holds all the values
fileNode := NewNode(yamlNode.Content[0], NodeFilepath(name))
name = strings.TrimSuffix(name, filepath.Ext(name))
names := strings.Split(name, string(filepath.Separator))
// nest the file with its path, e.g, config/app.yaml -> config.app
fileNode = PackNodeInNestedKeys(fileNode, names...)
if name != "" {
names := strings.Split(name, string(filepath.Separator))
// nest the file with its path, e.g, config/app.yaml -> config.app
fileNode = PackNodeInNestedKeys(fileNode, names...)
}

if l.root == nil {
l.root = fileNode
Expand Down Expand Up @@ -68,7 +69,7 @@ func (l *Loader) Get(ctx context.Context, path string, target any) error {
func (l *Loader) GetNode(ctx context.Context, path string) (*Node, error) {
current := l.root
if len(path) > 0 {
paths, err := parseDotPath(path)
paths, err := ParseDotPath(path)
if err != nil {
return nil, fmt.Errorf("unable to parse path %q: %w", path, err)
}
Expand All @@ -77,13 +78,13 @@ func (l *Loader) GetNode(ctx context.Context, path string) (*Node, error) {
if current == nil {
break
}
if p.key != "" { // map
current, err = current.GetMappingChild(p.key)
if p.Key != "" { // map
current, err = current.GetMappingChild(p.Key)
if err != nil {
return nil, err
}
} else { // slice
current, err = current.GetSequenceChild(p.index)
current, err = current.GetSequenceChild(p.Index)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -161,7 +162,7 @@ func (l *Loader) resolve(ctx context.Context, node *Node) (resultNode *Node, ret
result, err := feature.Resolve(ctx, l, node)
if err != nil {
node.resolved = false
return nil, err
return nil, newNodeError(node, err)
}
node.resolvedNode = result
return node, nil
Expand Down
19 changes: 19 additions & 0 deletions loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,23 @@ name: John`))).To(BeNil())
Expect(value).To(Equal("hello world"))
Expect(loader.root.mappingNodes["app"].mappingNodes["value"].value).To(Equal("origin"))
})

It("should override", func() {
loader := New()
Expect(loader.Load("", []byte(`env: dev
name:
first: John
last: Doe`))).To(BeNil())
Expect(loader.root.kind).To(Equal(yaml.MappingNode))
Expect(loader.root.mappingNodes["env"].value).To(Equal("dev"))
Expect(loader.root.mappingNodes["name"].mappingNodes["first"].value).To(Equal("John"))
Expect(loader.root.mappingNodes["name"].mappingNodes["last"].value).To(Equal("Doe"))

Expect(loader.Load("", []byte(`env: test
name:
first: Jane`))).To(BeNil())
Expect(loader.root.mappingNodes["env"].value).To(Equal("test"))
Expect(loader.root.mappingNodes["name"].mappingNodes["first"].value).To(Equal("Jane"))
Expect(loader.root.mappingNodes["name"].mappingNodes["last"].value).To(Equal("Doe"))
})
})
8 changes: 4 additions & 4 deletions node.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (n *Node) GetDeep(path string) (*Node, error) {
return n, nil
}

paths, err := parseDotPath(path)
paths, err := ParseDotPath(path)
if err != nil {
return nil, fmt.Errorf("unable to parse path %q: %w", path, err)
}
Expand All @@ -142,13 +142,13 @@ func (n *Node) GetDeep(path string) (*Node, error) {
if current == nil {
return nil, nil
}
if p.key != "" { // map
current, err = current.GetMappingChild(p.key)
if p.Key != "" { // map
current, err = current.GetMappingChild(p.Key)
if err != nil {
return nil, err
}
} else { // slice
current, err = current.GetSequenceChild(p.index)
current, err = current.GetSequenceChild(p.Index)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit dcff70b

Please sign in to comment.