github.com/devdivbcp/moby@v17.12.0-ce-rc1.0.20200726071732-2d4bfdc789ad+incompatible/cli/cobra.go (about)

     1  package cli // import "github.com/docker/docker/cli"
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/docker/docker/pkg/term"
     7  	"github.com/spf13/cobra"
     8  )
     9  
    10  // SetupRootCommand sets default usage, help, and error handling for the
    11  // root command.
    12  func SetupRootCommand(rootCmd *cobra.Command) {
    13  	cobra.AddTemplateFunc("hasSubCommands", hasSubCommands)
    14  	cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands)
    15  	cobra.AddTemplateFunc("operationSubCommands", operationSubCommands)
    16  	cobra.AddTemplateFunc("managementSubCommands", managementSubCommands)
    17  	cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages)
    18  
    19  	rootCmd.SetUsageTemplate(usageTemplate)
    20  	rootCmd.SetHelpTemplate(helpTemplate)
    21  	rootCmd.SetFlagErrorFunc(FlagErrorFunc)
    22  	rootCmd.SetVersionTemplate("Docker version {{.Version}}\n")
    23  
    24  	rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
    25  	rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
    26  }
    27  
    28  // FlagErrorFunc prints an error message which matches the format of the
    29  // docker/docker/cli error messages
    30  func FlagErrorFunc(cmd *cobra.Command, err error) error {
    31  	if err == nil {
    32  		return nil
    33  	}
    34  
    35  	usage := ""
    36  	if cmd.HasSubCommands() {
    37  		usage = "\n\n" + cmd.UsageString()
    38  	}
    39  	return StatusError{
    40  		Status:     fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage),
    41  		StatusCode: 125,
    42  	}
    43  }
    44  
    45  func hasSubCommands(cmd *cobra.Command) bool {
    46  	return len(operationSubCommands(cmd)) > 0
    47  }
    48  
    49  func hasManagementSubCommands(cmd *cobra.Command) bool {
    50  	return len(managementSubCommands(cmd)) > 0
    51  }
    52  
    53  func operationSubCommands(cmd *cobra.Command) []*cobra.Command {
    54  	var cmds []*cobra.Command
    55  	for _, sub := range cmd.Commands() {
    56  		if sub.IsAvailableCommand() && !sub.HasSubCommands() {
    57  			cmds = append(cmds, sub)
    58  		}
    59  	}
    60  	return cmds
    61  }
    62  
    63  func wrappedFlagUsages(cmd *cobra.Command) string {
    64  	width := 80
    65  	if ws, err := term.GetWinsize(0); err == nil {
    66  		width = int(ws.Width)
    67  	}
    68  	return cmd.Flags().FlagUsagesWrapped(width - 1)
    69  }
    70  
    71  func managementSubCommands(cmd *cobra.Command) []*cobra.Command {
    72  	var cmds []*cobra.Command
    73  	for _, sub := range cmd.Commands() {
    74  		if sub.IsAvailableCommand() && sub.HasSubCommands() {
    75  			cmds = append(cmds, sub)
    76  		}
    77  	}
    78  	return cmds
    79  }
    80  
    81  var usageTemplate = `Usage:
    82  
    83  {{- if not .HasSubCommands}}	{{.UseLine}}{{end}}
    84  {{- if .HasSubCommands}}	{{ .CommandPath}} COMMAND{{end}}
    85  
    86  {{ .Short | trim }}
    87  
    88  {{- if gt .Aliases 0}}
    89  
    90  Aliases:
    91    {{.NameAndAliases}}
    92  
    93  {{- end}}
    94  {{- if .HasExample}}
    95  
    96  Examples:
    97  {{ .Example }}
    98  
    99  {{- end}}
   100  {{- if .HasAvailableFlags}}
   101  
   102  Options:
   103  {{ wrappedFlagUsages . | trimRightSpace}}
   104  
   105  {{- end}}
   106  {{- if hasManagementSubCommands . }}
   107  
   108  Management Commands:
   109  
   110  {{- range managementSubCommands . }}
   111    {{rpad .Name .NamePadding }} {{.Short}}
   112  {{- end}}
   113  
   114  {{- end}}
   115  {{- if hasSubCommands .}}
   116  
   117  Commands:
   118  
   119  {{- range operationSubCommands . }}
   120    {{rpad .Name .NamePadding }} {{.Short}}
   121  {{- end}}
   122  {{- end}}
   123  
   124  {{- if .HasSubCommands }}
   125  
   126  Run '{{.CommandPath}} COMMAND --help' for more information on a command.
   127  {{- end}}
   128  `
   129  
   130  var helpTemplate = `
   131  {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`