Skip to content

Commit b3cd9d4

Browse files
authored
Merge pull request #6393 from thaJeztah/cleanup_stacks
cli/command/stack: cleanups and optimizations
2 parents 8f25f4f + 581cb2b commit b3cd9d4

File tree

5 files changed

+66
-72
lines changed

5 files changed

+66
-72
lines changed

cli/command/stack/formatter/formatter.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,28 @@ type Stack struct {
4343
// StackWrite writes formatted stacks using the Context
4444
//
4545
// Deprecated: this function was for internal use and will be removed in the next release.
46-
func StackWrite(ctx formatter.Context, stacks []*Stack) error {
47-
render := func(format func(subContext formatter.SubContext) error) error {
46+
func StackWrite(ctx formatter.Context, stacks []Stack) error {
47+
fmtCtx := &stackContext{
48+
HeaderContext: formatter.HeaderContext{
49+
Header: formatter.SubHeaderContext{
50+
"Name": formatter.NameHeader,
51+
"Services": stackServicesHeader,
52+
},
53+
},
54+
}
55+
return ctx.Write(fmtCtx, func(format func(subContext formatter.SubContext) error) error {
4856
for _, stack := range stacks {
4957
if err := format(&stackContext{s: stack}); err != nil {
5058
return err
5159
}
5260
}
5361
return nil
54-
}
55-
return ctx.Write(newStackContext(), render)
62+
})
5663
}
5764

5865
type stackContext struct {
5966
formatter.HeaderContext
60-
s *Stack
61-
}
62-
63-
func newStackContext() *stackContext {
64-
stackCtx := stackContext{}
65-
stackCtx.Header = formatter.SubHeaderContext{
66-
"Name": formatter.NameHeader,
67-
"Services": stackServicesHeader,
68-
}
69-
return &stackCtx
67+
s Stack
7068
}
7169

7270
func (s *stackContext) MarshalJSON() ([]byte, error) {

cli/command/stack/formatter/formatter_test.go

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,57 @@ import (
99
)
1010

1111
func TestStackContextWrite(t *testing.T) {
12-
cases := []struct {
13-
context formatter.Context
12+
tests := []struct {
13+
name string
14+
format formatter.Format
1415
expected string
1516
}{
16-
// Errors
1717
{
18-
formatter.Context{Format: "{{InvalidFunction}}"},
19-
`template parsing error: template: :1: function "InvalidFunction" not defined`,
18+
name: "invalid function",
19+
format: `{{InvalidFunction}}`,
20+
expected: `template parsing error: template: :1: function "InvalidFunction" not defined`,
2021
},
2122
{
22-
formatter.Context{Format: "{{nil}}"},
23-
`template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
23+
name: "invalid placeholder",
24+
format: `{{nil}}`,
25+
expected: `template parsing error: template: :1:2: executing "" at <nil>: nil is not a command`,
2426
},
25-
// Table format
2627
{
27-
formatter.Context{Format: SwarmStackTableFormat},
28-
`NAME SERVICES
28+
name: "table format",
29+
format: SwarmStackTableFormat,
30+
expected: `NAME SERVICES
2931
baz 2
3032
bar 1
3133
`,
3234
},
3335
{
34-
formatter.Context{Format: formatter.Format("table {{.Name}}")},
35-
`NAME
36+
name: "custom table format",
37+
format: `table {{.Name}}`,
38+
expected: `NAME
3639
baz
3740
bar
3841
`,
3942
},
40-
// Custom Format
4143
{
42-
formatter.Context{Format: formatter.Format("{{.Name}}")},
43-
`baz
44+
name: "custom format",
45+
format: `{{.Name}}`,
46+
expected: `baz
4447
bar
4548
`,
4649
},
4750
}
4851

49-
stacks := []*Stack{
50-
{Name: "baz", Services: 2},
51-
{Name: "bar", Services: 1},
52-
}
53-
for _, tc := range cases {
54-
t.Run(string(tc.context.Format), func(t *testing.T) {
52+
for _, tc := range tests {
53+
t.Run(tc.name, func(t *testing.T) {
5554
var out bytes.Buffer
56-
tc.context.Output = &out
57-
58-
if err := StackWrite(tc.context, stacks); err != nil {
55+
fmtCtx := formatter.Context{
56+
Format: tc.format,
57+
Output: &out,
58+
}
59+
if err := StackWrite(fmtCtx, []Stack{
60+
{Name: "baz", Services: 2},
61+
{Name: "bar", Services: 1},
62+
}); err != nil {
5963
assert.Error(t, err, tc.expected)
6064
} else {
6165
assert.Equal(t, out.String(), tc.expected)

cli/command/stack/list.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,14 @@ func RunList(ctx context.Context, dockerCLI command.Cli, opts options.List) erro
4646

4747
// runList performs a stack list against the specified swarm cluster
4848
func runList(ctx context.Context, dockerCLI command.Cli, opts listOptions) error {
49-
ss, err := swarm.GetStacks(ctx, dockerCLI.Client())
49+
stacks, err := swarm.GetStacks(ctx, dockerCLI.Client())
5050
if err != nil {
5151
return err
5252
}
53-
stacks := make([]*formatter.Stack, 0, len(ss))
54-
stacks = append(stacks, ss...)
5553
return format(dockerCLI.Out(), opts, stacks)
5654
}
5755

58-
func format(out io.Writer, opts listOptions, stacks []*formatter.Stack) error {
56+
func format(out io.Writer, opts listOptions, stacks []formatter.Stack) error {
5957
fmt := formatter.Format(opts.Format)
6058
if fmt == "" || fmt == formatter.TableFormatKey {
6159
fmt = formatter.SwarmStackTableFormat

cli/command/stack/swarm/deploy.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,19 @@ func checkDaemonIsSwarmManager(ctx context.Context, dockerCli command.Cli) error
6969
}
7070

7171
// pruneServices removes services that are no longer referenced in the source
72-
func pruneServices(ctx context.Context, dockerCCLI command.Cli, namespace convert.Namespace, services map[string]struct{}) {
73-
apiClient := dockerCCLI.Client()
72+
func pruneServices(ctx context.Context, dockerCLI command.Cli, namespace convert.Namespace, services map[string]struct{}) {
73+
apiClient := dockerCLI.Client()
7474

7575
oldServices, err := getStackServices(ctx, apiClient, namespace.Name())
7676
if err != nil {
77-
_, _ = fmt.Fprintln(dockerCCLI.Err(), "Failed to list services:", err)
77+
_, _ = fmt.Fprintln(dockerCLI.Err(), "Failed to list services:", err)
7878
}
7979

80-
pruneServices := []swarm.Service{}
80+
toRemove := make([]swarm.Service, 0, len(oldServices))
8181
for _, service := range oldServices {
8282
if _, exists := services[namespace.Descope(service.Spec.Name)]; !exists {
83-
pruneServices = append(pruneServices, service)
83+
toRemove = append(toRemove, service)
8484
}
8585
}
86-
removeServices(ctx, dockerCCLI, pruneServices)
86+
removeServices(ctx, dockerCLI, toRemove)
8787
}

cli/command/stack/swarm/list.go

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,31 @@ import (
99
"github.com/pkg/errors"
1010
)
1111

12-
// GetStacks lists the swarm stacks.
12+
// GetStacks lists the swarm stacks with the number of services they contain.
1313
//
1414
// Deprecated: this function was for internal use and will be removed in the next release.
15-
func GetStacks(ctx context.Context, apiClient client.ServiceAPIClient) ([]*formatter.Stack, error) {
16-
services, err := apiClient.ServiceList(
17-
ctx,
18-
client.ServiceListOptions{Filters: getAllStacksFilter()})
15+
func GetStacks(ctx context.Context, apiClient client.ServiceAPIClient) ([]formatter.Stack, error) {
16+
services, err := apiClient.ServiceList(ctx, client.ServiceListOptions{
17+
Filters: getAllStacksFilter(),
18+
})
1919
if err != nil {
2020
return nil, err
2121
}
22-
m := make(map[string]*formatter.Stack)
23-
for _, service := range services {
24-
labels := service.Spec.Labels
25-
name, ok := labels[convert.LabelNamespace]
22+
23+
idx := make(map[string]int, len(services))
24+
out := make([]formatter.Stack, 0, len(services))
25+
26+
for _, svc := range services {
27+
name, ok := svc.Spec.Labels[convert.LabelNamespace]
2628
if !ok {
27-
return nil, errors.Errorf("cannot get label %s for service %s",
28-
convert.LabelNamespace, service.ID)
29+
return nil, errors.New("cannot get label " + convert.LabelNamespace + " for service " + svc.ID)
2930
}
30-
ztack, ok := m[name]
31-
if !ok {
32-
m[name] = &formatter.Stack{
33-
Name: name,
34-
Services: 1,
35-
}
36-
} else {
37-
ztack.Services++
31+
if i, ok := idx[name]; ok {
32+
out[i].Services++
33+
continue
3834
}
35+
idx[name] = len(out)
36+
out = append(out, formatter.Stack{Name: name, Services: 1})
3937
}
40-
stacks := make([]*formatter.Stack, 0, len(m))
41-
for _, stack := range m {
42-
stacks = append(stacks, stack)
43-
}
44-
return stacks, nil
38+
return out, nil
4539
}

0 commit comments

Comments
 (0)