Skip to content

Commit 770a0a0

Browse files
authored
feat: add paging flags for list commands that support paging (#297)
This also increases the default page size from 10 to 100.
1 parent db3d235 commit 770a0a0

7 files changed

Lines changed: 107 additions & 20 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Add managed object storage name to `show` and `list` command outputs.
1313
- Add completions for managed object storages and allow using managed object storage name (in addition to its UUID) as a positional argument.
14+
- Add paging flags (`--limit` and `--page`) to `database`, `gateway`, `loadbalancer`, and `objectstorage` list commands
1415

1516
## [3.6.0] - 2024-03-07
1617

internal/commands/database/list.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
55
"github.com/UpCloudLtd/upcloud-cli/v3/internal/format"
66
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
7+
"github.com/UpCloudLtd/upcloud-cli/v3/internal/paging"
78
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
89
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
10+
"github.com/spf13/pflag"
911
)
1012

1113
// ListCommand creates the "database list" command
@@ -17,12 +19,21 @@ func ListCommand() commands.Command {
1719

1820
type listCommand struct {
1921
*commands.BaseCommand
22+
paging.PageParameters
23+
}
24+
25+
func (s *listCommand) InitCommand() {
26+
fs := &pflag.FlagSet{}
27+
s.ConfigureFlags(fs)
28+
s.AddFlags(fs)
2029
}
2130

2231
// ExecuteWithoutArguments implements commands.NoArgumentCommand
2332
func (s *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Output, error) {
2433
svc := exec.All()
25-
databases, err := svc.GetManagedDatabases(exec.Context(), &request.GetManagedDatabasesRequest{})
34+
databases, err := svc.GetManagedDatabases(exec.Context(), &request.GetManagedDatabasesRequest{
35+
Page: s.Page(),
36+
})
2637
if err != nil {
2738
return nil, err
2839
}

internal/commands/database/list_test.go

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,50 @@ import (
99
"github.com/UpCloudLtd/upcloud-cli/v3/internal/mockexecute"
1010

1111
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
12+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
1213
"github.com/jedib0t/go-pretty/v6/text"
1314
"github.com/stretchr/testify/assert"
14-
"github.com/stretchr/testify/mock"
1515
)
1616

1717
func TestDatabaseListTitleFallback(t *testing.T) {
1818
text.DisableColors()
1919
databases := []upcloud.ManagedDatabase{
20-
{UUID: "091f1afe-4ddd-4d43-afad-6aa3069cc7fe", Title: "service-name", Name: "hotname-prefix-1", State: "running"},
21-
{UUID: "091f1afe-4ddd-4d43-afad-6aa3069cc7fe", Name: "hotname-prefix-2", State: "running"},
20+
{UUID: "091f1afe-4ddd-4d43-afad-6aa3069cc7fe", Title: "service-name", Name: "hostname-prefix-1", State: "running"},
21+
{UUID: "091f1afe-4ddd-4d43-afad-6aa3069cc7fe", Name: "hostname-prefix-2", State: "running"},
2222
}
2323

24-
mService := smock.Service{}
25-
mService.On("GetManagedDatabases", mock.Anything).Return(databases, nil)
26-
27-
conf := config.New()
28-
command := commands.BuildCommand(ListCommand(), nil, conf)
29-
30-
output, err := mockexecute.MockExecute(command, &mService, conf)
31-
32-
assert.NoError(t, err)
33-
assert.Regexp(t, `UUID\s+Title\s+Type\s+Plan\s+Zone\s+State`, output)
34-
assert.Contains(t, output, "service-name")
35-
assert.NotContains(t, output, "hotname-prefix-1")
36-
assert.Contains(t, output, "hotname-prefix-2")
24+
for _, test := range []struct {
25+
name string
26+
args []string
27+
page request.Page
28+
}{
29+
{
30+
name: "default page",
31+
page: request.Page{Size: 100, Number: 0},
32+
},
33+
{
34+
name: "limit and page args",
35+
page: request.Page{Size: 18, Number: 19},
36+
args: []string{"--limit", "18", "--page", "19"},
37+
},
38+
} {
39+
t.Run(test.name, func(t *testing.T) {
40+
page := test.page
41+
42+
mService := smock.Service{}
43+
mService.On("GetManagedDatabases", &request.GetManagedDatabasesRequest{Page: &page}).Return(databases, nil)
44+
45+
conf := config.New()
46+
command := commands.BuildCommand(ListCommand(), nil, conf)
47+
command.Cobra().SetArgs(test.args)
48+
49+
output, err := mockexecute.MockExecute(command, &mService, conf)
50+
51+
assert.NoError(t, err)
52+
assert.Regexp(t, `UUID\s+Title\s+Type\s+Plan\s+Zone\s+State`, output)
53+
assert.Contains(t, output, "service-name")
54+
assert.NotContains(t, output, "hostname-prefix-1")
55+
assert.Contains(t, output, "hostname-prefix-2")
56+
})
57+
}
3758
}

internal/commands/gateway/list.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66

77
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
88
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
9+
"github.com/UpCloudLtd/upcloud-cli/v3/internal/paging"
910
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
1011
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
1112
"github.com/jedib0t/go-pretty/v6/text"
13+
"github.com/spf13/pflag"
1214
)
1315

1416
// ListCommand creates the "gateway list" command
@@ -20,12 +22,19 @@ func ListCommand() commands.Command {
2022

2123
type listCommand struct {
2224
*commands.BaseCommand
25+
paging.PageParameters
26+
}
27+
28+
func (c *listCommand) InitCommand() {
29+
fs := &pflag.FlagSet{}
30+
c.PageParameters.ConfigureFlags(fs)
31+
c.AddFlags(fs)
2332
}
2433

2534
// ExecuteWithoutArguments implements commands.NoArgumentCommand
2635
func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Output, error) {
2736
svc := exec.All()
28-
gateways, err := svc.GetGateways(exec.Context())
37+
gateways, err := svc.GetGateways(exec.Context(), c.Page())
2938
if err != nil {
3039
return nil, err
3140
}

internal/commands/loadbalancer/list.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import (
44
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
55
"github.com/UpCloudLtd/upcloud-cli/v3/internal/format"
66
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
7+
"github.com/UpCloudLtd/upcloud-cli/v3/internal/paging"
78
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
89
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
10+
"github.com/spf13/pflag"
911
)
1012

1113
// ListCommand creates the "loadbalancer list" command
@@ -17,12 +19,21 @@ func ListCommand() commands.Command {
1719

1820
type listCommand struct {
1921
*commands.BaseCommand
22+
paging.PageParameters
23+
}
24+
25+
func (s *listCommand) InitCommand() {
26+
fs := &pflag.FlagSet{}
27+
s.ConfigureFlags(fs)
28+
s.AddFlags(fs)
2029
}
2130

2231
// ExecuteWithoutArguments implements commands.NoArgumentCommand
2332
func (s *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Output, error) {
2433
svc := exec.All()
25-
loadbalancers, err := svc.GetLoadBalancers(exec.Context(), &request.GetLoadBalancersRequest{})
34+
loadbalancers, err := svc.GetLoadBalancers(exec.Context(), &request.GetLoadBalancersRequest{
35+
Page: s.Page(),
36+
})
2637
if err != nil {
2738
return nil, err
2839
}

internal/commands/objectstorage/list.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
55
"github.com/UpCloudLtd/upcloud-cli/v3/internal/format"
66
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
7+
"github.com/UpCloudLtd/upcloud-cli/v3/internal/paging"
78
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
9+
"github.com/spf13/pflag"
810

911
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
1012
)
@@ -18,12 +20,21 @@ func ListCommand() commands.Command {
1820

1921
type listCommand struct {
2022
*commands.BaseCommand
23+
paging.PageParameters
24+
}
25+
26+
func (c *listCommand) InitCommand() {
27+
fs := &pflag.FlagSet{}
28+
c.ConfigureFlags(fs)
29+
c.AddFlags(fs)
2130
}
2231

2332
// ExecuteWithoutArguments implements commands.NoArgumentCommand
2433
func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Output, error) {
2534
svc := exec.All()
26-
objectstorages, err := svc.GetManagedObjectStorages(exec.Context(), &request.GetManagedObjectStoragesRequest{})
35+
objectstorages, err := svc.GetManagedObjectStorages(exec.Context(), &request.GetManagedObjectStoragesRequest{
36+
Page: c.Page(),
37+
})
2738
if err != nil {
2839
return nil, err
2940
}

internal/paging/paging.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package paging
2+
3+
import (
4+
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
5+
"github.com/spf13/pflag"
6+
)
7+
8+
type PageParameters struct {
9+
size int
10+
number int
11+
}
12+
13+
func (pp *PageParameters) ConfigureFlags(fs *pflag.FlagSet) {
14+
fs.IntVar(&pp.size, "limit", 100, "Number of entries to receive at most.")
15+
fs.IntVar(&pp.number, "page", 0, "Page number to calculate first item to receive. Page numbers start from `1`.")
16+
}
17+
18+
func (pp *PageParameters) Page() *request.Page {
19+
return &request.Page{
20+
Number: pp.number,
21+
Size: pp.size,
22+
}
23+
}

0 commit comments

Comments
 (0)