hub.fastgit.org/hashicorp/consul.git@v1.4.5/command/flags/usage.go (about) 1 package flags 2 3 import ( 4 "bytes" 5 "flag" 6 "fmt" 7 "io" 8 "strings" 9 10 text "github.com/kr/text" 11 ) 12 13 func Usage(txt string, flags *flag.FlagSet) string { 14 u := &Usager{ 15 Usage: txt, 16 Flags: flags, 17 } 18 return u.String() 19 } 20 21 type Usager struct { 22 Usage string 23 Flags *flag.FlagSet 24 } 25 26 func (u *Usager) String() string { 27 out := new(bytes.Buffer) 28 out.WriteString(strings.TrimSpace(u.Usage)) 29 out.WriteString("\n") 30 out.WriteString("\n") 31 32 if u.Flags != nil { 33 f := &HTTPFlags{} 34 clientFlags := f.ClientFlags() 35 serverFlags := f.ServerFlags() 36 37 var httpFlags, cmdFlags *flag.FlagSet 38 u.Flags.VisitAll(func(f *flag.Flag) { 39 if contains(clientFlags, f) || contains(serverFlags, f) { 40 if httpFlags == nil { 41 httpFlags = flag.NewFlagSet("", flag.ContinueOnError) 42 } 43 httpFlags.Var(f.Value, f.Name, f.Usage) 44 } else { 45 if cmdFlags == nil { 46 cmdFlags = flag.NewFlagSet("", flag.ContinueOnError) 47 } 48 cmdFlags.Var(f.Value, f.Name, f.Usage) 49 } 50 }) 51 52 if httpFlags != nil { 53 printTitle(out, "HTTP API Options") 54 httpFlags.VisitAll(func(f *flag.Flag) { 55 printFlag(out, f) 56 }) 57 } 58 59 if cmdFlags != nil { 60 printTitle(out, "Command Options") 61 cmdFlags.VisitAll(func(f *flag.Flag) { 62 printFlag(out, f) 63 }) 64 } 65 } 66 67 return strings.TrimRight(out.String(), "\n") 68 } 69 70 // printTitle prints a consistently-formatted title to the given writer. 71 func printTitle(w io.Writer, s string) { 72 fmt.Fprintf(w, "%s\n\n", s) 73 } 74 75 // printFlag prints a single flag to the given writer. 76 func printFlag(w io.Writer, f *flag.Flag) { 77 example, _ := flag.UnquoteUsage(f) 78 if example != "" { 79 fmt.Fprintf(w, " -%s=<%s>\n", f.Name, example) 80 } else { 81 fmt.Fprintf(w, " -%s\n", f.Name) 82 } 83 84 indented := wrapAtLength(f.Usage, 5) 85 fmt.Fprintf(w, "%s\n\n", indented) 86 } 87 88 // contains returns true if the given flag is contained in the given flag 89 // set or false otherwise. 90 func contains(fs *flag.FlagSet, f *flag.Flag) bool { 91 if fs == nil { 92 return false 93 } 94 95 var in bool 96 fs.VisitAll(func(hf *flag.Flag) { 97 in = in || f.Name == hf.Name 98 }) 99 return in 100 } 101 102 // maxLineLength is the maximum width of any line. 103 const maxLineLength int = 72 104 105 // wrapAtLength wraps the given text at the maxLineLength, taking into account 106 // any provided left padding. 107 func wrapAtLength(s string, pad int) string { 108 wrapped := text.Wrap(s, maxLineLength-pad) 109 lines := strings.Split(wrapped, "\n") 110 for i, line := range lines { 111 lines[i] = strings.Repeat(" ", pad) + line 112 } 113 return strings.Join(lines, "\n") 114 }