| package main | |
| import ( | |
| "fmt" | |
| "github.com/moby/term" | |
| "github.com/spf13/cobra" | |
| ) | |
| // SetupRootCommand sets default usage, help, and error handling for the | |
| // root command. | |
| func SetupRootCommand(rootCmd *cobra.Command) { | |
| cobra.AddTemplateFunc("hasSubCommands", hasSubCommands) | |
| cobra.AddTemplateFunc("hasManagementSubCommands", hasManagementSubCommands) | |
| cobra.AddTemplateFunc("operationSubCommands", operationSubCommands) | |
| cobra.AddTemplateFunc("managementSubCommands", managementSubCommands) | |
| cobra.AddTemplateFunc("wrappedFlagUsages", wrappedFlagUsages) | |
| rootCmd.SetUsageTemplate(usageTemplate) | |
| rootCmd.SetHelpTemplate(helpTemplate) | |
| rootCmd.SetFlagErrorFunc(FlagErrorFunc) | |
| rootCmd.SetVersionTemplate("Docker version {{.Version}}\n") | |
| rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") | |
| rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") | |
| } | |
| // FlagErrorFunc prints an error message which matches the format of the | |
| // docker/docker/cli error messages | |
| func FlagErrorFunc(cmd *cobra.Command, err error) error { | |
| if err == nil { | |
| return nil | |
| } | |
| usage := "" | |
| if cmd.HasSubCommands() { | |
| usage = "\n\n" + cmd.UsageString() | |
| } | |
| return StatusError{ | |
| Status: fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage), | |
| StatusCode: 125, | |
| } | |
| } | |
| func hasSubCommands(cmd *cobra.Command) bool { | |
| return len(operationSubCommands(cmd)) > 0 | |
| } | |
| func hasManagementSubCommands(cmd *cobra.Command) bool { | |
| return len(managementSubCommands(cmd)) > 0 | |
| } | |
| func operationSubCommands(cmd *cobra.Command) []*cobra.Command { | |
| var cmds []*cobra.Command | |
| for _, sub := range cmd.Commands() { | |
| if sub.IsAvailableCommand() && !sub.HasSubCommands() { | |
| cmds = append(cmds, sub) | |
| } | |
| } | |
| return cmds | |
| } | |
| func wrappedFlagUsages(cmd *cobra.Command) string { | |
| width := 80 | |
| if ws, err := term.GetWinsize(0); err == nil { | |
| width = int(ws.Width) | |
| } | |
| return cmd.Flags().FlagUsagesWrapped(width - 1) | |
| } | |
| func managementSubCommands(cmd *cobra.Command) []*cobra.Command { | |
| var cmds []*cobra.Command | |
| for _, sub := range cmd.Commands() { | |
| if sub.IsAvailableCommand() && sub.HasSubCommands() { | |
| cmds = append(cmds, sub) | |
| } | |
| } | |
| return cmds | |
| } | |
| var usageTemplate = `Usage: | |
| {{- if not .HasSubCommands}} {{.UseLine}}{{end}} | |
| {{- if .HasSubCommands}} {{ .CommandPath}} COMMAND{{end}} | |
| {{ .Short | trim }} | |
| {{- if gt .Aliases 0}} | |
| Aliases: | |
| {{.NameAndAliases}} | |
| {{- end}} | |
| {{- if .HasExample}} | |
| Examples: | |
| {{ .Example }} | |
| {{- end}} | |
| {{- if .HasAvailableFlags}} | |
| Options: | |
| {{ wrappedFlagUsages . | trimRightSpace}} | |
| {{- end}} | |
| {{- if hasManagementSubCommands . }} | |
| Management Commands: | |
| {{- range managementSubCommands . }} | |
| {{rpad .Name .NamePadding }} {{.Short}} | |
| {{- end}} | |
| {{- end}} | |
| {{- if hasSubCommands .}} | |
| Commands: | |
| {{- range operationSubCommands . }} | |
| {{rpad .Name .NamePadding }} {{.Short}} | |
| {{- end}} | |
| {{- end}} | |
| {{- if .HasSubCommands }} | |
| Run '{{.CommandPath}} COMMAND --help' for more information on a command. | |
| {{- end}} | |
| ` | |
| var helpTemplate = ` | |
| {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` |