...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package cobrautl
18
19 import (
20 "bytes"
21 "fmt"
22 "io"
23 "os"
24 "strings"
25 "text/tabwriter"
26 "text/template"
27
28 "github.com/spf13/cobra"
29 "github.com/spf13/pflag"
30 )
31
32 var (
33 commandUsageTemplate *template.Template
34 templFuncs = template.FuncMap{
35 "descToLines": func(s string) []string {
36
37 return strings.Split(strings.Trim(s, "\n\t "), "\n")
38 },
39 "cmdName": func(cmd *cobra.Command, startCmd *cobra.Command) string {
40 parts := []string{cmd.Name()}
41 for cmd.HasParent() && cmd.Parent().Name() != startCmd.Name() {
42 cmd = cmd.Parent()
43 parts = append([]string{cmd.Name()}, parts...)
44 }
45 return strings.Join(parts, " ")
46 },
47 }
48 )
49
50 func init() {
51 commandUsage := `
52 {{ $cmd := .Cmd }}\
53 {{ $cmdname := cmdName .Cmd .Cmd.Root }}\
54 NAME:
55 {{ if not .Cmd.HasParent }}\
56 {{printf "\t%s - %s" .Cmd.Name .Cmd.Short}}
57 {{else}}\
58 {{printf "\t%s - %s" $cmdname .Cmd.Short}}
59 {{end}}\
60
61 USAGE:
62 {{printf "\t%s" .Cmd.UseLine}}
63 {{ if not .Cmd.HasParent }}\
64
65 VERSION:
66 {{printf "\t%s" .Version}}
67 {{end}}\
68 {{if .Cmd.HasSubCommands}}\
69
70 API VERSION:
71 {{printf "\t%s" .APIVersion}}
72 {{end}}\
73 {{if .Cmd.HasSubCommands}}\
74
75
76 COMMANDS:
77 {{range .SubCommands}}\
78 {{ $cmdname := cmdName . $cmd }}\
79 {{ if .Runnable }}\
80 {{printf "\t%s\t%s" $cmdname .Short}}
81 {{end}}\
82 {{end}}\
83 {{end}}\
84 {{ if .Cmd.Long }}\
85
86 DESCRIPTION:
87 {{range $line := descToLines .Cmd.Long}}{{printf "\t%s" $line}}
88 {{end}}\
89 {{end}}\
90 {{if .Cmd.HasLocalFlags}}\
91
92 OPTIONS:
93 {{.LocalFlags}}\
94 {{end}}\
95 {{if .Cmd.HasInheritedFlags}}\
96
97 GLOBAL OPTIONS:
98 {{.GlobalFlags}}\
99 {{end}}
100 `[1:]
101
102 commandUsageTemplate = template.Must(template.New("command_usage").Funcs(templFuncs).Parse(strings.Replace(commandUsage, "\\\n", "", -1)))
103 }
104
105 func etcdFlagUsages(flagSet *pflag.FlagSet) string {
106 x := new(bytes.Buffer)
107
108 flagSet.VisitAll(func(flag *pflag.Flag) {
109 if len(flag.Deprecated) > 0 {
110 return
111 }
112 var format string
113 if len(flag.Shorthand) > 0 {
114 format = " -%s, --%s"
115 } else {
116 format = " %s --%s"
117 }
118 if len(flag.NoOptDefVal) > 0 {
119 format = format + "["
120 }
121 if flag.Value.Type() == "string" {
122
123 format = format + "=%q"
124 } else {
125 format = format + "=%s"
126 }
127 if len(flag.NoOptDefVal) > 0 {
128 format = format + "]"
129 }
130 format = format + "\t%s\n"
131 shorthand := flag.Shorthand
132 fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
133 })
134
135 return x.String()
136 }
137
138 func getSubCommands(cmd *cobra.Command) []*cobra.Command {
139 var subCommands []*cobra.Command
140 for _, subCmd := range cmd.Commands() {
141 subCommands = append(subCommands, subCmd)
142 subCommands = append(subCommands, getSubCommands(subCmd)...)
143 }
144 return subCommands
145 }
146
147 func UsageFunc(cmd *cobra.Command, version, APIVersion string) error {
148 subCommands := getSubCommands(cmd)
149 tabOut := getTabOutWithWriter(os.Stdout)
150 commandUsageTemplate.Execute(tabOut, struct {
151 Cmd *cobra.Command
152 LocalFlags string
153 GlobalFlags string
154 SubCommands []*cobra.Command
155 Version string
156 APIVersion string
157 }{
158 cmd,
159 etcdFlagUsages(cmd.LocalFlags()),
160 etcdFlagUsages(cmd.InheritedFlags()),
161 subCommands,
162 version,
163 APIVersion,
164 })
165 tabOut.Flush()
166 return nil
167 }
168
169 func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer {
170 aTabOut := new(tabwriter.Writer)
171 aTabOut.Init(writer, 0, 8, 1, '\t', 0)
172 return aTabOut
173 }
174
View as plain text