mirror of https://github.com/docker/docs.git
				
				
				
			Use spf13/cobra for docker rmi
Moves image command rmi to `api/client/image/remove.go` and use cobra :) Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
		
							parent
							
								
									b259558336
								
							
						
					
					
						commit
						60e48bd6bd
					
				|  | @ -35,7 +35,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { | |||
| 		"rename":             cli.CmdRename, | ||||
| 		"restart":            cli.CmdRestart, | ||||
| 		"rm":                 cli.CmdRm, | ||||
| 		"rmi":                cli.CmdRmi, | ||||
| 		"save":               cli.CmdSave, | ||||
| 		"start":              cli.CmdStart, | ||||
| 		"stats":              cli.CmdStats, | ||||
|  |  | |||
|  | @ -0,0 +1,70 @@ | |||
| package image | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"golang.org/x/net/context" | ||||
| 
 | ||||
| 	"github.com/docker/docker/api/client" | ||||
| 	"github.com/docker/docker/cli" | ||||
| 	"github.com/docker/engine-api/types" | ||||
| 	"github.com/spf13/cobra" | ||||
| ) | ||||
| 
 | ||||
| type removeOptions struct { | ||||
| 	force   bool | ||||
| 	noPrune bool | ||||
| } | ||||
| 
 | ||||
| // NewRemoveCommand create a new `docker remove` command
 | ||||
| func NewRemoveCommand(dockerCli *client.DockerCli) *cobra.Command { | ||||
| 	var opts removeOptions | ||||
| 
 | ||||
| 	cmd := &cobra.Command{ | ||||
| 		Use:   "rmi [OPTIONS] IMAGE [IMAGE...]", | ||||
| 		Short: "Remove one or more images", | ||||
| 		Args:  cli.RequiresMinArgs(1), | ||||
| 		RunE: func(cmd *cobra.Command, args []string) error { | ||||
| 			return runRemove(dockerCli, opts, args) | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	flags := cmd.Flags() | ||||
| 
 | ||||
| 	flags.BoolVarP(&opts.force, "force", "f", false, "Force removal of the image") | ||||
| 	flags.BoolVar(&opts.noPrune, "no-prune", false, "Do not delete untagged parents") | ||||
| 
 | ||||
| 	return cmd | ||||
| } | ||||
| 
 | ||||
| func runRemove(dockerCli *client.DockerCli, opts removeOptions, images []string) error { | ||||
| 	client := dockerCli.Client() | ||||
| 	ctx := context.Background() | ||||
| 
 | ||||
| 	options := types.ImageRemoveOptions{ | ||||
| 		Force:         opts.force, | ||||
| 		PruneChildren: !opts.noPrune, | ||||
| 	} | ||||
| 
 | ||||
| 	var errs []string | ||||
| 	for _, image := range images { | ||||
| 		dels, err := client.ImageRemove(ctx, image, options) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err.Error()) | ||||
| 		} else { | ||||
| 			for _, del := range dels { | ||||
| 				if del.Deleted != "" { | ||||
| 					fmt.Fprintf(dockerCli.Out(), "Deleted: %s\n", del.Deleted) | ||||
| 				} else { | ||||
| 					fmt.Fprintf(dockerCli.Out(), "Untagged: %s\n", del.Untagged) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if len(errs) > 0 { | ||||
| 		return fmt.Errorf("%s", strings.Join(errs, "\n")) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | @ -1,60 +0,0 @@ | |||
| package client | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"golang.org/x/net/context" | ||||
| 
 | ||||
| 	Cli "github.com/docker/docker/cli" | ||||
| 	flag "github.com/docker/docker/pkg/mflag" | ||||
| 	"github.com/docker/engine-api/types" | ||||
| ) | ||||
| 
 | ||||
| // CmdRmi removes all images with the specified name(s).
 | ||||
| //
 | ||||
| // Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
 | ||||
| func (cli *DockerCli) CmdRmi(args ...string) error { | ||||
| 	cmd := Cli.Subcmd("rmi", []string{"IMAGE [IMAGE...]"}, Cli.DockerCommands["rmi"].Description, true) | ||||
| 	force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") | ||||
| 	noprune := cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") | ||||
| 	cmd.Require(flag.Min, 1) | ||||
| 
 | ||||
| 	cmd.ParseFlags(args, true) | ||||
| 
 | ||||
| 	v := url.Values{} | ||||
| 	if *force { | ||||
| 		v.Set("force", "1") | ||||
| 	} | ||||
| 	if *noprune { | ||||
| 		v.Set("noprune", "1") | ||||
| 	} | ||||
| 
 | ||||
| 	ctx := context.Background() | ||||
| 
 | ||||
| 	var errs []string | ||||
| 	for _, image := range cmd.Args() { | ||||
| 		options := types.ImageRemoveOptions{ | ||||
| 			Force:         *force, | ||||
| 			PruneChildren: !*noprune, | ||||
| 		} | ||||
| 
 | ||||
| 		dels, err := cli.client.ImageRemove(ctx, image, options) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err.Error()) | ||||
| 		} else { | ||||
| 			for _, del := range dels { | ||||
| 				if del.Deleted != "" { | ||||
| 					fmt.Fprintf(cli.out, "Deleted: %s\n", del.Deleted) | ||||
| 				} else { | ||||
| 					fmt.Fprintf(cli.out, "Untagged: %s\n", del.Untagged) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if len(errs) > 0 { | ||||
| 		return fmt.Errorf("%s", strings.Join(errs, "\n")) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | @ -37,6 +37,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { | |||
| 		container.NewExportCommand(dockerCli), | ||||
| 		container.NewRunCommand(dockerCli), | ||||
| 		container.NewStopCommand(dockerCli), | ||||
| 		image.NewRemoveCommand(dockerCli), | ||||
| 		image.NewSearchCommand(dockerCli), | ||||
| 		volume.NewVolumeCommand(dockerCli), | ||||
| 	) | ||||
|  |  | |||
|  | @ -34,7 +34,6 @@ var DockerCommandUsage = []Command{ | |||
| 	{"rename", "Rename a container"}, | ||||
| 	{"restart", "Restart a container"}, | ||||
| 	{"rm", "Remove one or more containers"}, | ||||
| 	{"rmi", "Remove one or more images"}, | ||||
| 	{"save", "Save one or more images to a tar archive"}, | ||||
| 	{"start", "Start one or more stopped containers"}, | ||||
| 	{"stats", "Display a live stream of container(s) resource usage statistics"}, | ||||
|  |  | |||
|  | @ -226,20 +226,13 @@ func (s *DockerSuite) TestRmiForceWithMultipleRepositories(c *check.C) { | |||
| } | ||||
| 
 | ||||
| func (s *DockerSuite) TestRmiBlank(c *check.C) { | ||||
| 	// try to delete a blank image name
 | ||||
| 	out, _, err := dockerCmdWithError("rmi", "") | ||||
| 	// Should have failed to delete '' image
 | ||||
| 	out, _, err := dockerCmdWithError("rmi", " ") | ||||
| 	// Should have failed to delete ' ' image
 | ||||
| 	c.Assert(err, checker.NotNil) | ||||
| 	// Wrong error message generated
 | ||||
| 	c.Assert(out, checker.Not(checker.Contains), "no such id", check.Commentf("out: %s", out)) | ||||
| 	// Expected error message not generated
 | ||||
| 	c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out)) | ||||
| 
 | ||||
| 	out, _, err = dockerCmdWithError("rmi", " ") | ||||
| 	// Should have failed to delete ' ' image
 | ||||
| 	c.Assert(err, checker.NotNil) | ||||
| 	// Expected error message not generated
 | ||||
| 	c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out)) | ||||
| } | ||||
| 
 | ||||
| func (s *DockerSuite) TestRmiContainerImageNotFound(c *check.C) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue