Sort services names in a natural order

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
This commit is contained in:
Boaz Shuster 2017-07-19 10:34:03 +03:00
parent 7f684c7512
commit 7478e47b2d
5 changed files with 82 additions and 26 deletions

View File

@ -0,0 +1,35 @@
package service
import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"golang.org/x/net/context"
)
type fakeClient struct {
client.Client
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error)
}
func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
if f.serviceListFunc != nil {
return f.serviceListFunc(ctx, options)
}
return nil, nil
}
func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
return nil, nil
}
func (f *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
return nil, nil
}
func newService(id string, name string) swarm.Service {
return swarm.Service{
ID: id,
Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}},
}
}

View File

@ -2,6 +2,9 @@ package service
import ( import (
"fmt" "fmt"
"sort"
"vbom.ml/util/sortorder"
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
@ -20,7 +23,7 @@ type listOptions struct {
filter opts.FilterOpt filter opts.FilterOpt
} }
func newListCommand(dockerCli *command.DockerCli) *cobra.Command { func newListCommand(dockerCli command.Cli) *cobra.Command {
options := listOptions{filter: opts.NewFilterOpt()} options := listOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -41,7 +44,13 @@ func newListCommand(dockerCli *command.DockerCli) *cobra.Command {
return cmd return cmd
} }
func runList(dockerCli *command.DockerCli, options listOptions) error { type byName []swarm.Service
func (n byName) Len() int { return len(n) }
func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Spec.Name, n[j].Spec.Name) }
func runList(dockerCli command.Cli, options listOptions) error {
ctx := context.Background() ctx := context.Background()
client := dockerCli.Client() client := dockerCli.Client()
@ -51,6 +60,7 @@ func runList(dockerCli *command.DockerCli, options listOptions) error {
return err return err
} }
sort.Sort(byName(services))
info := map[string]formatter.ServiceListInfo{} info := map[string]formatter.ServiceListInfo{}
if len(services) > 0 && !options.quiet { if len(services) > 0 && !options.quiet {
// only non-empty services and not quiet, should we call TaskList and NodeList api // only non-empty services and not quiet, should we call TaskList and NodeList api

View File

@ -0,0 +1,32 @@
package service
import (
"testing"
"golang.org/x/net/context"
"github.com/docker/cli/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/pkg/testutil"
"github.com/docker/docker/pkg/testutil/golden"
"github.com/stretchr/testify/assert"
)
func TestServiceListOrder(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
return []swarm.Service{
newService("a57dbe8", "service-1-foo"),
newService("a57dbdd", "service-10-foo"),
newService("aaaaaaa", "service-2-foo"),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Name}}")
assert.NoError(t, cmd.Execute())
actual := cli.OutBuffer().String()
expected := golden.Get(t, []byte(actual), "service-list-sort.golden")
testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected))
}

View File

@ -10,35 +10,11 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
type fakeClient struct {
client.Client
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error)
}
func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
if f.serviceListFunc != nil {
return f.serviceListFunc(ctx, options)
}
return nil, nil
}
func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {
return nil, nil
}
func newService(id string, name string) swarm.Service {
return swarm.Service{
ID: id,
Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}},
}
}
func TestCreateFilter(t *testing.T) { func TestCreateFilter(t *testing.T) {
client := &fakeClient{ client := &fakeClient{
serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {

View File

@ -0,0 +1,3 @@
service-1-foo
service-2-foo
service-10-foo