Skip to content

Commit

Permalink
use field options to refine replacements
Browse files Browse the repository at this point in the history
  • Loading branch information
natasha41575 committed Apr 8, 2021
1 parent f61b075 commit 0d0e6b9
Show file tree
Hide file tree
Showing 3 changed files with 493 additions and 8 deletions.
52 changes: 48 additions & 4 deletions api/filters/replacement/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,44 @@ func rejectId(rejects []*types.Selector, nodeId *types.KrmId) bool {

func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
for _, fp := range target.FieldPaths {
t, err := node.Pipe(yaml.Lookup(strings.Split(fp, ".")...))
fieldPath := strings.Split(fp, ".")
var t *yaml.RNode
var err error
if target.Options != nil && target.Options.Create {
t, err = node.Pipe(yaml.LookupCreate(value.YNode().Kind, fieldPath...))
} else {
t, err = node.Pipe(yaml.Lookup(fieldPath...))
}
if err != nil {
return err
}
if t != nil {
// TODO (#3492): Use the field options to refine interpretation of the field
t.SetYNode(value.YNode())
setTargetValue(target.Options, t, value)
}
}
return nil
}

func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) {
if t.YNode().Kind == yaml.ScalarNode && value.YNode().Kind == yaml.ScalarNode &&
options != nil && options.Delimiter != "" {

tv := strings.Split(t.YNode().Value, options.Delimiter)
v := yaml.GetValue(value)
// TODO: Add a way to remove an element
switch {
case options.Index < 0: // prefix
tv = append([]string{v}, tv...)
case options.Index >= len(tv): // suffix
tv = append(tv, v)
default: // replace an element
tv[options.Index] = v
}
value.YNode().Value = strings.Join(tv, options.Delimiter)
}
t.SetYNode(value.YNode())
}

func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
source, err := selectSourceNode(nodes, r.Source)
if err != nil {
Expand All @@ -93,10 +119,28 @@ func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, err
if err != nil {
return nil, err
}
// TODO (#3492): Use the field options to refine interpretation of the field
if !rn.IsNilOrEmpty() && rn.YNode().Kind == yaml.ScalarNode {
return getRefinedValue(r.Source.Options, rn)
}
return rn, nil
}

func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
if options == nil || options.Delimiter == "" {
return rn, nil
}
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
var index int
if options.Index > len(value) || options.Index < 0 { // take the last element
index = len(value) - 1
} else {
index = options.Index
}
n := rn.Copy()
n.YNode().Value = value[index]
return n, nil
}

// selectSourceNode finds the node that matches the selector, returning
// an error if multiple or none are found
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
Expand Down
Loading

0 comments on commit 0d0e6b9

Please sign in to comment.