forked from grafana/loki
-
Notifications
You must be signed in to change notification settings - Fork 1
/
flag.go
104 lines (89 loc) · 2.33 KB
/
flag.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package cfg
import (
"flag"
"fmt"
"sort"
"strings"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"github.com/grafana/dskit/flagext"
"github.com/pkg/errors"
)
// Defaults registers flags to the flagSet using dst as the flagext.Registerer
func Defaults(fs *flag.FlagSet) Source {
return func(dst Cloneable) error {
r, ok := dst.(flagext.Registerer)
if !ok {
return errors.New("dst does not satisfy flagext.Registerer")
}
// already sets the defaults on r
r.RegisterFlags(fs)
return nil
}
}
// Flags parses the flag from the command line, setting only user-supplied
// values on the flagext.Registerer passed to Defaults()
func Flags(args []string, fs *flag.FlagSet) Source {
flag.Usage = categorizedUsage(fs)
return dFlags(fs, args)
}
// dFlags parses the flagset, applying all values set on the slice
func dFlags(fs *flag.FlagSet, args []string) Source {
return func(dst Cloneable) error {
// parse the final flagset
return fs.Parse(args)
}
}
func categorizedUsage(fs *flag.FlagSet) func() {
categories := make(map[string][]string)
return func() {
if fs.Name() == "" {
fmt.Fprintf(fs.Output(), "Usage:\n")
} else {
fmt.Fprintf(fs.Output(), "Usage of %s:\n", fs.Name())
}
fs.VisitAll(func(f *flag.Flag) {
id := ""
if strings.Contains(f.Name, ".") {
id = strings.Split(f.Name, ".")[0]
}
kind, usage := flag.UnquoteUsage(f)
if kind != "" {
kind = " " + kind
}
def := f.DefValue
if def != "" {
def = fmt.Sprintf(" (default %s)", def)
}
categories[id] = append(categories[id], fmt.Sprintf(" -%s%s:\n %s%s", f.Name, kind, usage, def))
})
for name, flags := range categories {
if len(flags) == 1 {
categories[""] = append(categories[""], flags[0])
delete(categories, name)
}
}
for name := range categories {
sort.Strings(categories[name])
}
for _, u := range categories[""] {
fmt.Fprintln(fs.Output(), u)
}
fmt.Fprintln(fs.Output())
keys := make([]string, 0, len(categories))
for k := range categories {
keys = append(keys, k)
}
sort.Strings(keys)
for _, name := range keys {
if name == "" {
continue
}
fmt.Fprintf(fs.Output(), " %s:\n", cases.Title(language.Und, cases.NoLower).String(name))
for _, u := range categories[name] {
fmt.Fprintln(fs.Output(), u)
}
fmt.Fprintln(fs.Output())
}
}
}