Skip to content

Commit

Permalink
feat(cli): sort composed resources in the render output
Browse files Browse the repository at this point in the history
Signed-off-by: Philippe Scorsolini <p.scorsolini@gmail.com>
  • Loading branch information
phisco committed Nov 17, 2023
1 parent 5b27867 commit 114f957
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
15 changes: 15 additions & 0 deletions cmd/crank/beta/render/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"context"
"fmt"
"os"
"sort"
"strings"
"time"

"github.com/alecthomas/kong"
Expand Down Expand Up @@ -187,6 +189,9 @@ func (c *Cmd) Run(k *kong.Context, _ logging.Logger) error { //nolint:gocyclo //
return errors.Wrapf(err, "cannot marshal composite resource %q to YAML", xr.GetName())
}

// We sort the composed resources by groupVersionKind and name to ensure
// that the rendered output is stable.
sortComposedResources(out.ComposedResources)
for i := range out.ComposedResources {
fmt.Fprintln(k.Stdout, "---")
if err := s.Encode(&out.ComposedResources[i], os.Stdout); err != nil {
Expand All @@ -206,3 +211,13 @@ func (c *Cmd) Run(k *kong.Context, _ logging.Logger) error { //nolint:gocyclo //

return nil
}

// sortByKindAndName sorts a slice of composed resources in place, first by GroupVersionKind and then by name.
func sortComposedResources(out []composed.Unstructured) {
sort.Slice(out, func(i, j int) bool {
if comp := strings.Compare(out[i].GroupVersionKind().String(), out[j].GroupVersionKind().String()); comp != 0 {
return comp < 0
}
return strings.Compare(out[i].GetName(), out[j].GetName()) < 0
})
}
124 changes: 124 additions & 0 deletions cmd/crank/beta/render/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,130 @@ func TestRender(t *testing.T) {
}
}

func TestOutputSort(t *testing.T) {
type args struct {
in []composed.Unstructured
}
type want struct {
out []composed.Unstructured
}

cases := map[string]struct {
reason string
args args
want want
}{
"SortComposedOnly": {
reason: "Composed resources should be sorted by kind, then name, nothing else should change.",
args: args{
in: []composed.Unstructured{
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "BComposed",
"metadata": {
"name": "a"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "b"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "btest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "b"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "a"
}
}`),
},
},
},
},
want: want{
out: []composed.Unstructured{
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "a"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "b"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "atest.crossplane.io/v1",
"kind": "BComposed",
"metadata": {
"name": "a"
}
}`),
},
},
{
Unstructured: unstructured.Unstructured{
Object: MustLoadJSON(`{
"apiVersion": "btest.crossplane.io/v1",
"kind": "AComposed",
"metadata": {
"name": "b"
}
}`),
},
},
},
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
sortComposedResources(tc.args.in)

if diff := cmp.Diff(tc.want.out, tc.args.in, cmpopts.EquateEmpty()); diff != "" {
t.Errorf("%s\nSorted(): -want, +got:\n%s", tc.reason, diff)
}
})
}
}

func NewFunction(t *testing.T, rsp *fnv1beta1.RunFunctionResponse) net.Listener {
lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
Expand Down

0 comments on commit 114f957

Please sign in to comment.