github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/cli/cobra.go (about)

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