Skip to content

Commit c549fd7

Browse files
authored
Merge pull request #4067 from laurazard/size-flag-ps
Don't automatically request size if `--size` was explicitly set to `false`
2 parents cb5463a + 9733334 commit c549fd7

2 files changed

Lines changed: 74 additions & 25 deletions

File tree

cli/command/container/list.go

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ import (
1717
)
1818

1919
type psOptions struct {
20-
quiet bool
21-
size bool
22-
all bool
23-
noTrunc bool
24-
nLatest bool
25-
last int
26-
format string
27-
filter opts.FilterOpt
20+
quiet bool
21+
size bool
22+
sizeChanged bool
23+
all bool
24+
noTrunc bool
25+
nLatest bool
26+
last int
27+
format string
28+
filter opts.FilterOpt
2829
}
2930

3031
// NewPsCommand creates a new cobra.Command for `docker ps`
@@ -36,6 +37,7 @@ func NewPsCommand(dockerCli command.Cli) *cobra.Command {
3637
Short: "List containers",
3738
Args: cli.NoArgs,
3839
RunE: func(cmd *cobra.Command, args []string) error {
40+
options.sizeChanged = cmd.Flags().Changed("size")
3941
return runPs(dockerCli, &options)
4042
},
4143
Annotations: map[string]string{
@@ -78,13 +80,8 @@ func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, er
7880
options.Limit = 1
7981
}
8082

81-
if !opts.quiet && !options.Size && len(opts.format) > 0 {
82-
// The --size option isn't set, but .Size may be used in the template.
83-
// Parse and execute the given template to detect if the .Size field is
84-
// used. If it is, then automatically enable the --size option. See #24696
85-
//
86-
// Only requesting container size information when needed is an optimization,
87-
// because calculating the size is a costly operation.
83+
// always validate template when `--format` is used, for consistency
84+
if len(opts.format) > 0 {
8885
tmpl, err := templates.NewParse("", opts.format)
8986
if err != nil {
9087
return nil, errors.Wrap(err, "failed to parse template")
@@ -98,8 +95,19 @@ func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, er
9895
return nil, errors.Wrap(err, "failed to execute template")
9996
}
10097

101-
if _, ok := optionsProcessor.FieldsUsed["Size"]; ok {
102-
options.Size = true
98+
// if `size` was not explicitly set to false (with `--size=false`)
99+
// and `--quiet` is not set, request size if the template requires it
100+
if !opts.quiet && !options.Size && !opts.sizeChanged {
101+
// The --size option isn't set, but .Size may be used in the template.
102+
// Parse and execute the given template to detect if the .Size field is
103+
// used. If it is, then automatically enable the --size option. See #24696
104+
//
105+
// Only requesting container size information when needed is an optimization,
106+
// because calculating the size is a costly operation.
107+
108+
if _, ok := optionsProcessor.FieldsUsed["Size"]; ok {
109+
options.Size = true
110+
}
103111
}
104112
}
105113

cli/command/container/list_test.go

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,56 @@ func TestContainerListFormatTemplateWithArg(t *testing.T) {
231231
}
232232

233233
func TestContainerListFormatSizeSetsOption(t *testing.T) {
234-
cli := test.NewFakeCli(&fakeClient{
235-
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
236-
assert.Check(t, options.Size)
237-
return []types.Container{}, nil
234+
tests := []struct {
235+
doc, format, sizeFlag string
236+
sizeExpected bool
237+
}{
238+
{
239+
doc: "detect with all fields",
240+
format: `{{json .}}`,
241+
sizeExpected: true,
238242
},
239-
})
240-
cmd := newListCommand(cli)
241-
cmd.Flags().Set("format", `{{.Size}}`)
242-
assert.NilError(t, cmd.Execute())
243+
{
244+
doc: "detect with explicit field",
245+
format: `{{.Size}}`,
246+
sizeExpected: true,
247+
},
248+
{
249+
doc: "detect no size",
250+
format: `{{.Names}}`,
251+
sizeExpected: false,
252+
},
253+
{
254+
doc: "override enable",
255+
format: `{{.Names}}`,
256+
sizeFlag: "true",
257+
sizeExpected: true,
258+
},
259+
{
260+
doc: "override disable",
261+
format: `{{.Size}}`,
262+
sizeFlag: "false",
263+
sizeExpected: false,
264+
},
265+
}
266+
267+
for _, tc := range tests {
268+
tc := tc
269+
t.Run(tc.doc, func(t *testing.T) {
270+
cli := test.NewFakeCli(&fakeClient{
271+
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
272+
assert.Check(t, is.Equal(options.Size, tc.sizeExpected))
273+
return []types.Container{}, nil
274+
},
275+
})
276+
cmd := newListCommand(cli)
277+
cmd.Flags().Set("format", tc.format)
278+
if tc.sizeFlag != "" {
279+
cmd.Flags().Set("size", tc.sizeFlag)
280+
}
281+
assert.NilError(t, cmd.Execute())
282+
})
283+
}
243284
}
244285

245286
func TestContainerListWithConfigFormat(t *testing.T) {

0 commit comments

Comments
 (0)