Merge pull request #3506 from thaJeztah/group_swarm_commands

re-organize --help output
This commit is contained in:
Sebastiaan van Stijn 2022-04-08 18:10:37 +02:00 committed by GitHub
commit b68db383d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 160 additions and 65 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
pluginmanager "github.com/docker/cli/cli-plugins/manager" pluginmanager "github.com/docker/cli/cli-plugins/manager"
@ -12,6 +13,7 @@ import (
cliflags "github.com/docker/cli/cli/flags" cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/docker/pkg/homedir" "github.com/docker/docker/pkg/homedir"
"github.com/docker/docker/registry" "github.com/docker/docker/registry"
"github.com/fvbommel/sortorder"
"github.com/moby/term" "github.com/moby/term"
"github.com/morikuni/aec" "github.com/morikuni/aec"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -30,10 +32,14 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *p
cobra.AddTemplateFunc("add", func(a, b int) int { return a + b }) cobra.AddTemplateFunc("add", func(a, b int) int { return a + b })
cobra.AddTemplateFunc("hasSubCommands", hasSubCommands) cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
cobra.AddTemplateFunc("hasTopCommands", hasTopCommands)
cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands) cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
cobra.AddTemplateFunc("hasSwarmSubCommands", hasSwarmSubCommands)
cobra.AddTemplateFunc("hasInvalidPlugins", hasInvalidPlugins) cobra.AddTemplateFunc("hasInvalidPlugins", hasInvalidPlugins)
cobra.AddTemplateFunc("topCommands", topCommands)
cobra.AddTemplateFunc("operationSubCommands", operationSubCommands) cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
cobra.AddTemplateFunc("managementSubCommands", managementSubCommands) cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
cobra.AddTemplateFunc("orchestratorSubCommands", orchestratorSubCommands)
cobra.AddTemplateFunc("invalidPlugins", invalidPlugins) cobra.AddTemplateFunc("invalidPlugins", invalidPlugins)
cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages) cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages)
cobra.AddTemplateFunc("vendorAndVersion", vendorAndVersion) cobra.AddTemplateFunc("vendorAndVersion", vendorAndVersion)
@ -240,16 +246,51 @@ func hasManagementSubCommands(cmd *cobra.Command) bool {
return len(managementSubCommands(cmd)) > 0 return len(managementSubCommands(cmd)) > 0
} }
func hasSwarmSubCommands(cmd *cobra.Command) bool {
return len(orchestratorSubCommands(cmd)) > 0
}
func hasInvalidPlugins(cmd *cobra.Command) bool { func hasInvalidPlugins(cmd *cobra.Command) bool {
return len(invalidPlugins(cmd)) > 0 return len(invalidPlugins(cmd)) > 0
} }
func hasTopCommands(cmd *cobra.Command) bool {
return len(topCommands(cmd)) > 0
}
func topCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{}
if cmd.Parent() != nil {
// for now, only use top-commands for the root-command, and skip
// for sub-commands
return cmds
}
for _, sub := range cmd.Commands() {
if isPlugin(sub) || !sub.IsAvailableCommand() {
continue
}
if _, ok := sub.Annotations["category-top"]; ok {
cmds = append(cmds, sub)
}
}
sort.SliceStable(cmds, func(i, j int) bool {
return sortorder.NaturalLess(cmds[i].Annotations["category-top"], cmds[j].Annotations["category-top"])
})
return cmds
}
func operationSubCommands(cmd *cobra.Command) []*cobra.Command { func operationSubCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{} cmds := []*cobra.Command{}
for _, sub := range cmd.Commands() { for _, sub := range cmd.Commands() {
if isPlugin(sub) { if isPlugin(sub) {
continue continue
} }
if _, ok := sub.Annotations["category-top"]; ok {
if cmd.Parent() == nil {
// for now, only use top-commands for the root-command
continue
}
}
if sub.IsAvailableCommand() && !sub.HasSubCommands() { if sub.IsAvailableCommand() && !sub.HasSubCommands() {
cmds = append(cmds, sub) cmds = append(cmds, sub)
} }
@ -285,6 +326,27 @@ func vendorAndVersion(cmd *cobra.Command) string {
} }
func managementSubCommands(cmd *cobra.Command) []*cobra.Command { func managementSubCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{}
for _, sub := range allManagementSubCommands(cmd) {
if _, ok := sub.Annotations["swarm"]; ok {
continue
}
cmds = append(cmds, sub)
}
return cmds
}
func orchestratorSubCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{}
for _, sub := range allManagementSubCommands(cmd) {
if _, ok := sub.Annotations["swarm"]; ok {
cmds = append(cmds, sub)
}
}
return cmds
}
func allManagementSubCommands(cmd *cobra.Command) []*cobra.Command {
cmds := []*cobra.Command{} cmds := []*cobra.Command{}
for _, sub := range cmd.Commands() { for _, sub := range cmd.Commands() {
if isPlugin(sub) { if isPlugin(sub) {
@ -345,11 +407,20 @@ Examples:
{{ .Example }} {{ .Example }}
{{- end}} {{- end}}
{{- if .HasParent}}
{{- if .HasAvailableFlags}} {{- if .HasAvailableFlags}}
Options: Options:
{{ wrappedFlagUsages . | trimRightSpace}} {{ wrappedFlagUsages . | trimRightSpace}}
{{- end}}
{{- end}}
{{- if hasTopCommands .}}
Common Commands:
{{- range topCommands .}}
{{rpad (decoratedName .) (add .NamePadding 1)}}{{.Short}}
{{- end}}
{{- end}} {{- end}}
{{- if hasManagementSubCommands . }} {{- if hasManagementSubCommands . }}
@ -359,6 +430,15 @@ Management Commands:
{{rpad (decoratedName .) (add .NamePadding 1)}}{{.Short}}{{ if isPlugin .}} {{vendorAndVersion .}}{{ end}} {{rpad (decoratedName .) (add .NamePadding 1)}}{{.Short}}{{ if isPlugin .}} {{vendorAndVersion .}}{{ end}}
{{- end}} {{- end}}
{{- end}}
{{- if hasSwarmSubCommands . }}
Swarm Commands:
{{- range orchestratorSubCommands . }}
{{rpad (decoratedName .) (add .NamePadding 1)}}{{.Short}}{{ if isPlugin .}} {{vendorAndVersion .}}{{ end}}
{{- end}}
{{- end}} {{- end}}
{{- if hasSubCommands .}} {{- if hasSubCommands .}}
@ -377,6 +457,14 @@ Invalid Plugins:
{{rpad .Name .NamePadding }} {{invalidPluginReason .}} {{rpad .Name .NamePadding }} {{invalidPluginReason .}}
{{- end}} {{- end}}
{{- end}}
{{- if not .HasParent}}
{{- if .HasAvailableFlags}}
Global Options:
{{ wrappedFlagUsages . | trimRightSpace}}
{{- end}}
{{- end}} {{- end}}
{{- if .HasSubCommands }} {{- if .HasSubCommands }}

View File

@ -28,81 +28,52 @@ import (
// AddCommands adds all the commands from cli/command to the root command // AddCommands adds all the commands from cli/command to the root command
func AddCommands(cmd *cobra.Command, dockerCli command.Cli) { func AddCommands(cmd *cobra.Command, dockerCli command.Cli) {
cmd.AddCommand( cmd.AddCommand(
// checkpoint // commonly used shorthands
checkpoint.NewCheckpointCommand(dockerCli),
// config
config.NewConfigCommand(dockerCli),
// container
container.NewContainerCommand(dockerCli),
container.NewRunCommand(dockerCli), container.NewRunCommand(dockerCli),
container.NewExecCommand(dockerCli),
// image container.NewPsCommand(dockerCli),
image.NewImageCommand(dockerCli),
image.NewBuildCommand(dockerCli), image.NewBuildCommand(dockerCli),
image.NewPullCommand(dockerCli),
// builder image.NewPushCommand(dockerCli),
builder.NewBuilderCommand(dockerCli), image.NewImagesCommand(dockerCli),
// manifest
manifest.NewManifestCommand(dockerCli),
// network
network.NewNetworkCommand(dockerCli),
// node
node.NewNodeCommand(dockerCli),
// plugin
plugin.NewPluginCommand(dockerCli),
// registry
registry.NewLoginCommand(dockerCli), registry.NewLoginCommand(dockerCli),
registry.NewLogoutCommand(dockerCli), registry.NewLogoutCommand(dockerCli),
registry.NewSearchCommand(dockerCli), registry.NewSearchCommand(dockerCli),
// secret
secret.NewSecretCommand(dockerCli),
// service
service.NewServiceCommand(dockerCli),
// system
system.NewSystemCommand(dockerCli),
system.NewVersionCommand(dockerCli), system.NewVersionCommand(dockerCli),
system.NewInfoCommand(dockerCli),
// stack // management commands
stack.NewStackCommand(dockerCli), builder.NewBuilderCommand(dockerCli),
checkpoint.NewCheckpointCommand(dockerCli),
// swarm container.NewContainerCommand(dockerCli),
swarm.NewSwarmCommand(dockerCli), context.NewContextCommand(dockerCli),
image.NewImageCommand(dockerCli),
// trust manifest.NewManifestCommand(dockerCli),
network.NewNetworkCommand(dockerCli),
plugin.NewPluginCommand(dockerCli),
system.NewSystemCommand(dockerCli),
trust.NewTrustCommand(dockerCli), trust.NewTrustCommand(dockerCli),
// volume
volume.NewVolumeCommand(dockerCli), volume.NewVolumeCommand(dockerCli),
// context // orchestration (swarm) commands
context.NewContextCommand(dockerCli), config.NewConfigCommand(dockerCli),
node.NewNodeCommand(dockerCli),
secret.NewSecretCommand(dockerCli),
service.NewServiceCommand(dockerCli),
stack.NewStackCommand(dockerCli),
swarm.NewSwarmCommand(dockerCli),
// legacy commands may be hidden // legacy commands may be hidden
hide(system.NewEventsCommand(dockerCli)),
hide(system.NewInfoCommand(dockerCli)),
hide(system.NewInspectCommand(dockerCli)),
hide(container.NewAttachCommand(dockerCli)), hide(container.NewAttachCommand(dockerCli)),
hide(container.NewCommitCommand(dockerCli)), hide(container.NewCommitCommand(dockerCli)),
hide(container.NewCopyCommand(dockerCli)), hide(container.NewCopyCommand(dockerCli)),
hide(container.NewCreateCommand(dockerCli)), hide(container.NewCreateCommand(dockerCli)),
hide(container.NewDiffCommand(dockerCli)), hide(container.NewDiffCommand(dockerCli)),
hide(container.NewExecCommand(dockerCli)),
hide(container.NewExportCommand(dockerCli)), hide(container.NewExportCommand(dockerCli)),
hide(container.NewKillCommand(dockerCli)), hide(container.NewKillCommand(dockerCli)),
hide(container.NewLogsCommand(dockerCli)), hide(container.NewLogsCommand(dockerCli)),
hide(container.NewPauseCommand(dockerCli)), hide(container.NewPauseCommand(dockerCli)),
hide(container.NewPortCommand(dockerCli)), hide(container.NewPortCommand(dockerCli)),
hide(container.NewPsCommand(dockerCli)),
hide(container.NewRenameCommand(dockerCli)), hide(container.NewRenameCommand(dockerCli)),
hide(container.NewRestartCommand(dockerCli)), hide(container.NewRestartCommand(dockerCli)),
hide(container.NewRmCommand(dockerCli)), hide(container.NewRmCommand(dockerCli)),
@ -114,14 +85,13 @@ func AddCommands(cmd *cobra.Command, dockerCli command.Cli) {
hide(container.NewUpdateCommand(dockerCli)), hide(container.NewUpdateCommand(dockerCli)),
hide(container.NewWaitCommand(dockerCli)), hide(container.NewWaitCommand(dockerCli)),
hide(image.NewHistoryCommand(dockerCli)), hide(image.NewHistoryCommand(dockerCli)),
hide(image.NewImagesCommand(dockerCli)),
hide(image.NewImportCommand(dockerCli)), hide(image.NewImportCommand(dockerCli)),
hide(image.NewLoadCommand(dockerCli)), hide(image.NewLoadCommand(dockerCli)),
hide(image.NewPullCommand(dockerCli)),
hide(image.NewPushCommand(dockerCli)),
hide(image.NewRemoveCommand(dockerCli)), hide(image.NewRemoveCommand(dockerCli)),
hide(image.NewSaveCommand(dockerCli)), hide(image.NewSaveCommand(dockerCli)),
hide(image.NewTagCommand(dockerCli)), hide(image.NewTagCommand(dockerCli)),
hide(system.NewEventsCommand(dockerCli)),
hide(system.NewInspectCommand(dockerCli)),
) )
} }

View File

@ -11,7 +11,7 @@ import (
func NewConfigCommand(dockerCli command.Cli) *cobra.Command { func NewConfigCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "config", Use: "config",
Short: "Manage Docker configs", Short: "Manage Swarm configs",
Args: cli.NoArgs, Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()), RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{ Annotations: map[string]string{

View File

@ -52,6 +52,9 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
options.Command = args[1:] options.Command = args[1:]
return RunExec(dockerCli, options) return RunExec(dockerCli, options)
}, },
Annotations: map[string]string{
"category-top": "2",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -37,6 +37,9 @@ func NewPsCommand(dockerCli command.Cli) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runPs(dockerCli, &options) return runPs(dockerCli, &options)
}, },
Annotations: map[string]string{
"category-top": "3",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -44,6 +44,9 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
} }
return runRun(dockerCli, cmd.Flags(), &opts, copts) return runRun(dockerCli, cmd.Flags(), &opts, copts)
}, },
Annotations: map[string]string{
"category-top": "1",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -105,6 +105,9 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
options.context = args[0] options.context = args[0]
return runBuild(dockerCli, options) return runBuild(dockerCli, options)
}, },
Annotations: map[string]string{
"category-top": "4",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -37,6 +37,9 @@ func NewImagesCommand(dockerCli command.Cli) *cobra.Command {
} }
return runImages(dockerCli, options) return runImages(dockerCli, options)
}, },
Annotations: map[string]string{
"category-top": "7",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -34,6 +34,9 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
opts.remote = args[0] opts.remote = args[0]
return RunPull(dockerCli, opts) return RunPull(dockerCli, opts)
}, },
Annotations: map[string]string{
"category-top": "5",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -35,6 +35,9 @@ func NewPushCommand(dockerCli command.Cli) *cobra.Command {
opts.remote = args[0] opts.remote = args[0]
return RunPush(dockerCli, opts) return RunPush(dockerCli, opts)
}, },
Annotations: map[string]string{
"category-top": "6",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -44,6 +44,9 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command {
} }
return runLogin(dockerCli, opts) return runLogin(dockerCli, opts)
}, },
Annotations: map[string]string{
"category-top": "8",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -23,6 +23,9 @@ func NewLogoutCommand(dockerCli command.Cli) *cobra.Command {
} }
return runLogout(dockerCli, serverAddress) return runLogout(dockerCli, serverAddress)
}, },
Annotations: map[string]string{
"category-top": "9",
},
} }
return cmd return cmd

View File

@ -32,6 +32,9 @@ func NewSearchCommand(dockerCli command.Cli) *cobra.Command {
options.term = args[0] options.term = args[0]
return runSearch(dockerCli, options) return runSearch(dockerCli, options)
}, },
Annotations: map[string]string{
"category-top": "10",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -11,7 +11,7 @@ import (
func NewSecretCommand(dockerCli command.Cli) *cobra.Command { func NewSecretCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "secret", Use: "secret",
Short: "Manage Docker secrets", Short: "Manage Swarm secrets",
Args: cli.NoArgs, Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()), RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{ Annotations: map[string]string{

View File

@ -11,7 +11,7 @@ import (
func NewServiceCommand(dockerCli command.Cli) *cobra.Command { func NewServiceCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "service", Use: "service",
Short: "Manage services", Short: "Manage Swarm services",
Args: cli.NoArgs, Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()), RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{ Annotations: map[string]string{

View File

@ -12,11 +12,12 @@ import (
func NewStackCommand(dockerCli command.Cli) *cobra.Command { func NewStackCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "stack [OPTIONS]", Use: "stack [OPTIONS]",
Short: "Manage Docker stacks", Short: "Manage Swarm stacks",
Args: cli.NoArgs, Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()), RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{ Annotations: map[string]string{
"version": "1.25", "version": "1.25",
"swarm": "",
}, },
} }
defaultHelpFunc := cmd.HelpFunc() defaultHelpFunc := cmd.HelpFunc()

View File

@ -54,6 +54,9 @@ func NewInfoCommand(dockerCli command.Cli) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runInfo(cmd, dockerCli, &opts) return runInfo(cmd, dockerCli, &opts)
}, },
Annotations: map[string]string{
"category-top": "12",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -96,6 +96,9 @@ func NewVersionCommand(dockerCli command.Cli) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
return runVersion(dockerCli, &opts) return runVersion(dockerCli, &opts)
}, },
Annotations: map[string]string{
"category-top": "10",
},
} }
flags := cmd.Flags() flags := cmd.Flags()

View File

@ -9,7 +9,7 @@ keywords: "config"
```markdown ```markdown
Usage: docker config COMMAND Usage: docker config COMMAND
Manage Docker configs Manage Swarm configs
Options: Options:
--help Print usage --help Print usage

View File

@ -9,7 +9,7 @@ keywords: "secret"
```markdown ```markdown
Usage: docker secret COMMAND Usage: docker secret COMMAND
Manage Docker secrets Manage Swarm secrets
Options: Options:
--help Print usage --help Print usage

View File

@ -9,7 +9,7 @@ keywords: "service"
```markdown ```markdown
Usage: docker service COMMAND Usage: docker service COMMAND
Manage services Manage Swarm services
Options: Options:
--help Print usage --help Print usage
@ -29,7 +29,7 @@ Run 'docker service COMMAND --help' for more information on a command.
## Description ## Description
Manage services. Manage Swarm services.
> **Note** > **Note**
> >

View File

@ -9,7 +9,7 @@ keywords: "stack"
```markdown ```markdown
Usage: docker stack [OPTIONS] COMMAND Usage: docker stack [OPTIONS] COMMAND
Manage Docker stacks Manage Swarm stacks
Options: Options:
--help Print usage --help Print usage