/
cmdr.go
182 lines (151 loc) · 7.12 KB
/
cmdr.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package cmdr
import (
"os"
"flag"
"time"
"text/tabwriter"
"fmt"
)
// Default program bound to os.Args and flag.CommandLine
var DefaultProgram = &Program{
Name: os.Args[0],
Options: flag.CommandLine,
Usage: ProgramUsage,
ExitOnError: true,
}
// Create and add a new command to the DefaultProgram
func Cmd(name, description string, fn interface{}) *Command {
cmd := NewCommand(name, description, fn)
DefaultProgram.AddCommand(cmd)
return cmd
}
// Convenience function, invoking `DefaultProgram.Main(os.Args[1:])`
// Parses args and runs a command. Returns the command run.
func Main() *Command {
return DefaultProgram.Main(os.Args[1:])
}
// ==============================================================================================
func newTabWriter() *tabwriter.Writer {
return tabwriter.NewWriter(os.Stderr, 5, 0, 3, ' ', 0)
}
func flagIsString(f *flag.Flag) bool {
if _, ok := f.Value.(*stringValue); ok {
return true
} else if getter, ok := f.Value.(flag.Getter); ok {
_, ok = getter.Get().(string)
return ok
}
return false
}
func optionsUsage(flagSet *flag.FlagSet) {
w := newTabWriter()
flagSet.VisitAll(func(f *flag.Flag) {
v := f.Value
if _, ok := v.(*boolValue); ok {
if f.DefValue == "false" {
fmt.Fprintf(w, " -%s\t%s\n", f.Name, f.Usage)
} else {
fmt.Fprintf(w, " -%s=true\t%s\n", f.Name, f.Usage)
}
} else {
if flagIsString(f) {
fmt.Fprintf(w, " -%s %q\t%s\n", f.Name, f.DefValue, f.Usage)
} else {
fmt.Fprintf(w, " -%s %s\t%s\n", f.Name, f.DefValue, f.Usage)
}
}
})
w.Flush()
}
// ==============================================================================================
// BoolVar defines a bool flag with specified name, default value, and usage string.
// The argument p points to a bool variable in which to store the value of the flag.
func BoolVar(p *bool, name string, value bool, usage string) {
DefaultProgram.Options.BoolVar(p, name, value, usage)
}
// Bool defines a bool flag with specified name, default value, and usage string.
// The return value is the address of a bool variable that stores the value of the flag.
func Bool(name string, value bool, usage string) *bool {
return DefaultProgram.Options.Bool(name, value, usage)
}
// IntVar defines an int flag with specified name, default value, and usage string.
// The argument p points to an int variable in which to store the value of the flag.
func IntVar(p *int, name string, value int, usage string) {
DefaultProgram.Options.IntVar(p, name, value, usage)
}
// Int defines an int flag with specified name, default value, and usage string.
// The return value is the address of an int variable that stores the value of the flag.
func Int(name string, value int, usage string) *int {
return DefaultProgram.Options.Int(name, value, usage)
}
// Int64Var defines an int64 flag with specified name, default value, and usage string.
// The argument p points to an int64 variable in which to store the value of the flag.
func Int64Var(p *int64, name string, value int64, usage string) {
DefaultProgram.Options.Int64Var(p, name, value, usage)
}
// Int64 defines an int64 flag with specified name, default value, and usage string.
// The return value is the address of an int64 variable that stores the value of the flag.
func Int64(name string, value int64, usage string) *int64 {
return DefaultProgram.Options.Int64(name, value, usage)
}
// UintVar defines a uint flag with specified name, default value, and usage string.
// The argument p points to a uint variable in which to store the value of the flag.
func UintVar(p *uint, name string, value uint, usage string) {
DefaultProgram.Options.UintVar(p, name, value, usage)
}
// Uint defines a uint flag with specified name, default value, and usage string.
// The return value is the address of a uint variable that stores the value of the flag.
func Uint(name string, value uint, usage string) *uint {
return DefaultProgram.Options.Uint(name, value, usage)
}
// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
// The argument p points to a uint64 variable in which to store the value of the flag.
func Uint64Var(p *uint64, name string, value uint64, usage string) {
DefaultProgram.Options.Uint64Var(p, name, value, usage)
}
// Uint64 defines a uint64 flag with specified name, default value, and usage string.
// The return value is the address of a uint64 variable that stores the value of the flag.
func Uint64(name string, value uint64, usage string) *uint64 {
return DefaultProgram.Options.Uint64(name, value, usage)
}
// StringVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a string variable in which to store the value of the flag.
func StringVar(p *string, name string, value string, usage string) {
DefaultProgram.Options.StringVar(p, name, value, usage)
}
// String defines a string flag with specified name, default value, and usage string.
// The return value is the address of a string variable that stores the value of the flag.
func String(name string, value string, usage string) *string {
return DefaultProgram.Options.String(name, value, usage)
}
// Float64Var defines a float64 flag with specified name, default value, and usage string.
// The argument p points to a float64 variable in which to store the value of the flag.
func Float64Var(p *float64, name string, value float64, usage string) {
DefaultProgram.Options.Float64Var(p, name, value, usage)
}
// Float64 defines a float64 flag with specified name, default value, and usage string.
// The return value is the address of a float64 variable that stores the value of the flag.
func Float64(name string, value float64, usage string) *float64 {
return DefaultProgram.Options.Float64(name, value, usage)
}
// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
// The argument p points to a time.Duration variable in which to store the value of the flag.
// The flag accepts a value acceptable to time.ParseDuration.
func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
DefaultProgram.Options.DurationVar(p, name, value, usage)
}
// Duration defines a time.Duration flag with specified name, default value, and usage string.
// The return value is the address of a time.Duration variable that stores the value of the flag.
// The flag accepts a value acceptable to time.ParseDuration.
func Duration(name string, value time.Duration, usage string) *time.Duration {
return DefaultProgram.Options.Duration(name, value, usage)
}
// Var defines a flag with the specified name and usage string. The type and
// value of the flag are represented by the first argument, of type Value, which
// typically holds a user-defined implementation of Value. For instance, the
// caller could create a flag that turns a comma-separated string into a slice
// of strings by giving the slice the methods of Value; in particular, Set would
// decompose the comma-separated string into the slice.
func Var(value flag.Value, name string, usage string) {
DefaultProgram.Options.Var(value, name, usage)
}