Skip to content

Commit

Permalink
add support for resolving YAML aliases (#415)
Browse files Browse the repository at this point in the history
* add support for resolving YAML aliases

* Add yaml aliases read tests

* Update changelog

---------

Co-authored-by: Tom Wright <contact@tomwright.me>
  • Loading branch information
pmeier and TomWright authored Jun 28, 2024
1 parent 202dfbb commit 5342db0
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed a bug that could cause a panic.
- `type()` now returns `null` instead of `unknown` for null values.
- Added YAML support for merge tag/aliases. Thanks to [pmeier](https://github.com/pmeier). [Issue 285](https://github.com/TomWright/dasel/issues/285).

## [v2.7.0] - 2024-03-14

Expand Down
1 change: 1 addition & 0 deletions dencoding/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
yamlTagInt = "!!int"
yamlTagFloat = "!!float"
yamlTagTimestamp = "!!timestamp"
yamlTagMerge = "!!merge"
)

// YAMLEncoderOption is identifies an option that can be applied to a YAML encoder.
Expand Down
14 changes: 11 additions & 3 deletions dencoding/yaml_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,18 @@ func (decoder *YAMLDecoder) getMappingNodeValue(node *yaml.Node) (any, error) {
keyNode := node.Content[i]
valueNode := node.Content[i+1]

keyValue, err := decoder.getNodeValue(keyNode)
if err != nil {
return nil, err
var keyValue any
if keyNode.ShortTag() == yamlTagMerge {
keyValue = valueNode.Value
valueNode = valueNode.Alias
} else {
var err error
keyValue, err = decoder.getNodeValue(keyNode)
if err != nil {
return nil, err
}
}

value, err := decoder.getNodeValue(valueNode)
if err != nil {
return nil, err
Expand Down
54 changes: 53 additions & 1 deletion dencoding/yaml_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"io"
"reflect"
"testing"

"github.com/tomwright/dasel/v2/dencoding"
)

func TestYAMLDecoder_Decode(t *testing.T) {
Expand Down Expand Up @@ -96,4 +97,55 @@ key2: value6
}
})

t.Run("YamlAliases", func(t *testing.T) {
b := []byte(`foo: &foo
bar: 1
baz: "baz"
spam:
ham: "eggs"
<<: *foo
`)

dec := dencoding.NewYAMLDecoder(bytes.NewReader(b))

got := make([]any, 0)
for {
var v any
if err := dec.Decode(&v); err != nil {
if err == io.EOF {
break
}
t.Errorf("unexpected error: %v", err)
return
}
got = append(got, v)
}

fooMap := dencoding.NewMap().
Set("bar", int64(1)).
Set("baz", "baz")
spamMap := dencoding.NewMap().
Set("ham", "eggs").
Set("foo", fooMap)

exp := dencoding.NewMap().
Set("foo", fooMap).
Set("spam", spamMap)

if len(got) != 1 {
t.Errorf("expected result len of %d, got %d", 1, len(got))
return
}

gotMap, ok := got[0].(*dencoding.Map)
if !ok {
t.Errorf("expected result to be of type %T, got %T", exp, got[0])
return
}

if !reflect.DeepEqual(exp, gotMap) {
t.Errorf("expected %v, got %v", exp, gotMap)
}
})

}
24 changes: 23 additions & 1 deletion internal/command/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,28 @@ octal: 8`)),
nil,
))

t.Run("Issue285 - YAML alias on read", runTest(
[]string{"-r", "yaml", "-w", "yaml"},
[]byte(`foo: &foo
bar: 1
baz: baz
spam:
ham: eggs
<<: *foo
`),
[]byte(`foo:
bar: 1
baz: baz
spam:
ham: eggs
foo:
bar: 1
baz: baz
`),
nil,
nil,
))

t.Run("OrDefaultString", runTest(
[]string{"-r", "json", "all().orDefault(locale,string(nope))"},
[]byte(`{
Expand Down Expand Up @@ -449,7 +471,7 @@ d.e.f`)),
nil,
nil,
))

t.Run("Issue346", func(t *testing.T) {
t.Run("Select null or default string", runTest(
[]string{"-r", "json", "orDefault(foo,string(nope))"},
Expand Down

0 comments on commit 5342db0

Please sign in to comment.