Browse code

Use spf13/cobra for docker images

This fix is part of the effort to convert commands to spf13/cobra #23211.

Thif fix coverted command `docker images` to use spf13/cobra

NOTE: As part of this fix, a new function `RequiresMaxArgs()`
has been defined in `cli/required.go`. This func returns an
error if there is not at most max args

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/06/06 12:55:47
Showing 6 changed files
... ...
@@ -8,7 +8,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
8 8
 		"cp":      cli.CmdCp,
9 9
 		"events":  cli.CmdEvents,
10 10
 		"exec":    cli.CmdExec,
11
-		"images":  cli.CmdImages,
12 11
 		"info":    cli.CmdInfo,
13 12
 		"inspect": cli.CmdInspect,
14 13
 		"load":    cli.CmdLoad,
15 14
new file mode 100644
... ...
@@ -0,0 +1,103 @@
0
+package image
1
+
2
+import (
3
+	"golang.org/x/net/context"
4
+
5
+	"github.com/docker/docker/api/client"
6
+	"github.com/docker/docker/api/client/formatter"
7
+	"github.com/docker/docker/cli"
8
+	"github.com/docker/engine-api/types"
9
+	"github.com/docker/engine-api/types/filters"
10
+	"github.com/spf13/cobra"
11
+)
12
+
13
+type imagesOptions struct {
14
+	matchName string
15
+
16
+	quiet       bool
17
+	all         bool
18
+	noTrunc     bool
19
+	showDigests bool
20
+	format      string
21
+	filter      []string
22
+}
23
+
24
+// NewImagesCommand create a new `docker images` command
25
+func NewImagesCommand(dockerCli *client.DockerCli) *cobra.Command {
26
+	var opts imagesOptions
27
+
28
+	cmd := &cobra.Command{
29
+		Use:   "images [OPTIONS] [REPOSITORY[:TAG]]",
30
+		Short: "List images",
31
+		Args:  cli.RequiresMaxArgs(1),
32
+		RunE: func(cmd *cobra.Command, args []string) error {
33
+			if len(args) > 0 {
34
+				opts.matchName = args[0]
35
+			}
36
+			return runImages(dockerCli, opts)
37
+		},
38
+	}
39
+
40
+	flags := cmd.Flags()
41
+
42
+	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show numeric IDs")
43
+	flags.BoolVarP(&opts.all, "all", "a", false, "Show all images (default hides intermediate images)")
44
+	flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
45
+	flags.BoolVar(&opts.showDigests, "digests", false, "Show digests")
46
+	flags.StringVar(&opts.format, "format", "", "Pretty-print images using a Go template")
47
+	flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided")
48
+
49
+	return cmd
50
+}
51
+
52
+func runImages(dockerCli *client.DockerCli, opts imagesOptions) error {
53
+	ctx := context.Background()
54
+
55
+	// Consolidate all filter flags, and sanity check them early.
56
+	// They'll get process in the daemon/server.
57
+	imageFilterArgs := filters.NewArgs()
58
+	for _, f := range opts.filter {
59
+		var err error
60
+		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
61
+		if err != nil {
62
+			return err
63
+		}
64
+	}
65
+
66
+	matchName := opts.matchName
67
+
68
+	options := types.ImageListOptions{
69
+		MatchName: matchName,
70
+		All:       opts.all,
71
+		Filters:   imageFilterArgs,
72
+	}
73
+
74
+	images, err := dockerCli.Client().ImageList(ctx, options)
75
+	if err != nil {
76
+		return err
77
+	}
78
+
79
+	f := opts.format
80
+	if len(f) == 0 {
81
+		if len(dockerCli.ImagesFormat()) > 0 && !opts.quiet {
82
+			f = dockerCli.ImagesFormat()
83
+		} else {
84
+			f = "table"
85
+		}
86
+	}
87
+
88
+	imagesCtx := formatter.ImageContext{
89
+		Context: formatter.Context{
90
+			Output: dockerCli.Out(),
91
+			Format: f,
92
+			Quiet:  opts.quiet,
93
+			Trunc:  !opts.noTrunc,
94
+		},
95
+		Digest: opts.showDigests,
96
+		Images: images,
97
+	}
98
+
99
+	imagesCtx.Write()
100
+
101
+	return nil
102
+}
0 103
deleted file mode 100644
... ...
@@ -1,81 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"golang.org/x/net/context"
5
-
6
-	"github.com/docker/docker/api/client/formatter"
7
-	Cli "github.com/docker/docker/cli"
8
-	"github.com/docker/docker/opts"
9
-	flag "github.com/docker/docker/pkg/mflag"
10
-	"github.com/docker/engine-api/types"
11
-	"github.com/docker/engine-api/types/filters"
12
-)
13
-
14
-// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
15
-//
16
-// Usage: docker images [OPTIONS] [REPOSITORY]
17
-func (cli *DockerCli) CmdImages(args ...string) error {
18
-	cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true)
19
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
20
-	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
21
-	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
22
-	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
23
-	format := cmd.String([]string{"-format"}, "", "Pretty-print images using a Go template")
24
-
25
-	flFilter := opts.NewListOpts(nil)
26
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
27
-	cmd.Require(flag.Max, 1)
28
-
29
-	cmd.ParseFlags(args, true)
30
-
31
-	// Consolidate all filter flags, and sanity check them early.
32
-	// They'll get process in the daemon/server.
33
-	imageFilterArgs := filters.NewArgs()
34
-	for _, f := range flFilter.GetAll() {
35
-		var err error
36
-		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
37
-		if err != nil {
38
-			return err
39
-		}
40
-	}
41
-
42
-	var matchName string
43
-	if cmd.NArg() == 1 {
44
-		matchName = cmd.Arg(0)
45
-	}
46
-
47
-	options := types.ImageListOptions{
48
-		MatchName: matchName,
49
-		All:       *all,
50
-		Filters:   imageFilterArgs,
51
-	}
52
-
53
-	images, err := cli.client.ImageList(context.Background(), options)
54
-	if err != nil {
55
-		return err
56
-	}
57
-
58
-	f := *format
59
-	if len(f) == 0 {
60
-		if len(cli.ImagesFormat()) > 0 && !*quiet {
61
-			f = cli.ImagesFormat()
62
-		} else {
63
-			f = "table"
64
-		}
65
-	}
66
-
67
-	imagesCtx := formatter.ImageContext{
68
-		Context: formatter.Context{
69
-			Output: cli.out,
70
-			Format: f,
71
-			Quiet:  *quiet,
72
-			Trunc:  !*noTrunc,
73
-		},
74
-		Digest: *showDigests,
75
-		Images: images,
76
-	}
77
-
78
-	imagesCtx.Write()
79
-
80
-	return nil
81
-}
... ...
@@ -51,6 +51,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
51 51
 		container.NewUnpauseCommand(dockerCli),
52 52
 		container.NewWaitCommand(dockerCli),
53 53
 		image.NewHistoryCommand(dockerCli),
54
+		image.NewImagesCommand(dockerCli),
54 55
 		image.NewRemoveCommand(dockerCli),
55 56
 		image.NewSearchCommand(dockerCli),
56 57
 		image.NewImportCommand(dockerCli),
... ...
@@ -43,6 +43,23 @@ func RequiresMinArgs(min int) cobra.PositionalArgs {
43 43
 	}
44 44
 }
45 45
 
46
+// RequiresMaxArgs returns an error if there is not at most max args
47
+func RequiresMaxArgs(max int) cobra.PositionalArgs {
48
+	return func(cmd *cobra.Command, args []string) error {
49
+		if len(args) <= max {
50
+			return nil
51
+		}
52
+		return fmt.Errorf(
53
+			"\"%s\" requires at most %d argument(s).\nSee '%s --help'.\n\nUsage:  %s\n\n%s",
54
+			cmd.CommandPath(),
55
+			max,
56
+			cmd.CommandPath(),
57
+			cmd.UseLine(),
58
+			cmd.Short,
59
+		)
60
+	}
61
+}
62
+
46 63
 // RequiresMinMaxArgs returns an error if there is not at least min args and at most max args
47 64
 func RequiresMinMaxArgs(min int, max int) cobra.PositionalArgs {
48 65
 	return func(cmd *cobra.Command, args []string) error {
... ...
@@ -13,7 +13,6 @@ var DockerCommandUsage = []Command{
13 13
 	{"cp", "Copy files/folders between a container and the local filesystem"},
14 14
 	{"events", "Get real time events from the server"},
15 15
 	{"exec", "Run a command in a running container"},
16
-	{"images", "List images"},
17 16
 	{"info", "Display system-wide information"},
18 17
 	{"inspect", "Return low-level information on a container or image"},
19 18
 	{"load", "Load an image from a tar archive or STDIN"},