浏览代码

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 9 年之前
父节点
当前提交
65a0034c67
共有 6 个文件被更改,包括 121 次插入83 次删除
  1. 0 1
      api/client/commands.go
  2. 103 0
      api/client/image/images.go
  3. 0 81
      api/client/images.go
  4. 1 0
      cli/cobraadaptor/adaptor.go
  5. 17 0
      cli/required.go
  6. 0 1
      cli/usage.go

+ 0 - 1
api/client/commands.go

@@ -8,7 +8,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
 		"cp":      cli.CmdCp,
 		"events":  cli.CmdEvents,
 		"exec":    cli.CmdExec,
-		"images":  cli.CmdImages,
 		"info":    cli.CmdInfo,
 		"inspect": cli.CmdInspect,
 		"load":    cli.CmdLoad,

+ 103 - 0
api/client/image/images.go

@@ -0,0 +1,103 @@
+package image
+
+import (
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/api/client"
+	"github.com/docker/docker/api/client/formatter"
+	"github.com/docker/docker/cli"
+	"github.com/docker/engine-api/types"
+	"github.com/docker/engine-api/types/filters"
+	"github.com/spf13/cobra"
+)
+
+type imagesOptions struct {
+	matchName string
+
+	quiet       bool
+	all         bool
+	noTrunc     bool
+	showDigests bool
+	format      string
+	filter      []string
+}
+
+// NewImagesCommand create a new `docker images` command
+func NewImagesCommand(dockerCli *client.DockerCli) *cobra.Command {
+	var opts imagesOptions
+
+	cmd := &cobra.Command{
+		Use:   "images [OPTIONS] [REPOSITORY[:TAG]]",
+		Short: "List images",
+		Args:  cli.RequiresMaxArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			if len(args) > 0 {
+				opts.matchName = args[0]
+			}
+			return runImages(dockerCli, opts)
+		},
+	}
+
+	flags := cmd.Flags()
+
+	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show numeric IDs")
+	flags.BoolVarP(&opts.all, "all", "a", false, "Show all images (default hides intermediate images)")
+	flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
+	flags.BoolVar(&opts.showDigests, "digests", false, "Show digests")
+	flags.StringVar(&opts.format, "format", "", "Pretty-print images using a Go template")
+	flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided")
+
+	return cmd
+}
+
+func runImages(dockerCli *client.DockerCli, opts imagesOptions) error {
+	ctx := context.Background()
+
+	// Consolidate all filter flags, and sanity check them early.
+	// They'll get process in the daemon/server.
+	imageFilterArgs := filters.NewArgs()
+	for _, f := range opts.filter {
+		var err error
+		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
+		if err != nil {
+			return err
+		}
+	}
+
+	matchName := opts.matchName
+
+	options := types.ImageListOptions{
+		MatchName: matchName,
+		All:       opts.all,
+		Filters:   imageFilterArgs,
+	}
+
+	images, err := dockerCli.Client().ImageList(ctx, options)
+	if err != nil {
+		return err
+	}
+
+	f := opts.format
+	if len(f) == 0 {
+		if len(dockerCli.ImagesFormat()) > 0 && !opts.quiet {
+			f = dockerCli.ImagesFormat()
+		} else {
+			f = "table"
+		}
+	}
+
+	imagesCtx := formatter.ImageContext{
+		Context: formatter.Context{
+			Output: dockerCli.Out(),
+			Format: f,
+			Quiet:  opts.quiet,
+			Trunc:  !opts.noTrunc,
+		},
+		Digest: opts.showDigests,
+		Images: images,
+	}
+
+	imagesCtx.Write()
+
+	return nil
+}

+ 0 - 81
api/client/images.go

@@ -1,81 +0,0 @@
-package client
-
-import (
-	"golang.org/x/net/context"
-
-	"github.com/docker/docker/api/client/formatter"
-	Cli "github.com/docker/docker/cli"
-	"github.com/docker/docker/opts"
-	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/engine-api/types"
-	"github.com/docker/engine-api/types/filters"
-)
-
-// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
-//
-// Usage: docker images [OPTIONS] [REPOSITORY]
-func (cli *DockerCli) CmdImages(args ...string) error {
-	cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true)
-	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
-	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
-	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
-	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
-	format := cmd.String([]string{"-format"}, "", "Pretty-print images using a Go template")
-
-	flFilter := opts.NewListOpts(nil)
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
-	cmd.Require(flag.Max, 1)
-
-	cmd.ParseFlags(args, true)
-
-	// Consolidate all filter flags, and sanity check them early.
-	// They'll get process in the daemon/server.
-	imageFilterArgs := filters.NewArgs()
-	for _, f := range flFilter.GetAll() {
-		var err error
-		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
-		if err != nil {
-			return err
-		}
-	}
-
-	var matchName string
-	if cmd.NArg() == 1 {
-		matchName = cmd.Arg(0)
-	}
-
-	options := types.ImageListOptions{
-		MatchName: matchName,
-		All:       *all,
-		Filters:   imageFilterArgs,
-	}
-
-	images, err := cli.client.ImageList(context.Background(), options)
-	if err != nil {
-		return err
-	}
-
-	f := *format
-	if len(f) == 0 {
-		if len(cli.ImagesFormat()) > 0 && !*quiet {
-			f = cli.ImagesFormat()
-		} else {
-			f = "table"
-		}
-	}
-
-	imagesCtx := formatter.ImageContext{
-		Context: formatter.Context{
-			Output: cli.out,
-			Format: f,
-			Quiet:  *quiet,
-			Trunc:  !*noTrunc,
-		},
-		Digest: *showDigests,
-		Images: images,
-	}
-
-	imagesCtx.Write()
-
-	return nil
-}

+ 1 - 0
cli/cobraadaptor/adaptor.go

@@ -51,6 +51,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
 		container.NewUnpauseCommand(dockerCli),
 		container.NewWaitCommand(dockerCli),
 		image.NewHistoryCommand(dockerCli),
+		image.NewImagesCommand(dockerCli),
 		image.NewRemoveCommand(dockerCli),
 		image.NewSearchCommand(dockerCli),
 		image.NewImportCommand(dockerCli),

+ 17 - 0
cli/required.go

@@ -43,6 +43,23 @@ func RequiresMinArgs(min int) cobra.PositionalArgs {
 	}
 }
 
+// RequiresMaxArgs returns an error if there is not at most max args
+func RequiresMaxArgs(max int) cobra.PositionalArgs {
+	return func(cmd *cobra.Command, args []string) error {
+		if len(args) <= max {
+			return nil
+		}
+		return fmt.Errorf(
+			"\"%s\" requires at most %d argument(s).\nSee '%s --help'.\n\nUsage:  %s\n\n%s",
+			cmd.CommandPath(),
+			max,
+			cmd.CommandPath(),
+			cmd.UseLine(),
+			cmd.Short,
+		)
+	}
+}
+
 // RequiresMinMaxArgs returns an error if there is not at least min args and at most max args
 func RequiresMinMaxArgs(min int, max int) cobra.PositionalArgs {
 	return func(cmd *cobra.Command, args []string) error {

+ 0 - 1
cli/usage.go

@@ -13,7 +13,6 @@ var DockerCommandUsage = []Command{
 	{"cp", "Copy files/folders between a container and the local filesystem"},
 	{"events", "Get real time events from the server"},
 	{"exec", "Run a command in a running container"},
-	{"images", "List images"},
 	{"info", "Display system-wide information"},
 	{"inspect", "Return low-level information on a container or image"},
 	{"load", "Load an image from a tar archive or STDIN"},