Skip to content

Commit

Permalink
feat(helm): add ability to sort release list by chart name
Browse files Browse the repository at this point in the history
Signed-off-by: Arash Deshmeh <[email protected]>
  • Loading branch information
adshmh committed Sep 1, 2018
1 parent 3f0c6c5 commit 380ca1a
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 103 deletions.
1 change: 1 addition & 0 deletions _proto/hapi/services/tiller.proto
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ message ListSort{
UNKNOWN = 0;
NAME = 1;
LAST_RELEASED = 2;
CHART_NAME = 3;
}

// SortOrder defines sort orders to augment sorting operations.
Expand Down
41 changes: 23 additions & 18 deletions cmd/helm/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,25 @@ flag with the '--offset' flag allows you to page through results.
`

type listCmd struct {
filter string
short bool
limit int
offset string
byDate bool
sortDesc bool
out io.Writer
all bool
deleted bool
deleting bool
deployed bool
failed bool
namespace string
superseded bool
pending bool
client helm.Interface
colWidth uint
output string
filter string
short bool
limit int
offset string
byDate bool
sortDesc bool
out io.Writer
all bool
deleted bool
deleting bool
deployed bool
failed bool
namespace string
superseded bool
pending bool
client helm.Interface
colWidth uint
output string
byChartName bool
}

type listResult struct {
Expand Down Expand Up @@ -133,6 +134,7 @@ func newListCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.StringVar(&list.namespace, "namespace", "", "show releases within a specific namespace")
f.UintVar(&list.colWidth, "col-width", 60, "specifies the max column width of output")
f.StringVar(&list.output, "output", "", "output the specified format (json or yaml)")
f.BoolVarP(&list.byChartName, "chart-name", "c", false, "sort by chart name")

// TODO: Do we want this as a feature of 'helm list'?
//f.BoolVar(&list.superseded, "history", true, "show historical releases")
Expand All @@ -145,6 +147,9 @@ func (l *listCmd) run() error {
if l.byDate {
sortBy = services.ListSort_LAST_RELEASED
}
if l.byChartName {
sortBy = services.ListSort_CHART_NAME
}

sortOrder := services.ListSort_ASC
if l.sortDesc {
Expand Down
3 changes: 2 additions & 1 deletion docs/helm/helm_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ helm list [flags] [FILTER]

```
-a, --all show all releases, not just the ones marked DEPLOYED
-c, --chart-name sort by chart name
--col-width uint specifies the max column width of output (default 60)
-d, --date sort by release date
--deleted show deleted releases
Expand Down Expand Up @@ -77,4 +78,4 @@ helm list [flags] [FILTER]

* [helm](helm.md) - The Helm package manager for Kubernetes.

###### Auto generated by spf13/cobra on 10-Aug-2018
###### Auto generated by spf13/cobra on 1-Sep-2018
171 changes: 87 additions & 84 deletions pkg/proto/hapi/services/tiller.pb.go

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions pkg/releaseutil/sorter.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,26 @@ func SortByRevision(list []*rspb.Release) {
}
sort.Sort(s)
}

// SortByChartName sorts the list of releases by a
// release's chart name in lexicographical order.
func SortByChartName(list []*rspb.Release) {
s := &sorter{list: list}
s.less = func(i, j int) bool {
chi := s.list[i].Chart
chj := s.list[j].Chart

ni := ""
if chi != nil && chi.Metadata != nil {
ni = chi.Metadata.Name
}

nj := ""
if chj != nil && chj.Metadata != nil {
nj = chj.Metadata.Name
}

return ni < nj
}
sort.Sort(s)
}
16 changes: 16 additions & 0 deletions pkg/releaseutil/sorter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"testing"
"time"

"k8s.io/helm/pkg/proto/hapi/chart"
rspb "k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/timeconv"
)
Expand All @@ -40,6 +41,11 @@ func tsRelease(name string, vers int32, dur time.Duration, code rspb.Status_Code
Name: name,
Version: vers,
Info: info,
Chart: &chart.Chart{
Metadata: &chart.Metadata{
Name: name,
},
},
}
}

Expand Down Expand Up @@ -80,3 +86,13 @@ func TestSortByRevision(t *testing.T) {
return vi < vj
})
}

func TestSortByChartName(t *testing.T) {
SortByChartName(releases)

check(t, "ByChartName", func(i, j int) bool {
ni := releases[i].Chart.Metadata.Name
nj := releases[j].Chart.Metadata.Name
return ni < nj
})
}
2 changes: 2 additions & 0 deletions pkg/tiller/release_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream s
relutil.SortByName(rels)
case services.ListSort_LAST_RELEASED:
relutil.SortByDate(rels)
case services.ListSort_CHART_NAME:
relutil.SortByChartName(rels)
}

if req.SortOrder == services.ListSort_DESC {
Expand Down
43 changes: 43 additions & 0 deletions pkg/tiller/release_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"testing"

"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/proto/hapi/services"
)
Expand Down Expand Up @@ -147,6 +148,48 @@ func TestListReleasesSort(t *testing.T) {
}
}

func TestListReleasesSortByChartName(t *testing.T) {
rs := rsFixture()

// Put them in by reverse order so that the mock doesn't "accidentally"
// sort.
num := 7
for i := num; i > 0; i-- {
rel := releaseStub()
rel.Name = fmt.Sprintf("rel-%d", num-i)
rel.Chart = &chart.Chart{
Metadata: &chart.Metadata{
Name: fmt.Sprintf("chartName-%d", i),
},
}
if err := rs.env.Releases.Create(rel); err != nil {
t.Fatalf("Could not store mock release: %s", err)
}
}

limit := 6
mrs := &mockListServer{}
req := &services.ListReleasesRequest{
Offset: "",
Limit: int64(limit),
SortBy: services.ListSort_CHART_NAME,
}
if err := rs.ListReleases(req, mrs); err != nil {
t.Fatalf("Failed listing: %s", err)
}

if len(mrs.val.Releases) != limit {
t.Errorf("Expected %d releases, got %d", limit, len(mrs.val.Releases))
}

for i := 0; i < limit; i++ {
n := fmt.Sprintf("chartName-%d", i+1)
if mrs.val.Releases[i].Chart.Metadata.Name != n {
t.Errorf("Expected %q, got %q", n, mrs.val.Releases[i].Chart.Metadata.Name)
}
}
}

func TestListReleasesFilter(t *testing.T) {
rs := rsFixture()
names := []string{
Expand Down

0 comments on commit 380ca1a

Please sign in to comment.