Preserve order when merging.

This commit is contained in:
Jeffrey Regan
2019-06-03 11:22:53 -07:00
committed by jregan
parent c094780aae
commit c63ebbdfc4
9 changed files with 254 additions and 271 deletions

View File

@@ -42,18 +42,14 @@ func (ra *ResAccumulator) Vars() []types.Var {
return ra.varSet.Set() return ra.varSet.Set()
} }
func (ra *ResAccumulator) MergeResourcesWithErrorOnIdCollision( func (ra *ResAccumulator) AppendAll(
resources resmap.ResMap) (err error) { resources resmap.ResMap) error {
ra.resMap, err = resmap.MergeWithErrorOnIdCollision( return ra.resMap.AppendAll(resources)
resources, ra.resMap)
return err
} }
func (ra *ResAccumulator) MergeResourcesWithOverride( func (ra *ResAccumulator) AbsorbAll(
resources resmap.ResMap) (err error) { resources resmap.ResMap) error {
ra.resMap, err = resmap.MergeWithOverride( return ra.resMap.AbsorbAll(resources)
ra.resMap, resources)
return err
} }
func (ra *ResAccumulator) MergeConfig( func (ra *ResAccumulator) MergeConfig(
@@ -71,7 +67,7 @@ func (ra *ResAccumulator) MergeVars(incoming []types.Var) error {
} }
func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) { func (ra *ResAccumulator) MergeAccumulator(other *ResAccumulator) (err error) {
err = ra.MergeResourcesWithErrorOnIdCollision(other.resMap) err = ra.AppendAll(other.resMap)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -41,7 +41,7 @@ func makeResAccumulator() (*ResAccumulator, *resource.Factory, error) {
} }
rf := resource.NewFactory( rf := resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl()) kunstruct.NewKunstructuredFactoryImpl())
err = ra.MergeResourcesWithErrorOnIdCollision( err = ra.AppendAll(
resmap.FromMap(map[resid.ResId]*resource.Resource{ resmap.FromMap(map[resid.ResId]*resource.Resource{
resid.NewResId( resid.NewResId(
gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}, gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"},
@@ -188,7 +188,7 @@ func TestResolveVarsVarNeedsDisambiguation(t *testing.T) {
}), }),
}) })
err = ra.MergeResourcesWithErrorOnIdCollision(rm0) err = ra.AppendAll(rm0)
if err != nil { if err != nil {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }

View File

@@ -153,7 +153,7 @@ func (o *Options) emitResources(
if o.outputPath != "" && fSys.IsDir(o.outputPath) { if o.outputPath != "" && fSys.IsDir(o.outputPath) {
return writeIndividualFiles(fSys, o.outputPath, m) return writeIndividualFiles(fSys, o.outputPath, m)
} }
res, err := m.EncodeAsYaml() res, err := m.AsYaml(resmap.LegacySort)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -193,7 +193,7 @@ func (th *KustTestHarness) AssertActualEqualsExpected(
if len(expected) > 0 && expected[0] == 10 { if len(expected) > 0 && expected[0] == 10 {
expected = expected[1:] expected = expected[1:]
} }
actual, err := m.EncodeAsYaml() actual, err := m.AsYaml(resmap.LegacySort)
if err != nil { if err != nil {
th.t.Fatalf("Unexpected err: %v", err) th.t.Fatalf("Unexpected err: %v", err)
} }

View File

@@ -140,7 +140,7 @@ func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
} }
// encode the ResMap so it can be fed to the plugin // encode the ResMap so it can be fed to the plugin
resources, err := inputRM.EncodeAsYaml() resources, err := inputRM.AsYaml(resmap.Identity)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -84,17 +84,34 @@ type ResMap interface {
// Error on Id collision. // Error on Id collision.
AppendWithId(resid.ResId, *resource.Resource) error AppendWithId(resid.ResId, *resource.Resource) error
// AsMap returns ResId, *Resource pairs in // AppendAll appends another ResMap to self,
// arbitrary order via a map. // failing on any Id collision.
AppendAll(ResMap) error
// AbsorbAll appends, replaces or merges the contents
// of another ResMap into self,
// allowing and sometimes demanding ID collisions.
// A collision would be demanded, say, when a generated
// ConfigMap has the "replace" option in its generation
// instructions, meaning it _must_ replace
// something in the known set of resources.
// If a resource id for resource X is found to already
// be in self, then the behavior field for X must
// be BehaviorMerge or BehaviorReplace. If X is not in
// self, then its behavior _cannot_ be merge or replace.
AbsorbAll(ResMap) error
// AsMap returns (ResId, *Resource) pairs in
// arbitrary order via a generated map.
// The map is discardable, and edits to map structure // The map is discardable, and edits to map structure
// have no impact on the ResMap. // have no impact on the ResMap.
// The Ids are copies, but the resources are pointers, // The Ids are copies, but the resources are pointers,
// so the resources themselves can be modified. // so the resources themselves can be modified.
AsMap() map[resid.ResId]*resource.Resource AsMap() map[resid.ResId]*resource.Resource
// EncodeAsYaml emits the resources as YAML in a byte slice. // AsYaml returns the yaml form of resources, after twiddling.
// Resources are separated by `---`. // Certainly nobody will abuse the twiddler.
EncodeAsYaml() ([]byte, error) AsYaml(f ResTwiddler) ([]byte, error)
// Gets the resource with the given Id, else nil. // Gets the resource with the given Id, else nil.
GetById(resid.ResId) *resource.Resource GetById(resid.ResId) *resource.Resource
@@ -350,33 +367,42 @@ func (m *resWrangler) GetMatchingIds(matches IdMatcher) []resid.ResId {
return result return result
} }
// EncodeAsYaml implements ResMap. // Identity returns Resources as is.
func (m *resWrangler) EncodeAsYaml() ([]byte, error) { func Identity(m ResMap) []*resource.Resource {
// TODO: should be able to suppress this sort return m.Resources()
// and rely on ordering as specified in the ResMap }
// internal rList.
// LegacySort return Resources in a particular order.
func LegacySort(m ResMap) []*resource.Resource {
resources := make([]*resource.Resource, m.Size())
ids := m.AllIds() ids := m.AllIds()
sort.Sort(IdSlice(ids)) sort.Sort(IdSlice(ids))
for i, id := range ids {
resources[i] = m.GetById(id)
}
return resources
}
type ResTwiddler func(ResMap) []*resource.Resource
// AsYaml implements ResMap.
func (m *resWrangler) AsYaml(twiddle ResTwiddler) ([]byte, error) {
firstObj := true firstObj := true
var b []byte var b []byte
buf := bytes.NewBuffer(b) buf := bytes.NewBuffer(b)
for _, id := range ids { for _, res := range twiddle(m) {
obj := m.GetById(id) out, err := yaml.Marshal(res.Map())
out, err := yaml.Marshal(obj.Map())
if err != nil { if err != nil {
return nil, err return nil, err
} }
if firstObj { if firstObj {
firstObj = false firstObj = false
} else { } else {
_, err = buf.WriteString("---\n") if _, err = buf.WriteString("---\n"); err != nil {
if err != nil {
return nil, err return nil, err
} }
} }
_, err = buf.Write(out) if _, err = buf.Write(out); err != nil {
if err != nil {
return nil, err return nil, err
} }
} }
@@ -387,7 +413,7 @@ func (m *resWrangler) EncodeAsYaml() ([]byte, error) {
func (m *resWrangler) ErrorIfNotEqual(other ResMap) error { func (m *resWrangler) ErrorIfNotEqual(other ResMap) error {
m2, ok := other.(*resWrangler) m2, ok := other.(*resWrangler)
if !ok { if !ok {
panic(fmt.Errorf("bad cast to resmapImpl")) panic(fmt.Errorf("bad cast"))
} }
if m.Size() != m2.Size() { if m.Size() != m2.Size() {
return fmt.Errorf( return fmt.Errorf(
@@ -462,86 +488,93 @@ func (m *resWrangler) ResourcesThatCouldReference(inputId resid.ResId) ResMap {
return result return result
} }
// MergeWithErrorOnIdCollision combines multiple ResMap instances, failing on // AppendAll implements ResMap.
// key collision and skipping nil maps. func (m *resWrangler) AppendAll(other ResMap) error {
// If all of the maps are nil, an empty ResMap is returned. if other == nil {
func MergeWithErrorOnIdCollision(maps ...ResMap) (ResMap, error) { return nil
result := New() }
for _, m := range maps { w2, ok := other.(*resWrangler)
if m == nil { if !ok {
continue panic(fmt.Errorf("bad cast"))
}
for i, res := range w2.Resources() {
id, err := w2.idMappingToIndex(i)
if err != nil {
panic("map is unrecoverably corrupted; " + err.Error())
} }
for id, res := range m.AsMap() { err = m.AppendWithId(id, res)
err := result.AppendWithId(id, res) if err != nil {
if err != nil { return err
return nil, err
}
} }
} }
return result, nil return nil
} }
// MergeWithOverride combines multiple ResMap instances, allowing and sometimes // AbsorbAll implements ResMap.
// demanding certain collisions and skipping nil maps. func (m *resWrangler) AbsorbAll(other ResMap) error {
// A collision would be demanded, say, when a generated ConfigMap has the if other == nil {
// "replace" option in its generation instructions, meaning it is supposed return nil
// to replace something from the raw resources list.
// If all of the maps are nil, an empty ResMap is returned.
// When looping over the instances to combine them, if a resource id for
// resource X is found to be already in the combined map, then the behavior
// field for X must be BehaviorMerge or BehaviorReplace. If X is not in the
// map, then it's behavior cannot be merge or replace.
// nolint: gocyclo
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
if len(maps) == 0 {
return New(), nil
} }
result := maps[0] w2, ok := other.(*resWrangler)
if result == nil { if !ok {
result = New() panic(fmt.Errorf("bad cast"))
} }
for _, m := range maps[1:] { for i, r := range w2.Resources() {
if m == nil { id, err := w2.idMappingToIndex(i)
continue if err != nil {
panic("map is unrecoverably corrupted; " + err.Error())
} }
for id, r := range m.AsMap() { err = m.appendReplaceOrMerge(id, r)
matchedId := result.GetMatchingIds(id.GvknEquals) if err != nil {
if len(matchedId) == 1 { return err
id = matchedId[0] }
old := result.GetById(id) }
if old == nil { return nil
return nil, fmt.Errorf("id lookup failure") }
}
switch r.Behavior() { func (m *resWrangler) appendReplaceOrMerge(
case types.BehaviorReplace: idForRes resid.ResId, res *resource.Resource) error {
r.Replace(old) matchedId := m.GetMatchingIds(idForRes.GvknEquals)
err := result.ReplaceResource(id, r) switch len(matchedId) {
if err != nil { case 0:
return nil, err switch res.Behavior() {
} case types.BehaviorMerge, types.BehaviorReplace:
case types.BehaviorMerge: return fmt.Errorf(
r.Merge(old) "id %#v does not exist; cannot merge or replace", idForRes)
err := result.ReplaceResource(id, r) default:
if err != nil { // presumably types.BehaviorCreate
return nil, err err := m.AppendWithId(idForRes, res)
} if err != nil {
default: return err
return nil, fmt.Errorf("id %#v exists; must merge or replace", id)
}
} else if len(matchedId) == 0 {
switch r.Behavior() {
case types.BehaviorMerge, types.BehaviorReplace:
return nil, fmt.Errorf("id %#v does not exist; cannot merge or replace", id)
default:
err := result.AppendWithId(id, r)
if err != nil {
return nil, err
}
}
} else {
return nil, fmt.Errorf("merge conflict, found multiple objects %v the Resmap %v can merge into", matchedId, id)
} }
} }
case 1:
mId := matchedId[0]
old := m.GetById(mId)
if old == nil {
return fmt.Errorf("id lookup failure")
}
switch res.Behavior() {
case types.BehaviorReplace:
res.Replace(old)
err := m.ReplaceResource(mId, res)
if err != nil {
return err
}
case types.BehaviorMerge:
res.Merge(old)
err := m.ReplaceResource(mId, res)
if err != nil {
return err
}
default:
return fmt.Errorf(
"id %#v exists; must merge or replace", idForRes)
}
default:
return fmt.Errorf(
"found multiple objects %v that could accept merge of %v",
matchedId, idForRes)
} }
return result, nil return nil
} }

View File

@@ -17,7 +17,6 @@ import (
) )
var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"} var deploy = gvk.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
var statefulset = gvk.Gvk{Group: "apps", Version: "v1", Kind: "StatefulSet"}
var rf = resource.NewFactory( var rf = resource.NewFactory(
kunstruct.NewKunstructuredFactoryImpl()) kunstruct.NewKunstructuredFactoryImpl())
var rmF = NewFactory(rf) var rmF = NewFactory(rf)
@@ -161,25 +160,24 @@ kind: ConfigMap
metadata: metadata:
name: cm2 name: cm2
`) `)
input := FromMap(map[resid.ResId]*resource.Resource{ input := New()
resid.NewResId(cmap, "cm1"): rf.FromMap( input.Append(rf.FromMap(
map[string]interface{}{ map[string]interface{}{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": map[string]interface{}{ "metadata": map[string]interface{}{
"name": "cm1", "name": "cm1",
}, },
}), }))
resid.NewResId(cmap, "cm2"): rf.FromMap( input.Append(rf.FromMap(
map[string]interface{}{ map[string]interface{}{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": map[string]interface{}{ "metadata": map[string]interface{}{
"name": "cm2", "name": "cm2",
}, },
}), }))
}) out, err := input.AsYaml(Identity)
out, err := input.EncodeAsYaml()
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -581,172 +579,127 @@ func TestErrorIfNotEqual(t *testing.T) {
if err == nil { if err == nil {
t.Fatalf("%v should not equal %v %v", rm1, rm2, err) t.Fatalf("%v should not equal %v %v", rm1, rm2, err)
} }
} }
func TestMergeWithoutOverride(t *testing.T) { func TestAppendAll(t *testing.T) {
input1 := FromMap(map[resid.ResId]*resource.Resource{ r1 := rf.FromMap(
resid.NewResId(deploy, "deploy1"): rf.FromMap( map[string]interface{}{
map[string]interface{}{ "apiVersion": "apps/v1",
"apiVersion": "apps/v1", "kind": "Deployment",
"kind": "Deployment", "metadata": map[string]interface{}{
"metadata": map[string]interface{}{ "name": "foo-deploy1",
"name": "foo-deploy1", },
}, })
}), input1 := rmF.FromResource(r1)
}) r2 := rf.FromMap(
input2 := FromMap(map[resid.ResId]*resource.Resource{ map[string]interface{}{
resid.NewResId(statefulset, "stateful1"): rf.FromMap( "apiVersion": "apps/v1",
map[string]interface{}{ "kind": "StatefulSet",
"apiVersion": "apps/v1", "metadata": map[string]interface{}{
"kind": "StatefulSet", "name": "bar-stateful",
"metadata": map[string]interface{}{ },
"name": "bar-stateful", })
}, input2 := rmF.FromResource(r2)
}),
}) expected := New()
input := []ResMap{input1, input2} expected.Append(r1)
expected := FromMap(map[resid.ResId]*resource.Resource{ expected.Append(r2)
resid.NewResId(deploy, "deploy1"): rf.FromMap(
map[string]interface{}{ if err := input1.AppendAll(input2); err != nil {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "foo-deploy1",
},
}),
resid.NewResId(statefulset, "stateful1"): rf.FromMap(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "StatefulSet",
"metadata": map[string]interface{}{
"name": "bar-stateful",
},
}),
})
merged, err := MergeWithErrorOnIdCollision(input...)
if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
err = expected.ErrorIfNotEqual(merged) if err := expected.ErrorIfNotEqual(input1); err != nil {
if err != nil { input1.Debug("1")
t.Fatalf("%#v doesn't equal expected %#v", merged, expected) expected.Debug("ex")
t.Fatalf("%#v doesn't equal expected %#v", input1, expected)
} }
input3 := []ResMap{merged, nil} if err := input1.AppendAll(nil); err != nil {
merged1, err := MergeWithErrorOnIdCollision(input3...)
if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
err = expected.ErrorIfNotEqual(merged1) if err := expected.ErrorIfNotEqual(input1); err != nil {
if err != nil { t.Fatalf("%#v doesn't equal expected %#v", input1, expected)
t.Fatal(err)
}
input4 := []ResMap{nil, merged}
merged2, err := MergeWithErrorOnIdCollision(input4...)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = expected.ErrorIfNotEqual(merged2)
if err != nil {
t.Fatal(err)
} }
} }
func generateMergeFixtures(b types.GenerationBehavior) []ResMap { func makeMap1() ResMap {
input1 := FromMap(map[resid.ResId]*resource.Resource{ return rmF.FromResource(rf.FromMapAndOption(
resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{
map[string]interface{}{ "apiVersion": "apps/v1",
"apiVersion": "apps/v1", "kind": "ConfigMap",
"kind": "ConfigMap", "metadata": map[string]interface{}{
"metadata": map[string]interface{}{ "name": "cmap",
"name": "cmap", },
}, "data": map[string]interface{}{
"data": map[string]interface{}{ "a": "x",
"a": "x", "b": "y",
"b": "y", },
}, }, &types.GeneratorArgs{
}, &types.GeneratorArgs{ Behavior: "create",
Behavior: "create", }, nil))
}, nil),
})
input2 := FromMap(map[resid.ResId]*resource.Resource{
resid.NewResId(cmap, "cmap"): rf.FromMapAndOption(
map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cmap",
},
"data": map[string]interface{}{
"a": "u",
"b": "v",
"c": "w",
},
}, &types.GeneratorArgs{
Behavior: b.String(),
}, nil),
})
return []ResMap{input1, input2}
} }
func TestMergeWithOverride(t *testing.T) { func makeMap2(b types.GenerationBehavior) ResMap {
expected := FromMap(map[resid.ResId]*resource.Resource{ return rmF.FromResource(rf.FromMapAndOption(
resid.NewResId(cmap, "cmap"): rf.FromMapAndOption( map[string]interface{}{
map[string]interface{}{ "apiVersion": "apps/v1",
"apiVersion": "apps/v1", "kind": "ConfigMap",
"kind": "ConfigMap", "metadata": map[string]interface{}{
"metadata": map[string]interface{}{ "name": "cmap",
"annotations": map[string]interface{}{}, },
"labels": map[string]interface{}{}, "data": map[string]interface{}{
"name": "cmap", "a": "u",
}, "b": "v",
"data": map[string]interface{}{ "c": "w",
"a": "u", },
"b": "v", }, &types.GeneratorArgs{
"c": "w", Behavior: b.String(),
}, }, nil))
}, &types.GeneratorArgs{ }
Behavior: "create",
}, nil), func TestAbsorbAll(t *testing.T) {
}) expected := rmF.FromResource(rf.FromMapAndOption(
merged, err := MergeWithOverride(generateMergeFixtures(types.BehaviorMerge)...) map[string]interface{}{
if err != nil { "apiVersion": "apps/v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{},
"labels": map[string]interface{}{},
"name": "cmap",
},
"data": map[string]interface{}{
"a": "u",
"b": "v",
"c": "w",
},
}, &types.GeneratorArgs{
Behavior: "create",
}, nil))
w := makeMap1()
if err := w.AbsorbAll(makeMap2(types.BehaviorMerge)); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
err = expected.ErrorIfNotEqual(merged) if err := expected.ErrorIfNotEqual(w); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
input3 := []ResMap{merged, nil} w = makeMap1()
merged1, err := MergeWithOverride(input3...) if err := w.AbsorbAll(nil); err != nil {
if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
err = expected.ErrorIfNotEqual(merged1) if err := w.ErrorIfNotEqual(makeMap1()); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
input4 := []ResMap{nil, merged} w = makeMap1()
merged2, err := MergeWithOverride(input4...) w2 := makeMap2(types.BehaviorReplace)
if err != nil { if err := w.AbsorbAll(w2); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
err = expected.ErrorIfNotEqual(merged2) if err := w2.ErrorIfNotEqual(w); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
inputs := generateMergeFixtures(types.BehaviorReplace) w = makeMap1()
replaced, err := MergeWithOverride(inputs...) w2 = makeMap2(types.BehaviorUnspecified)
if err != nil { err := w.AbsorbAll(w2)
t.Fatalf("unexpected error: %v", err)
}
expectedReplaced := inputs[1]
err = expectedReplaced.ErrorIfNotEqual(replaced)
if err != nil {
t.Fatal(err)
}
_, err = MergeWithOverride(generateMergeFixtures(types.BehaviorUnspecified)...)
if err == nil { if err == nil {
t.Fatal("Merging with GenerationBehavior BehaviorUnspecified should return an error but does not") t.Fatalf("expected error with unspecified behavior")
} }
} }

View File

@@ -263,7 +263,7 @@ func (kt *KustTarget) runGenerators(
return err return err
} }
// The legacy generators allow override. // The legacy generators allow override.
err = ra.MergeResourcesWithOverride(resMap) err = ra.AbsorbAll(resMap)
if err != nil { if err != nil {
return errors.Wrapf(err, "merging from generator %v", g) return errors.Wrapf(err, "merging from generator %v", g)
} }
@@ -277,7 +277,7 @@ func (kt *KustTarget) runGenerators(
if err != nil { if err != nil {
return err return err
} }
err = ra.MergeResourcesWithErrorOnIdCollision(resMap) err = ra.AppendAll(resMap)
if err != nil { if err != nil {
return errors.Wrapf(err, "merging from generator %v", g) return errors.Wrapf(err, "merging from generator %v", g)
} }
@@ -380,7 +380,7 @@ func (kt *KustTarget) accumulateFile(
if err != nil { if err != nil {
return errors.Wrapf(err, "accumulating resources from '%s'", path) return errors.Wrapf(err, "accumulating resources from '%s'", path)
} }
err = ra.MergeResourcesWithErrorOnIdCollision(resources) err = ra.AppendAll(resources)
if err != nil { if err != nil {
return errors.Wrapf(err, "merging resources from '%s'", path) return errors.Wrapf(err, "merging resources from '%s'", path)
} }

View File

@@ -8,6 +8,7 @@ import (
"testing" "testing"
"sigs.k8s.io/kustomize/pkg/kusttest" "sigs.k8s.io/kustomize/pkg/kusttest"
"sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/plugin" "sigs.k8s.io/kustomize/plugin"
) )
@@ -32,7 +33,7 @@ kind: PrintWorkDir
metadata: metadata:
name: whatever name: whatever
`) `)
a, err := m.EncodeAsYaml() a, err := m.AsYaml(resmap.Identity)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }