Skip to content

Commit 804491f

Browse files
Merge pull request #24 from segmentio/yolken-update-ordering
Improve ordering of diff and apply results
2 parents a6ca0f5 + 44b1af2 commit 804491f

File tree

8 files changed

+288
-25
lines changed

8 files changed

+288
-25
lines changed

data/data.go

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cluster/apply/format.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ func ResultsTextTable(results []Result) string {
1515
table := tablewriter.NewWriter(buf)
1616
table.SetHeader(
1717
[]string{
18+
"Namespace",
1819
"Kind",
1920
"Name",
20-
"Namespace",
2121
"Created",
2222
"Old Version",
2323
"New Version",
@@ -60,9 +60,9 @@ func ResultsTextTable(results []Result) string {
6060

6161
table.Append(
6262
[]string{
63+
printer("%s", result.Namespace),
6364
printer("%s", result.Kind),
6465
printer("%s", result.Name),
65-
printer("%s", result.Namespace),
6666
printer("%s", result.CreatedTimestamp()),
6767
printer("%s", result.OldVersion),
6868
printer("%s", result.NewVersion),

pkg/cluster/diff/format.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ func ResultsTable(results []Result) string {
1414
table := tablewriter.NewWriter(buf)
1515
table.SetHeader(
1616
[]string{
17+
"Namespace",
1718
"Kind",
1819
"Name",
19-
"Namespace",
2020
"Changed Lines",
2121
},
2222
)
@@ -53,9 +53,9 @@ func ResultsTable(results []Result) string {
5353

5454
table.Append(
5555
[]string{
56+
namespace,
5657
kind,
5758
name,
58-
namespace,
5959
fmt.Sprintf("%d", result.NumChangedLines()),
6060
},
6161
)

pkg/cluster/kube_client.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,11 @@ func (cc *KubeClusterClient) ApplyStructured(
195195
return nil, err
196196
}
197197

198-
return apply.ObjsToResults(oldObjs, newObjs)
198+
results, err := apply.ObjsToResults(oldObjs, newObjs)
199+
if err != nil {
200+
return nil, err
201+
}
202+
return sortedApplyResults(results), nil
199203
}
200204

201205
// Diff runs a kubectl diff between the configs at the argument path and the associated
@@ -238,7 +242,7 @@ func (cc *KubeClusterClient) DiffStructured(
238242
if err := json.Unmarshal(rawResults, &results); err != nil {
239243
return nil, err
240244
}
241-
return results.Results, nil
245+
return sortedDiffResults(results.Results), nil
242246
}
243247

244248
// Summary returns a summary of the current cluster state.

pkg/cluster/sort.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package cluster
2+
3+
import (
4+
"sort"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/segmentio/kubeapply/pkg/cluster/apply"
9+
"github.com/segmentio/kubeapply/pkg/cluster/diff"
10+
)
11+
12+
type wrappedResult struct {
13+
nameBase string
14+
nameIndex int
15+
namespaceBase string
16+
namespaceIndex int
17+
kind string
18+
resultIndex int
19+
}
20+
21+
// sortedDiffResults sorts diff results by namespace, then resource type,
22+
// then resource name. If a resource name or namespace is structured as
23+
// [base string]-[number], then the number is used to break ties among all
24+
// entities with the same base.
25+
func sortedDiffResults(results []diff.Result) []diff.Result {
26+
wrappedResults := make([]wrappedResult, len(results))
27+
for r, result := range results {
28+
if result.Object != nil {
29+
wrappedResults[r].nameBase, wrappedResults[r].nameIndex =
30+
parseName(result.Object.Name)
31+
wrappedResults[r].namespaceBase, wrappedResults[r].namespaceIndex =
32+
parseName(result.Object.Namespace)
33+
wrappedResults[r].kind = result.Object.Kind
34+
} else {
35+
wrappedResults[r].namespaceBase = result.Name
36+
}
37+
wrappedResults[r].resultIndex = r
38+
}
39+
40+
sortWrappedResults(wrappedResults)
41+
42+
sortedResults := make([]diff.Result, len(results))
43+
for r, wrappedResult := range wrappedResults {
44+
sortedResults[r] = results[wrappedResult.resultIndex]
45+
}
46+
47+
return sortedResults
48+
}
49+
50+
// sortedApplyResults sorts apply results by namespace, then resource type,
51+
// then resource name. If a resource name or namespace is structured as
52+
// [base string]-[number], then the number is used to break ties among all
53+
// entities with the same base.
54+
func sortedApplyResults(results []apply.Result) []apply.Result {
55+
wrappedResults := make([]wrappedResult, len(results))
56+
for r, result := range results {
57+
wrappedResults[r].nameBase, wrappedResults[r].nameIndex =
58+
parseName(result.Name)
59+
wrappedResults[r].namespaceBase, wrappedResults[r].namespaceIndex =
60+
parseName(result.Namespace)
61+
wrappedResults[r].kind = result.Kind
62+
wrappedResults[r].resultIndex = r
63+
}
64+
65+
sortWrappedResults(wrappedResults)
66+
67+
sortedResults := make([]apply.Result, len(results))
68+
for r, wrappedResult := range wrappedResults {
69+
sortedResults[r] = results[wrappedResult.resultIndex]
70+
}
71+
72+
return sortedResults
73+
}
74+
75+
func sortWrappedResults(wrappedResults []wrappedResult) {
76+
sort.Slice(wrappedResults, func(a, b int) bool {
77+
result1 := wrappedResults[a]
78+
result2 := wrappedResults[b]
79+
if result1.namespaceBase < result2.namespaceBase {
80+
return true
81+
} else if result1.namespaceBase > result2.namespaceBase {
82+
return false
83+
} else if result1.namespaceIndex < result2.namespaceIndex {
84+
return true
85+
} else if result1.namespaceIndex > result2.namespaceIndex {
86+
return false
87+
} else if result1.kind < result2.kind {
88+
return true
89+
} else if result1.kind > result2.kind {
90+
return false
91+
} else if result1.nameBase < result2.nameBase {
92+
return true
93+
} else if result1.nameBase > result2.nameBase {
94+
return false
95+
} else if result1.nameIndex < result2.nameIndex {
96+
return true
97+
}
98+
return false
99+
})
100+
}
101+
102+
func parseName(name string) (string, int) {
103+
components := strings.Split(name, "-")
104+
if len(components) < 2 {
105+
return name, 0
106+
}
107+
index, err := strconv.Atoi(components[len(components)-1])
108+
if err != nil {
109+
return name, 0
110+
}
111+
return strings.Join(components[0:len(components)-1], "-"), index
112+
}

0 commit comments

Comments
 (0)