...
1
16
17 package flag
18
19 import (
20 "bytes"
21 "fmt"
22 "io"
23 "strings"
24
25 "github.com/spf13/cobra"
26 "github.com/spf13/pflag"
27 )
28
29 const (
30 usageFmt = "Usage:\n %s\n"
31 )
32
33
34 type NamedFlagSets struct {
35
36 Order []string
37
38 FlagSets map[string]*pflag.FlagSet
39
40 NormalizeNameFunc func(f *pflag.FlagSet, name string) pflag.NormalizedName
41 }
42
43
44
45 func (nfs *NamedFlagSets) FlagSet(name string) *pflag.FlagSet {
46 if nfs.FlagSets == nil {
47 nfs.FlagSets = map[string]*pflag.FlagSet{}
48 }
49 if _, ok := nfs.FlagSets[name]; !ok {
50 flagSet := pflag.NewFlagSet(name, pflag.ExitOnError)
51 flagSet.SetNormalizeFunc(pflag.CommandLine.GetNormalizeFunc())
52 if nfs.NormalizeNameFunc != nil {
53 flagSet.SetNormalizeFunc(nfs.NormalizeNameFunc)
54 }
55 nfs.FlagSets[name] = flagSet
56 nfs.Order = append(nfs.Order, name)
57 }
58 return nfs.FlagSets[name]
59 }
60
61
62
63 func PrintSections(w io.Writer, fss NamedFlagSets, cols int) {
64 for _, name := range fss.Order {
65 fs := fss.FlagSets[name]
66 if !fs.HasFlags() {
67 continue
68 }
69
70 wideFS := pflag.NewFlagSet("", pflag.ExitOnError)
71 wideFS.AddFlagSet(fs)
72
73 var zzz string
74 if cols > 24 {
75 zzz = strings.Repeat("z", cols-24)
76 wideFS.Int(zzz, 0, strings.Repeat("z", cols-24))
77 }
78
79 var buf bytes.Buffer
80 fmt.Fprintf(&buf, "\n%s flags:\n\n%s", strings.ToUpper(name[:1])+name[1:], wideFS.FlagUsagesWrapped(cols))
81
82 if cols > 24 {
83 i := strings.Index(buf.String(), zzz)
84 lines := strings.Split(buf.String()[:i], "\n")
85 fmt.Fprint(w, strings.Join(lines[:len(lines)-1], "\n"))
86 fmt.Fprintln(w)
87 } else {
88 fmt.Fprint(w, buf.String())
89 }
90 }
91 }
92
93
94
95 func SetUsageAndHelpFunc(cmd *cobra.Command, fss NamedFlagSets, cols int) {
96 cmd.SetUsageFunc(func(cmd *cobra.Command) error {
97 fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmd.UseLine())
98 PrintSections(cmd.OutOrStderr(), fss, cols)
99 return nil
100 })
101 cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {
102 fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
103 PrintSections(cmd.OutOrStdout(), fss, cols)
104 })
105 }
106
View as plain text