mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-09-18 13:22:17 +00:00
Merge pull request #3044 from Shell32-Natsu/element-getter
add GetElementByKey
This commit is contained in:
@@ -57,6 +57,16 @@ type ElementSetter struct {
|
|||||||
Value string `yaml:"value,omitempty"`
|
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) {
|
func (e ElementSetter) Filter(rn *RNode) (*RNode, error) {
|
||||||
if err := ErrorIfInvalid(rn, SequenceNode); err != nil {
|
if err := ErrorIfInvalid(rn, SequenceNode); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -73,6 +83,11 @@ func (e ElementSetter) Filter(rn *RNode) (*RNode, error) {
|
|||||||
if IsMissingOrNull(newNode) || IsEmptyMap(newNode) {
|
if IsMissingOrNull(newNode) || IsEmptyMap(newNode) {
|
||||||
continue
|
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
|
// check if this is the element we are matching
|
||||||
val, err := newNode.Pipe(FieldMatcher{Name: e.Key, StringValue: e.Value})
|
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}
|
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
|
// 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 {
|
type ElementMatcher struct {
|
||||||
Kind string `yaml:"kind,omitempty"`
|
Kind string `yaml:"kind,omitempty"`
|
||||||
|
|
||||||
@@ -180,12 +200,20 @@ type ElementMatcher struct {
|
|||||||
|
|
||||||
// Create will create the Element if it is not found
|
// Create will create the Element if it is not found
|
||||||
Create *RNode `yaml:"create,omitempty"`
|
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) {
|
func (e ElementMatcher) Filter(rn *RNode) (*RNode, error) {
|
||||||
if err := ErrorIfInvalid(rn, yaml.SequenceNode); err != nil {
|
if err := ErrorIfInvalid(rn, yaml.SequenceNode); err != nil {
|
||||||
return nil, err
|
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
|
// SequenceNode Content is a slice of ScalarNodes. Each ScalarNode has a
|
||||||
// YNode containing the primitive data.
|
// 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
|
// cast the entry to a RNode so we can operate on it
|
||||||
elem := NewRNode(rn.Content()[i])
|
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) {
|
if IsFoundOrError(field, err) {
|
||||||
return elem, err
|
return elem, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,47 @@ func TestAppend(t *testing.T) {
|
|||||||
assert.Nil(t, rn)
|
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) {
|
func TestClearField_Fn(t *testing.T) {
|
||||||
node, err := Parse(NodeSampleData)
|
node, err := Parse(NodeSampleData)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user