Commit 6844d3b4 authored by Matt Butcher's avatar Matt Butcher

feat(helm,tiller): add list reverse, string offset

parent dfc9693a
...@@ -61,39 +61,56 @@ message ListReleasesRequest { ...@@ -61,39 +61,56 @@ message ListReleasesRequest {
// Limit is the maximum number of releases to be returned. // Limit is the maximum number of releases to be returned.
int64 limit = 1; int64 limit = 1;
// Offset is the zero-based offset at which the returned release list begins. // Offset is the last release name that was seen. The next listing
int64 offset = 2; // operation will start with the name after this one.
// Example: If list one returns albert, bernie, carl and we supply
// SortBy is the sort field that the ListReleases server should sort data before returning. // carl as the offset, the next one should begin with the next release name
ListSort.SortBy sort_by = 3; // after carl (e.g. dennis).
string offset = 2;
// Filter is a regular expression used to filter which releases should be listed.
// // SortBy is the sort field that the ListReleases server should sort data before returning.
// Anything that matches the regexp will be included in the results. ListSort.SortBy sort_by = 3;
string filter = 4;
// Filter is a regular expression used to filter which releases should be listed.
//
// Anything that matches the regexp will be included in the results.
string filter = 4;
ListSort.SortOrder sort_order = 5;
} }
// ListSort defines sorting fields on a release list.
message ListSort{ message ListSort{
enum SortBy { // SortBy defines sort operations.
UNKNOWN = 0; enum SortBy {
NAME = 1; UNKNOWN = 0;
LAST_RELEASED = 2; NAME = 1;
} LAST_RELEASED = 2;
}
// SortOrder defines sort orders to augment sorting operations.
enum SortOrder {
ASC = 0;
DESC = 1;
}
} }
// ListReleasesResponse is a list of releases. // ListReleasesResponse is a list of releases.
message ListReleasesResponse { message ListReleasesResponse {
// The expected total number of releases to be returned // Count is the expected total number of releases to be returned.
int64 count = 1; int64 count = 1;
// The zero-based offset at which the list is positioned // Offset is the last-seen release name, used to offset the next set.
int64 offset = 2; string offset = 2;
// The total number of queryable releases // Total is the total number of queryable releases.
int64 total = 3; int64 total = 3;
// The resulting releases // Releases is the list of found release objects.
repeated hapi.release.Release releases = 4; repeated hapi.release.Release releases = 4;
// More indicates whether there are more objects to retrieve.
bool more = 5;
} }
// GetReleaseStatusRequest is a request to get the status of a release. // GetReleaseStatusRequest is a request to get the status of a release.
......
...@@ -43,16 +43,22 @@ var listCommand = &cobra.Command{ ...@@ -43,16 +43,22 @@ var listCommand = &cobra.Command{
Aliases: []string{"ls"}, Aliases: []string{"ls"},
} }
var listLong bool var (
var listMax int listLong bool
var listOffset int listMax int
var listByDate bool listOffset string
listByDate bool
listSortDesc bool
)
func init() { func init() {
listCommand.Flags().BoolVarP(&listLong, "long", "l", false, "output long listing format") f := listCommand.Flags()
listCommand.Flags().BoolVarP(&listByDate, "date", "d", false, "sort by release date") f.BoolVarP(&listLong, "long", "l", false, "output long listing format")
listCommand.Flags().IntVarP(&listMax, "max", "m", 256, "maximum number of releases to fetch") f.BoolVarP(&listByDate, "date", "d", false, "sort by release date")
listCommand.Flags().IntVarP(&listOffset, "offset", "o", 0, "offset from start value (zero-indexed)") f.BoolVarP(&listSortDesc, "reverse", "r", false, "reverse the sort order")
f.IntVarP(&listMax, "max", "m", 256, "maximum number of releases to fetch")
f.StringVarP(&listOffset, "offset", "o", "", "the last seen release name, used to offset from start value")
RootCommand.AddCommand(listCommand) RootCommand.AddCommand(listCommand)
} }
...@@ -67,17 +73,17 @@ func listCmd(cmd *cobra.Command, args []string) error { ...@@ -67,17 +73,17 @@ func listCmd(cmd *cobra.Command, args []string) error {
sortBy = services.ListSort_LAST_RELEASED sortBy = services.ListSort_LAST_RELEASED
} }
res, err := helm.ListReleases(listMax, listOffset, sortBy, filter) sortOrder := services.ListSort_ASC
if listSortDesc {
sortOrder = services.ListSort_DESC
}
res, err := helm.ListReleases(listMax, listOffset, sortBy, sortOrder, filter)
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
rels := res.Releases rels := res.Releases
if flagVerbose && res.Count+res.Offset < res.Total {
fmt.Println("==> Not all values were fetched.")
}
// Purty output, ya'll
if listLong { if listLong {
return formatList(rels) return formatList(rels)
} }
......
...@@ -44,6 +44,7 @@ var ( ...@@ -44,6 +44,7 @@ var (
var ListDefaultLimit int64 = 512 var ListDefaultLimit int64 = 512
func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error { func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
more := false
rels, err := s.env.Releases.List() rels, err := s.env.Releases.List()
if err != nil { if err != nil {
return err return err
...@@ -65,12 +66,33 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s ...@@ -65,12 +66,33 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s
sort.Sort(byDate(rels)) sort.Sort(byDate(rels))
} }
if req.SortOrder == services.ListSort_DESC {
ll := len(rels)
rr := make([]*release.Release, ll)
for i, item := range rels {
rr[ll-i-1] = item
}
rels = rr
}
l := int64(len(rels)) l := int64(len(rels))
if req.Offset > 0 { if req.Offset != "" {
if req.Offset >= l {
return fmt.Errorf("offset %d is outside of range %d", req.Offset, l) i := -1
for ii, cur := range rels {
if cur.Name == req.Offset {
i = ii + 1
}
}
if i == -1 {
return fmt.Errorf("offset %q not found", req.Offset)
} }
rels = rels[req.Offset:]
if len(rels) < i {
return fmt.Errorf("no items after %q", req.Offset)
}
rels = rels[i:]
l = int64(len(rels)) l = int64(len(rels))
} }
...@@ -79,15 +101,21 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s ...@@ -79,15 +101,21 @@ func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream s
} }
if l > req.Limit { if l > req.Limit {
more = true
rels = rels[0:req.Limit] rels = rels[0:req.Limit]
l = int64(len(rels)) l = int64(len(rels))
} }
last := ""
if l > 0 {
last = rels[l-1].Name
}
res := &services.ListReleasesResponse{ res := &services.ListReleasesResponse{
Offset: 0, Offset: last,
Count: l, Count: l,
Total: total, Total: total,
Releases: rels, Releases: rels,
More: more,
} }
stream.Send(res) stream.Send(res)
return nil return nil
......
...@@ -208,7 +208,7 @@ func TestListReleases(t *testing.T) { ...@@ -208,7 +208,7 @@ func TestListReleases(t *testing.T) {
} }
mrs := &mockListServer{} mrs := &mockListServer{}
if err := rs.ListReleases(&services.ListReleasesRequest{Offset: 0, Limit: 64}, mrs); err != nil { if err := rs.ListReleases(&services.ListReleasesRequest{Offset: "", Limit: 64}, mrs); err != nil {
t.Fatalf("Failed listing: %s", err) t.Fatalf("Failed listing: %s", err)
} }
...@@ -234,7 +234,7 @@ func TestListReleasesSort(t *testing.T) { ...@@ -234,7 +234,7 @@ func TestListReleasesSort(t *testing.T) {
limit := 6 limit := 6
mrs := &mockListServer{} mrs := &mockListServer{}
req := &services.ListReleasesRequest{ req := &services.ListReleasesRequest{
Offset: 0, Offset: "",
Limit: int64(limit), Limit: int64(limit),
SortBy: services.ListSort_NAME, SortBy: services.ListSort_NAME,
} }
...@@ -276,7 +276,7 @@ func TestListReleasesFilter(t *testing.T) { ...@@ -276,7 +276,7 @@ func TestListReleasesFilter(t *testing.T) {
mrs := &mockListServer{} mrs := &mockListServer{}
req := &services.ListReleasesRequest{ req := &services.ListReleasesRequest{
Offset: 0, Offset: "",
Limit: 64, Limit: 64,
Filter: "neuro[a-z]+", Filter: "neuro[a-z]+",
SortBy: services.ListSort_NAME, SortBy: services.ListSort_NAME,
......
...@@ -13,7 +13,7 @@ var Config = &config{ ...@@ -13,7 +13,7 @@ var Config = &config{
} }
// ListReleases lists the current releases. // ListReleases lists the current releases.
func ListReleases(limit, offset int, sort services.ListSort_SortBy, filter string) (*services.ListReleasesResponse, error) { func ListReleases(limit int, offset string, sort services.ListSort_SortBy, order services.ListSort_SortOrder, filter string) (*services.ListReleasesResponse, error) {
c := Config.client() c := Config.client()
if err := c.dial(); err != nil { if err := c.dial(); err != nil {
return nil, err return nil, err
...@@ -21,10 +21,11 @@ func ListReleases(limit, offset int, sort services.ListSort_SortBy, filter strin ...@@ -21,10 +21,11 @@ func ListReleases(limit, offset int, sort services.ListSort_SortBy, filter strin
defer c.Close() defer c.Close()
req := &services.ListReleasesRequest{ req := &services.ListReleasesRequest{
Limit: int64(limit), Limit: int64(limit),
Offset: int64(offset), Offset: offset,
SortBy: sort, SortBy: sort,
Filter: filter, SortOrder: order,
Filter: filter,
} }
cli, err := c.impl.ListReleases(context.TODO(), req, c.cfg.CallOpts()...) cli, err := c.impl.ListReleases(context.TODO(), req, c.cfg.CallOpts()...)
if err != nil { if err != nil {
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment