github.com/s-matyukevich/consul@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  }