Browse Source

Merge pull request #26025 from dnephin/cli-new-command-structure

Restructure CLI Commands
Sebastiaan van Stijn 8 years ago
parent
commit
ad9ceff3b3

+ 71 - 8
cli/cobra.go

@@ -9,6 +9,11 @@ import (
 // SetupRootCommand sets default usage, help, and error handling for the
 // root command.
 func SetupRootCommand(rootCmd *cobra.Command) {
+	cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
+	cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
+	cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
+	cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
+
 	rootCmd.SetUsageTemplate(usageTemplate)
 	rootCmd.SetHelpTemplate(helpTemplate)
 	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
@@ -34,23 +39,81 @@ func FlagErrorFunc(cmd *cobra.Command, err error) error {
 	}
 }
 
-var usageTemplate = `Usage:	{{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}}
+func hasSubCommands(cmd *cobra.Command) bool {
+	return len(operationSubCommands(cmd)) > 0
+}
+
+func hasManagementSubCommands(cmd *cobra.Command) bool {
+	return len(managementSubCommands(cmd)) > 0
+}
+
+func operationSubCommands(cmd *cobra.Command) []*cobra.Command {
+	cmds := []*cobra.Command{}
+	for _, sub := range cmd.Commands() {
+		if sub.IsAvailableCommand() && !sub.HasSubCommands() {
+			cmds = append(cmds, sub)
+		}
+	}
+	return cmds
+}
+
+func managementSubCommands(cmd *cobra.Command) []*cobra.Command {
+	cmds := []*cobra.Command{}
+	for _, sub := range cmd.Commands() {
+		if sub.IsAvailableCommand() && sub.HasSubCommands() {
+			cmds = append(cmds, sub)
+		}
+	}
+	return cmds
+}
+
+var usageTemplate = `Usage:
 
-{{ .Short | trim }}{{if gt .Aliases 0}}
+{{- if not .HasSubCommands}}	{{.UseLine}}{{end}}
+{{- if .HasSubCommands}}	{{ .CommandPath}} COMMAND{{end}}
+
+{{ .Short | trim }}
+
+{{- if gt .Aliases 0}}
 
 Aliases:
-  {{.NameAndAliases}}{{end}}{{if .HasExample}}
+  {{.NameAndAliases}}
+
+{{- end}}
+{{- if .HasExample}}
 
 Examples:
-{{ .Example }}{{end}}{{if .HasFlags}}
+{{ .Example }}
+
+{{- end}}
+{{- if .HasFlags}}
 
 Options:
-{{.Flags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasAvailableSubCommands}}
+{{.Flags.FlagUsages | trimRightSpace}}
+
+{{- end}}
+{{- if hasManagementSubCommands . }}
+
+Management Commands:
+
+{{- range managementSubCommands . }}
+  {{rpad .Name .NamePadding }} {{.Short}}
+{{- end}}
+
+{{- end}}
+{{- if hasSubCommands .}}
+
+Commands:
+
+{{- range operationSubCommands . }}
+  {{rpad .Name .NamePadding }} {{.Short}}
+{{- end}}
+{{- end}}
 
-Commands:{{range .Commands}}{{if .IsAvailableCommand}}
-  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasSubCommands }}
+{{- if .HasSubCommands }}
 
-Run '{{.CommandPath}} COMMAND --help' for more information on a command.{{end}}
+Run '{{.CommandPath}} COMMAND --help' for more information on a command.
+{{- end}}
 `
 
 var helpTemplate = `

+ 1 - 1
cli/command/checkpoint/cmd_experimental.go

@@ -15,7 +15,7 @@ import (
 func NewCheckpointCommand(rootCmd *cobra.Command, dockerCli *command.DockerCli) {
 	cmd := &cobra.Command{
 		Use:   "checkpoint",
-		Short: "Manage Container Checkpoints",
+		Short: "Manage checkpoints",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 47 - 33
cli/command/commands/commands.go

@@ -1,6 +1,8 @@
 package commands
 
 import (
+	"os"
+
 	"github.com/docker/docker/cli/command"
 	"github.com/docker/docker/cli/command/checkpoint"
 	"github.com/docker/docker/cli/command/container"
@@ -25,49 +27,61 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
 		stack.NewStackCommand(dockerCli),
 		stack.NewTopLevelDeployCommand(dockerCli),
 		swarm.NewSwarmCommand(dockerCli),
-		container.NewAttachCommand(dockerCli),
-		container.NewCommitCommand(dockerCli),
-		container.NewCopyCommand(dockerCli),
-		container.NewCreateCommand(dockerCli),
-		container.NewDiffCommand(dockerCli),
-		container.NewExecCommand(dockerCli),
-		container.NewExportCommand(dockerCli),
-		container.NewKillCommand(dockerCli),
-		container.NewLogsCommand(dockerCli),
-		container.NewPauseCommand(dockerCli),
-		container.NewPortCommand(dockerCli),
-		container.NewPsCommand(dockerCli),
-		container.NewRenameCommand(dockerCli),
-		container.NewRestartCommand(dockerCli),
-		container.NewRmCommand(dockerCli),
+		container.NewContainerCommand(dockerCli),
+		image.NewImageCommand(dockerCli),
 		container.NewRunCommand(dockerCli),
-		container.NewStartCommand(dockerCli),
-		container.NewStatsCommand(dockerCli),
-		container.NewStopCommand(dockerCli),
-		container.NewTopCommand(dockerCli),
-		container.NewUnpauseCommand(dockerCli),
-		container.NewUpdateCommand(dockerCli),
-		container.NewWaitCommand(dockerCli),
 		image.NewBuildCommand(dockerCli),
-		image.NewHistoryCommand(dockerCli),
-		image.NewImagesCommand(dockerCli),
-		image.NewLoadCommand(dockerCli),
-		image.NewRemoveCommand(dockerCli),
-		image.NewSaveCommand(dockerCli),
-		image.NewPullCommand(dockerCli),
-		image.NewPushCommand(dockerCli),
-		image.NewSearchCommand(dockerCli),
-		image.NewImportCommand(dockerCli),
-		image.NewTagCommand(dockerCli),
 		network.NewNetworkCommand(dockerCli),
 		system.NewEventsCommand(dockerCli),
-		system.NewInspectCommand(dockerCli),
 		registry.NewLoginCommand(dockerCli),
 		registry.NewLogoutCommand(dockerCli),
+		registry.NewSearchCommand(dockerCli),
 		system.NewVersionCommand(dockerCli),
 		volume.NewVolumeCommand(dockerCli),
 		system.NewInfoCommand(dockerCli),
+		hide(container.NewAttachCommand(dockerCli)),
+		hide(container.NewCommitCommand(dockerCli)),
+		hide(container.NewCopyCommand(dockerCli)),
+		hide(container.NewCreateCommand(dockerCli)),
+		hide(container.NewDiffCommand(dockerCli)),
+		hide(container.NewExecCommand(dockerCli)),
+		hide(container.NewExportCommand(dockerCli)),
+		hide(container.NewKillCommand(dockerCli)),
+		hide(container.NewLogsCommand(dockerCli)),
+		hide(container.NewPauseCommand(dockerCli)),
+		hide(container.NewPortCommand(dockerCli)),
+		hide(container.NewPsCommand(dockerCli)),
+		hide(container.NewRenameCommand(dockerCli)),
+		hide(container.NewRestartCommand(dockerCli)),
+		hide(container.NewRmCommand(dockerCli)),
+		hide(container.NewStartCommand(dockerCli)),
+		hide(container.NewStatsCommand(dockerCli)),
+		hide(container.NewStopCommand(dockerCli)),
+		hide(container.NewTopCommand(dockerCli)),
+		hide(container.NewUnpauseCommand(dockerCli)),
+		hide(container.NewUpdateCommand(dockerCli)),
+		hide(container.NewWaitCommand(dockerCli)),
+		hide(image.NewHistoryCommand(dockerCli)),
+		hide(image.NewImagesCommand(dockerCli)),
+		hide(image.NewImportCommand(dockerCli)),
+		hide(image.NewLoadCommand(dockerCli)),
+		hide(image.NewPullCommand(dockerCli)),
+		hide(image.NewPushCommand(dockerCli)),
+		hide(image.NewRemoveCommand(dockerCli)),
+		hide(image.NewSaveCommand(dockerCli)),
+		hide(image.NewTagCommand(dockerCli)),
+		hide(system.NewInspectCommand(dockerCli)),
 	)
 	checkpoint.NewCheckpointCommand(cmd, dockerCli)
 	plugin.NewPluginCommand(cmd, dockerCli)
 }
+
+func hide(cmd *cobra.Command) *cobra.Command {
+	if os.Getenv("DOCKER_HIDE_LEGACY_COMMANDS") == "" {
+		return cmd
+	}
+	cmdCopy := *cmd
+	cmdCopy.Hidden = true
+	cmdCopy.Aliases = []string{}
+	return &cmdCopy
+}

+ 49 - 0
cli/command/container/cmd.go

@@ -0,0 +1,49 @@
+package container
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	"github.com/docker/docker/cli"
+	"github.com/docker/docker/cli/command"
+)
+
+// NewContainerCommand returns a cobra command for `container` subcommands
+func NewContainerCommand(dockerCli *command.DockerCli) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "container",
+		Short: "Manage containers",
+		Args:  cli.NoArgs,
+		Run: func(cmd *cobra.Command, args []string) {
+			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
+		},
+	}
+	cmd.AddCommand(
+		NewAttachCommand(dockerCli),
+		NewCommitCommand(dockerCli),
+		NewCopyCommand(dockerCli),
+		NewCreateCommand(dockerCli),
+		NewDiffCommand(dockerCli),
+		NewExecCommand(dockerCli),
+		NewExportCommand(dockerCli),
+		NewKillCommand(dockerCli),
+		NewLogsCommand(dockerCli),
+		NewPauseCommand(dockerCli),
+		NewPortCommand(dockerCli),
+		NewRenameCommand(dockerCli),
+		NewRestartCommand(dockerCli),
+		NewRmCommand(dockerCli),
+		NewRunCommand(dockerCli),
+		NewStartCommand(dockerCli),
+		NewStatsCommand(dockerCli),
+		NewStopCommand(dockerCli),
+		NewTopCommand(dockerCli),
+		NewUnpauseCommand(dockerCli),
+		NewUpdateCommand(dockerCli),
+		NewWaitCommand(dockerCli),
+		newListCommand(dockerCli),
+		newInspectCommand(dockerCli),
+	)
+	return cmd
+}

+ 47 - 0
cli/command/container/inspect.go

@@ -0,0 +1,47 @@
+package container
+
+import (
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/cli"
+	"github.com/docker/docker/cli/command"
+	"github.com/docker/docker/cli/command/inspect"
+	"github.com/spf13/cobra"
+)
+
+type inspectOptions struct {
+	format string
+	size   bool
+	refs   []string
+}
+
+// newInspectCommand creates a new cobra.Command for `docker container inspect`
+func newInspectCommand(dockerCli *command.DockerCli) *cobra.Command {
+	var opts inspectOptions
+
+	cmd := &cobra.Command{
+		Use:   "inspect [OPTIONS] CONTAINER [CONTAINER...]",
+		Short: "Display detailed information on one or more containers",
+		Args:  cli.RequiresMinArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			opts.refs = args
+			return runInspect(dockerCli, opts)
+		},
+	}
+
+	flags := cmd.Flags()
+	flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given go template")
+	flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes")
+
+	return cmd
+}
+
+func runInspect(dockerCli *command.DockerCli, opts inspectOptions) error {
+	client := dockerCli.Client()
+	ctx := context.Background()
+
+	getRefFunc := func(ref string) (interface{}, []byte, error) {
+		return client.ContainerInspectWithRaw(ctx, ref, opts.size)
+	}
+	return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRefFunc)
+}

+ 7 - 0
cli/command/container/ps.go → cli/command/container/list.go

@@ -52,6 +52,13 @@ func NewPsCommand(dockerCli *command.DockerCli) *cobra.Command {
 	return cmd
 }
 
+func newListCommand(dockerCli *command.DockerCli) *cobra.Command {
+	cmd := *NewPsCommand(dockerCli)
+	cmd.Aliases = []string{"ps", "list"}
+	cmd.Use = "ls [OPTIONS]"
+	return &cmd
+}
+
 type preProcessor struct {
 	types.Container
 	opts *types.ContainerListOptions

+ 36 - 0
cli/command/image/cmd.go

@@ -0,0 +1,36 @@
+package image
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+
+	"github.com/docker/docker/cli"
+	"github.com/docker/docker/cli/command"
+)
+
+// NewImageCommand returns a cobra command for `image` subcommands
+func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "image",
+		Short: "Manage images",
+		Args:  cli.NoArgs,
+		Run: func(cmd *cobra.Command, args []string) {
+			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
+		},
+	}
+	cmd.AddCommand(
+		NewBuildCommand(dockerCli),
+		NewHistoryCommand(dockerCli),
+		NewImportCommand(dockerCli),
+		NewLoadCommand(dockerCli),
+		NewPullCommand(dockerCli),
+		NewPushCommand(dockerCli),
+		NewSaveCommand(dockerCli),
+		NewTagCommand(dockerCli),
+		newListCommand(dockerCli),
+		newRemoveCommand(dockerCli),
+		newInspectCommand(dockerCli),
+	)
+	return cmd
+}

+ 44 - 0
cli/command/image/inspect.go

@@ -0,0 +1,44 @@
+package image
+
+import (
+	"golang.org/x/net/context"
+
+	"github.com/docker/docker/cli"
+	"github.com/docker/docker/cli/command"
+	"github.com/docker/docker/cli/command/inspect"
+	"github.com/spf13/cobra"
+)
+
+type inspectOptions struct {
+	format string
+	refs   []string
+}
+
+// newInspectCommand creates a new cobra.Command for `docker image inspect`
+func newInspectCommand(dockerCli *command.DockerCli) *cobra.Command {
+	var opts inspectOptions
+
+	cmd := &cobra.Command{
+		Use:   "inspect [OPTIONS] IMAGE [IMAGE...]",
+		Short: "Display detailed information on one or more images",
+		Args:  cli.RequiresMinArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			opts.refs = args
+			return runInspect(dockerCli, opts)
+		},
+	}
+
+	flags := cmd.Flags()
+	flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given go template")
+	return cmd
+}
+
+func runInspect(dockerCli *command.DockerCli, opts inspectOptions) error {
+	client := dockerCli.Client()
+	ctx := context.Background()
+
+	getRefFunc := func(ref string) (interface{}, []byte, error) {
+		return client.ImageInspectWithRaw(ctx, ref)
+	}
+	return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRefFunc)
+}

+ 7 - 0
cli/command/image/images.go → cli/command/image/list.go

@@ -50,6 +50,13 @@ func NewImagesCommand(dockerCli *command.DockerCli) *cobra.Command {
 	return cmd
 }
 
+func newListCommand(dockerCli *command.DockerCli) *cobra.Command {
+	cmd := *NewImagesCommand(dockerCli)
+	cmd.Aliases = []string{"images", "list"}
+	cmd.Use = "ls [OPTIONS] [REPOSITORY[:TAG]]"
+	return &cmd
+}
+
 func runImages(dockerCli *command.DockerCli, opts imagesOptions) error {
 	ctx := context.Background()
 

+ 7 - 0
cli/command/image/remove.go

@@ -38,6 +38,13 @@ func NewRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
 	return cmd
 }
 
+func newRemoveCommand(dockerCli *command.DockerCli) *cobra.Command {
+	cmd := *NewRemoveCommand(dockerCli)
+	cmd.Aliases = []string{"rmi", "remove"}
+	cmd.Use = "rm [OPTIONS] IMAGE [IMAGE...]"
+	return &cmd
+}
+
 func runRemove(dockerCli *command.DockerCli, opts removeOptions, images []string) error {
 	client := dockerCli.Client()
 	ctx := context.Background()

+ 1 - 1
cli/command/network/cmd.go

@@ -13,7 +13,7 @@ import (
 func NewNetworkCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "network",
-		Short: "Manage Docker networks",
+		Short: "Manage networks",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 1 - 1
cli/command/node/cmd.go

@@ -14,7 +14,7 @@ import (
 func NewNodeCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "node",
-		Short: "Manage Docker Swarm nodes",
+		Short: "Manage Swarm nodes",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 1 - 1
cli/command/plugin/cmd_experimental.go

@@ -14,7 +14,7 @@ import (
 func NewPluginCommand(rootCmd *cobra.Command, dockerCli *command.DockerCli) {
 	cmd := &cobra.Command{
 		Use:   "plugin",
-		Short: "Manage Docker plugins",
+		Short: "Manage plugins",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 1 - 1
cli/command/image/search.go → cli/command/registry/search.go

@@ -1,4 +1,4 @@
-package image
+package registry
 
 import (
 	"fmt"

+ 1 - 1
cli/command/service/cmd.go

@@ -13,7 +13,7 @@ import (
 func NewServiceCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "service",
-		Short: "Manage Docker services",
+		Short: "Manage services",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 3 - 3
cli/command/stack/cmd.go

@@ -14,7 +14,7 @@ import (
 func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "stack",
-		Short: "Manage Docker stacks",
+		Short: "Manage stacks",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
@@ -32,8 +32,8 @@ func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command {
 
 // NewTopLevelDeployCommand returns a command for `docker deploy`
 func NewTopLevelDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
-	cmd := newDeployCommand(dockerCli)
+	cmd := *newDeployCommand(dockerCli)
 	// Remove the aliases at the top level
 	cmd.Aliases = []string{}
-	return cmd
+	return &cmd
 }

+ 1 - 1
cli/command/swarm/cmd.go

@@ -13,7 +13,7 @@ import (
 func NewSwarmCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "swarm",
-		Short: "Manage Docker Swarm",
+		Short: "Manage Swarm",
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {
 			fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())

+ 1 - 1
cli/command/volume/cmd.go

@@ -13,7 +13,7 @@ import (
 func NewVolumeCommand(dockerCli *command.DockerCli) *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "volume COMMAND",
-		Short: "Manage Docker volumes",
+		Short: "Manage volumes",
 		Long:  volumeDescription,
 		Args:  cli.NoArgs,
 		Run: func(cmd *cobra.Command, args []string) {