diff --git a/cobra.go b/cobra.go index 836196d76e..324c0d7b2d 100644 --- a/cobra.go +++ b/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 +} -{{ .Short | trim }}{{if gt .Aliases 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: + +{{- 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}} -Commands:{{range .Commands}}{{if .IsAvailableCommand}} - {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasSubCommands }} +{{- end}} +{{- if hasManagementSubCommands . }} -Run '{{.CommandPath}} COMMAND --help' for more information on a command.{{end}} +Management Commands: + +{{- range managementSubCommands . }} + {{rpad .Name .NamePadding }} {{.Short}} +{{- end}} + +{{- end}} +{{- if hasSubCommands .}} + +Commands: + +{{- range operationSubCommands . }} + {{rpad .Name .NamePadding }} {{.Short}} +{{- end}} +{{- end}} + +{{- if .HasSubCommands }} + +Run '{{.CommandPath}} COMMAND --help' for more information on a command. +{{- end}} ` var helpTemplate = ` diff --git a/command/checkpoint/cmd_experimental.go b/command/checkpoint/cmd_experimental.go index 7939678cd5..c05d3ded40 100644 --- a/command/checkpoint/cmd_experimental.go +++ b/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()) diff --git a/command/commands/commands.go b/command/commands/commands.go index cace1b152c..d618233997 100644 --- a/command/commands/commands.go +++ b/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" @@ -75,6 +77,9 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.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{} diff --git a/command/container/cmd.go b/command/container/cmd.go index 6d71e53eba..da9ea6d41d 100644 --- a/command/container/cmd.go +++ b/command/container/cmd.go @@ -13,7 +13,7 @@ import ( func NewContainerCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "container", - Short: "Manage Docker containers", + Short: "Manage containers", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) diff --git a/command/image/cmd.go b/command/image/cmd.go index 4a7d2b3fd9..f60ffeeb8f 100644 --- a/command/image/cmd.go +++ b/command/image/cmd.go @@ -13,7 +13,7 @@ import ( func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command { cmd := &cobra.Command{ Use: "image", - Short: "Manage Docker images", + Short: "Manage images", Args: cli.NoArgs, Run: func(cmd *cobra.Command, args []string) { fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) diff --git a/command/network/cmd.go b/command/network/cmd.go index a7c9b3fce3..b33f98cd30 100644 --- a/command/network/cmd.go +++ b/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()) diff --git a/command/node/cmd.go b/command/node/cmd.go index 6aa4dfcb18..c7d0cf8181 100644 --- a/command/node/cmd.go +++ b/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()) diff --git a/command/plugin/cmd_experimental.go b/command/plugin/cmd_experimental.go index cc779143fa..33c1c93acb 100644 --- a/command/plugin/cmd_experimental.go +++ b/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()) diff --git a/command/service/cmd.go b/command/service/cmd.go index 282ce2b4b9..9f342e1342 100644 --- a/command/service/cmd.go +++ b/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()) diff --git a/command/stack/cmd.go b/command/stack/cmd.go index 22f076c4d0..22a2334419 100644 --- a/command/stack/cmd.go +++ b/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()) diff --git a/command/swarm/cmd.go b/command/swarm/cmd.go index db2b6a2530..9f9df53950 100644 --- a/command/swarm/cmd.go +++ b/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()) diff --git a/command/volume/cmd.go b/command/volume/cmd.go index 090a006439..caf6afcaa3 100644 --- a/command/volume/cmd.go +++ b/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) {