mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
add GetElementByKey
This commit is contained in:
@@ -57,6 +57,16 @@ type ElementSetter struct {
|
||||
Value string `yaml:"value,omitempty"`
|
||||
}
|
||||
|
||||
// isMappingNode returns whether node is a mapping node
|
||||
func (e ElementSetter) isMappingNode(node *RNode) bool {
|
||||
return ErrorIfInvalid(node, yaml.MappingNode) == nil
|
||||
}
|
||||
|
||||
// isMappingSetter returns is this setter intended to set a mapping node
|
||||
func (e ElementSetter) isMappingSetter() bool {
|
||||
return e.Key != "" && e.Value != ""
|
||||
}
|
||||
|
||||
func (e ElementSetter) Filter(rn *RNode) (*RNode, error) {
|
||||
if err := ErrorIfInvalid(rn, SequenceNode); err != nil {
|
||||
return nil, err
|
||||
@@ -73,6 +83,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 mapping.
|
||||
if !e.isMappingNode(newNode) && e.isMappingSetter() {
|
||||
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})
|
||||
@@ -165,8 +180,13 @@ func MatchElement(field, value string) ElementMatcher {
|
||||
return ElementMatcher{FieldName: field, FieldValue: value}
|
||||
}
|
||||
|
||||
func GetElementByKey(key string) ElementMatcher {
|
||||
return ElementMatcher{FieldName: key, MatchAnyValue: true}
|
||||
}
|
||||
|
||||
// ElementMatcher returns the first element from a Sequence matching the
|
||||
// specified field's value.
|
||||
// specified field's value. If there's no match, and no configuration error,
|
||||
// the matcher returns nil, nil.
|
||||
type ElementMatcher struct {
|
||||
Kind string `yaml:"kind,omitempty"`
|
||||
|
||||
@@ -180,12 +200,20 @@ type ElementMatcher struct {
|
||||
|
||||
// Create will create the Element if it is not found
|
||||
Create *RNode `yaml:"create,omitempty"`
|
||||
|
||||
// MatchAnyValue 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.
|
||||
MatchAnyValue 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.MatchAnyValue && 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.
|
||||
@@ -207,7 +235,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.MatchAnyValue {
|
||||
field, err = elem.Pipe(Get(e.FieldName))
|
||||
} else {
|
||||
field, err = elem.Pipe(MatchField(e.FieldName, e.FieldValue))
|
||||
}
|
||||
if IsFoundOrError(field, err) {
|
||||
return elem, err
|
||||
}
|
||||
|
||||
@@ -57,6 +57,47 @@ 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 TestElementMatcherWithNoValue(t *testing.T) {
|
||||
node, err := Parse(`
|
||||
- a: c
|
||||
- b: ""
|
||||
`)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rn, err := node.Pipe(ElementMatcher{FieldName: "b"})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "b: \"\"\n", assertNoErrorString(t)(rn.String()))
|
||||
|
||||
rn, err = node.Pipe(ElementMatcher{FieldName: "a"})
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, rn)
|
||||
|
||||
rn, err = node.Pipe(ElementMatcher{FieldName: "a", MatchAnyValue: true})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "a: c\n", assertNoErrorString(t)(rn.String()))
|
||||
|
||||
_, err = node.Pipe(ElementMatcher{FieldName: "a", FieldValue: "c", MatchAnyValue: true})
|
||||
assert.Errorf(t, err, "FieldValue must be empty when NoValue is set to true")
|
||||
}
|
||||
func TestClearField_Fn(t *testing.T) {
|
||||
node, err := Parse(NodeSampleData)
|
||||
assert.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user