1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Fixes #24696 - fixes size showing 0 in format output

Signed-off-by: Josh Horwitz <horwitz@addthis.com>
This commit is contained in:
Josh Horwitz 2016-07-15 18:37:05 -04:00
parent 9a9fc01af8
commit 456e039659
2 changed files with 122 additions and 31 deletions

View file

@ -9,9 +9,10 @@ import (
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
"github.com/docker/engine-api/types/filters" "github.com/docker/engine-api/types/filters"
"io/ioutil"
"github.com/docker/docker/utils/templates" "github.com/docker/docker/utils/templates"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"io/ioutil"
) )
type psOptions struct { type psOptions struct {
@ -25,16 +26,6 @@ type psOptions struct {
filter []string filter []string
} }
type preProcessor struct {
opts *types.ContainerListOptions
}
// Size sets the size option when called by a template execution.
func (p *preProcessor) Size() bool {
p.opts.Size = true
return true
}
// NewPsCommand creates a new cobra.Command for `docker ps` // NewPsCommand creates a new cobra.Command for `docker ps`
func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command { func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
var opts psOptions var opts psOptions
@ -62,39 +53,65 @@ func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command {
return cmd return cmd
} }
func runPs(dockerCli *client.DockerCli, opts *psOptions) error { type preProcessor struct {
ctx := context.Background() types.Container
opts *types.ContainerListOptions
}
if opts.nLatest && opts.last == -1 { // Size sets the size option when called by a template execution.
opts.last = 1 func (p *preProcessor) Size() bool {
} p.opts.Size = true
return true
}
containerFilterArgs := filters.NewArgs() func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
for _, f := range opts.filter {
var err error
containerFilterArgs, err = filters.ParseFlag(f, containerFilterArgs)
if err != nil {
return err
}
}
options := types.ContainerListOptions{ options := &types.ContainerListOptions{
All: opts.all, All: opts.all,
Limit: opts.last, Limit: opts.last,
Size: opts.size, Size: opts.size,
Filter: containerFilterArgs, Filter: filters.NewArgs(),
} }
pre := &preProcessor{opts: &options} if opts.nLatest && opts.last == -1 {
options.Limit = 1
}
for _, f := range opts.filter {
var err error
options.Filter, err = filters.ParseFlag(f, options.Filter)
if err != nil {
return nil, err
}
}
// Currently only used with Size, so we can determine if the user
// put {{.Size}} in their format.
pre := &preProcessor{opts: options}
tmpl, err := templates.Parse(opts.format) tmpl, err := templates.Parse(opts.format)
if err != nil {
return nil, err
}
// This shouldn't error out but swallowing the error makes it harder
// to track down if preProcessor issues come up. Ref #24696
if err := tmpl.Execute(ioutil.Discard, pre); err != nil {
return nil, err
}
return options, nil
}
func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
ctx := context.Background()
listOptions, err := buildContainerListOptions(opts)
if err != nil { if err != nil {
return err return err
} }
_ = tmpl.Execute(ioutil.Discard, pre) containers, err := dockerCli.Client().ContainerList(ctx, *listOptions)
containers, err := dockerCli.Client().ContainerList(ctx, options)
if err != nil { if err != nil {
return err return err
} }
@ -115,7 +132,7 @@ func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
Quiet: opts.quiet, Quiet: opts.quiet,
Trunc: !opts.noTrunc, Trunc: !opts.noTrunc,
}, },
Size: opts.size, Size: listOptions.Size,
Containers: containers, Containers: containers,
} }

View file

@ -0,0 +1,74 @@
package container
import "testing"
func TestBuildContainerListOptions(t *testing.T) {
contexts := []struct {
psOpts *psOptions
expectedAll bool
expectedSize bool
expectedLimit int
expectedFilters map[string]string
}{
{
psOpts: &psOptions{
all: true,
size: true,
last: 5,
filter: []string{"foo=bar", "baz=foo"},
},
expectedAll: true,
expectedSize: true,
expectedLimit: 5,
expectedFilters: map[string]string{
"foo": "bar",
"baz": "foo",
},
},
{
psOpts: &psOptions{
all: true,
size: true,
last: -1,
nLatest: true,
},
expectedAll: true,
expectedSize: true,
expectedLimit: 1,
expectedFilters: make(map[string]string),
},
}
for _, c := range contexts {
options, err := buildContainerListOptions(c.psOpts)
if err != nil {
t.Fatal(err)
}
if c.expectedAll != options.All {
t.Fatalf("Expected All to be %t but got %t", c.expectedAll, options.All)
}
if c.expectedSize != options.Size {
t.Fatalf("Expected Size to be %t but got %t", c.expectedSize, options.Size)
}
if c.expectedLimit != options.Limit {
t.Fatalf("Expected Limit to be %d but got %d", c.expectedLimit, options.Limit)
}
f := options.Filter
if f.Len() != len(c.expectedFilters) {
t.Fatalf("Expected %d filters but got %d", len(c.expectedFilters), f.Len())
}
for k, v := range c.expectedFilters {
f := options.Filter
if !f.ExactMatch(k, v) {
t.Fatalf("Expected filter with key %s to be %s but got %s", k, v, f.Get(k))
}
}
}
}