Skip to content

Commit 7e50687

Browse files
committed
feat(cdn) add limit flag to distribution list
1 parent c3095c5 commit 7e50687

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

internal/cmd/beta/cdn/distribution/list/list.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package list
33
import (
44
"context"
55
"fmt"
6+
"math"
67
"strings"
78

89
"github.com/spf13/cobra"
@@ -23,10 +24,13 @@ import (
2324
type inputModel struct {
2425
*globalflags.GlobalFlagModel
2526
SortBy string
27+
Limit *int32
2628
}
2729

2830
const (
29-
sortByFlag = "sort-by"
31+
sortByFlag = "sort-by"
32+
limitFlag = ""
33+
maxPageSize = int32(100)
3034
)
3135

3236
func NewCmd(params *params.CmdParams) *cobra.Command {
@@ -76,6 +80,7 @@ var sortByFlagOptions = []string{"id", "createdAt", "updatedAt", "originUrl", "s
7680
func configureFlags(cmd *cobra.Command) {
7781
// same default as apiClient
7882
cmd.Flags().Var(flags.EnumFlag(false, "createdAt", sortByFlagOptions...), sortByFlag, fmt.Sprintf("Sort entries by a specific field, one of %q", sortByFlagOptions))
83+
cmd.Flags().Int64(limitFlag, 0, "Limit the output to the first n elements")
7984
}
8085

8186
func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
@@ -84,6 +89,14 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
8489
return nil, &errors.ProjectIdError{}
8590
}
8691

92+
limit := flags.FlagToInt32Pointer(p, cmd, limitFlag)
93+
if limit != nil && *limit < 1 {
94+
return nil, &errors.FlagValidationError{
95+
Flag: limitFlag,
96+
Details: "must be greater than 0",
97+
}
98+
}
99+
87100
model := inputModel{
88101
GlobalFlagModel: globalFlags,
89102
SortBy: flags.FlagWithDefaultToStringValue(p, cmd, sortByFlag),
@@ -93,10 +106,10 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
93106
return &model, nil
94107
}
95108

96-
func buildRequest(ctx context.Context, model *inputModel, apiClient *cdn.APIClient, nextPageID cdn.ListDistributionsResponseGetNextPageIdentifierAttributeType) cdn.ApiListDistributionsRequest {
109+
func buildRequest(ctx context.Context, model *inputModel, apiClient *cdn.APIClient, nextPageID cdn.ListDistributionsResponseGetNextPageIdentifierAttributeType, pageLimit int32) cdn.ApiListDistributionsRequest {
97110
req := apiClient.ListDistributions(ctx, model.GlobalFlagModel.ProjectId)
98111
req = req.SortBy(model.SortBy)
99-
req = req.PageSize(100)
112+
req = req.PageSize(pageLimit)
100113
if nextPageID != nil {
101114
req = req.PageIdentifier(*nextPageID)
102115
}
@@ -135,17 +148,24 @@ func outputResult(p *print.Printer, outputFormat string, distributions []cdn.Dis
135148
func fetchDistributions(ctx context.Context, model *inputModel, apiClient *cdn.APIClient) ([]cdn.Distribution, error) {
136149
var nextPageID cdn.ListDistributionsResponseGetNextPageIdentifierAttributeType
137150
var distributions []cdn.Distribution
151+
received := int32(0)
152+
limit := int32(math.MaxInt32)
153+
if model.Limit != nil {
154+
limit = utils.Min(limit, *model.Limit)
155+
}
138156
for {
139-
request := buildRequest(ctx, model, apiClient, nextPageID)
157+
want := utils.Min(maxPageSize, limit-received)
158+
request := buildRequest(ctx, model, apiClient, nextPageID, want)
140159
response, err := request.Execute()
141160
if err != nil {
142161
return nil, fmt.Errorf("list distributions: %w", err)
143162
}
144-
nextPageID = response.NextPageIdentifier
145163
if response.Distributions != nil {
146164
distributions = append(distributions, *response.Distributions...)
147165
}
148-
if nextPageID == nil {
166+
nextPageID = response.NextPageIdentifier
167+
received += want
168+
if nextPageID == nil || received >= limit {
149169
break
150170
}
151171
}

internal/cmd/beta/cdn/distribution/list/list_test.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
"fmt"
78
"net/http"
89
"net/http/httptest"
10+
"slices"
911
"testing"
1012

1113
"github.com/google/go-cmp/cmp"
@@ -205,7 +207,7 @@ func TestBuildRequest(t *testing.T) {
205207
}
206208
for _, tt := range tests {
207209
t.Run(tt.description, func(t *testing.T) {
208-
req := buildRequest(testCtx, tt.inputModel, testClient, tt.nextPageID)
210+
req := buildRequest(testCtx, tt.inputModel, testClient, tt.nextPageID, maxPageSize)
209211
diff := cmp.Diff(req, tt.expected,
210212
cmp.AllowUnexported(tt.expected),
211213
cmpopts.EquateComparable(testCtx),
@@ -256,9 +258,21 @@ func fixtureDistribution(id string) cdn.Distribution {
256258
}
257259
}
258260

261+
func fixtureDistributions(count int) []cdn.Distribution {
262+
distributions := make([]cdn.Distribution, count)
263+
for i := 0; i < count; i++ {
264+
id := fmt.Sprintf("dist-%d", i+1)
265+
distributions[i] = cdn.Distribution{
266+
Id: &id,
267+
}
268+
}
269+
return distributions
270+
}
271+
259272
func TestFetchDistributions(t *testing.T) {
260273
tests := []struct {
261274
description string
275+
limit int
262276
responses []testResponse
263277
expected []cdn.Distribution
264278
fails bool
@@ -323,6 +337,20 @@ func TestFetchDistributions(t *testing.T) {
323337
},
324338
fails: true,
325339
},
340+
{
341+
description: "limit across 2 pages",
342+
limit: 110,
343+
responses: []testResponse{
344+
fixtureTestResponse(
345+
responseNextPageID(utils.Ptr(testNextPageID)),
346+
responseDistributions(fixtureDistributions(100)...),
347+
),
348+
fixtureTestResponse(
349+
responseDistributions(fixtureDistributions(10)...),
350+
),
351+
},
352+
expected: slices.Concat(fixtureDistributions(100), fixtureDistributions(10)),
353+
},
326354
}
327355
for _, tt := range tests {
328356
t.Run(tt.description, func(t *testing.T) {
@@ -350,7 +378,14 @@ func TestFetchDistributions(t *testing.T) {
350378
if err != nil {
351379
t.Fatalf("failed to create test client: %v", err)
352380
}
353-
got, err := fetchDistributions(testCtx, fixtureInputModel(), client)
381+
var mods []func(m *inputModel)
382+
if tt.limit > 0 {
383+
mods = append(mods, func(m *inputModel) {
384+
m.Limit = utils.Ptr(int32(tt.limit))
385+
})
386+
}
387+
model := fixtureInputModel(mods...)
388+
got, err := fetchDistributions(testCtx, model, client)
354389
if err != nil {
355390
if !tt.fails {
356391
t.Fatalf("fetchDistributions() unexpected error: %v", err)

0 commit comments

Comments
 (0)