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