Skip to content

Commit

Permalink
add GetElementByKey
Browse files Browse the repository at this point in the history
  • Loading branch information
Shell32-Natsu committed Sep 29, 2020
1 parent 4c48a4f commit 2ba6066
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
30 changes: 29 additions & 1 deletion kyaml/yaml/fns.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ func (e ElementSetter) Filter(rn *RNode) (*RNode, error) {
if IsMissingOrNull(newNode) || IsEmptyMap(newNode) {
continue
}
// keep non-mapping node in the Content when we want to match a key value pair.
if err := ErrorIfInvalid(newNode, yaml.MappingNode); err != nil && e.Key != "" && e.Value != "" {
newContent = append(newContent, elem)
continue
}

// check if this is the element we are matching
val, err := newNode.Pipe(FieldMatcher{Name: e.Key, StringValue: e.Value})
Expand Down Expand Up @@ -165,6 +170,10 @@ func MatchElement(field, value string) ElementMatcher {
return ElementMatcher{FieldName: field, FieldValue: value}
}

func GetElementByKey(key string) ElementMatcher {
return ElementMatcher{FieldName: key, NoValue: true}
}

// ElementMatcher returns the first element from a Sequence matching the
// specified field's value.
type ElementMatcher struct {
Expand All @@ -180,12 +189,20 @@ type ElementMatcher struct {

// Create will create the Element if it is not found
Create *RNode `yaml:"create,omitempty"`

// NoValue indicates that matcher should only consider the key and ignore
// the actual value in the list. FieldValue must be empty when NoValue is
// set to true.
NoValue bool `yaml:"noValue,omitempty"`
}

func (e ElementMatcher) Filter(rn *RNode) (*RNode, error) {
if err := ErrorIfInvalid(rn, yaml.SequenceNode); err != nil {
return nil, err
}
if e.NoValue && e.FieldValue != "" {
return nil, fmt.Errorf("FieldValue must be empty when NoValue is set to true")
}

// SequenceNode Content is a slice of ScalarNodes. Each ScalarNode has a
// YNode containing the primitive data.
Expand All @@ -207,7 +224,18 @@ func (e ElementMatcher) Filter(rn *RNode) (*RNode, error) {
// cast the entry to a RNode so we can operate on it
elem := NewRNode(rn.Content()[i])

field, err := elem.Pipe(MatchField(e.FieldName, e.FieldValue))
// only check mapping node
if err := ErrorIfInvalid(elem, yaml.MappingNode); err != nil {
continue
}

var field *RNode
var err error
if e.NoValue {
field, err = elem.Pipe(Get(e.FieldName))
} else {
field, err = elem.Pipe(MatchField(e.FieldName, e.FieldValue))
}
if IsFoundOrError(field, err) {
return elem, err
}
Expand Down
19 changes: 19 additions & 0 deletions kyaml/yaml/fns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ func TestAppend(t *testing.T) {
assert.Nil(t, rn)
}

func TestGetElementByKey(t *testing.T) {
node, err := Parse(`
- b: c
- i
- d: e
- f: g
- f: h
`)
assert.NoError(t, err)

rn, err := node.Pipe(GetElementByKey("b"))
assert.NoError(t, err)
assert.Equal(t, "b: c\n", assertNoErrorString(t)(rn.String()))

rn, err = node.Pipe(GetElementByKey("f"))
assert.NoError(t, err)
assert.Equal(t, "f: g\n", assertNoErrorString(t)(rn.String()))
}

func TestClearField_Fn(t *testing.T) {
node, err := Parse(NodeSampleData)
assert.NoError(t, err)
Expand Down

0 comments on commit 2ba6066

Please sign in to comment.