move commonly used top-level commands to the top of --help
This adds a new annotation to commands that are known to be frequently used, and allows setting a custom weight/order for these commands to influence in what order they appear in the --help output. I'm not entirely happy with the implementation (we could at least use some helpers for this, and/or make it more generic to group commands in output), but it could be a start. For now, limiting this to only be used for the top-level --help, but we can expand this to subcommands as well if we think it makes sense to highlight "common" / "commonly used" commands. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
a058f9774a
commit
aaa912c9f7
42
cli/cobra.go
42
cli/cobra.go
@ -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,9 +32,11 @@ 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("hasOrchestratorSubCommands", hasOrchestratorSubCommands)
|
cobra.AddTemplateFunc("hasOrchestratorSubCommands", hasOrchestratorSubCommands)
|
||||||
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("orchestratorSubCommands", orchestratorSubCommands)
|
||||||
@ -250,12 +254,43 @@ 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)
|
||||||
}
|
}
|
||||||
@ -378,6 +413,13 @@ Examples:
|
|||||||
Options:
|
Options:
|
||||||
{{ wrappedFlagUsages . | trimRightSpace}}
|
{{ wrappedFlagUsages . | trimRightSpace}}
|
||||||
|
|
||||||
|
{{- end}}
|
||||||
|
{{- end}}
|
||||||
|
{{- if hasTopCommands .}}
|
||||||
|
|
||||||
|
Common Commands:
|
||||||
|
{{- range topCommands .}}
|
||||||
|
{{rpad (decoratedName .) (add .NamePadding 1)}}{{.Short}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- if hasManagementSubCommands . }}
|
{{- if hasManagementSubCommands . }}
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user