github.com/wozhu6104/docker@v20.10.10+incompatible/cli/cobra.go (about) 1 package cli // import "github.com/docker/docker/cli" 2 3 import ( 4 "fmt" 5 6 "github.com/moby/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}}`