-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflag.go
146 lines (126 loc) · 3.17 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
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
package cli
import (
"reflect"
"strings"
)
// Flag represents a flag.
type Flag struct {
flag reflect.Value
kind FlagKind
name string
alias string
count int
value string
envKey string
defaultValue string
}
// NewFlag returns a new flag. The flag must be a pointer. You must pass the
// Kind option so the flag parser knows how to process the command line unless
// the flag points to a string, the default flag kind.
func NewFlag(name string, flag interface{}, opts ...FlagOption) *Flag {
v := reflect.ValueOf(flag)
if v.Kind() != reflect.Ptr {
panic("cli: flag must be pointer")
}
f := &Flag{
flag: v.Elem(),
kind: flagString{},
name: strings.ToLower(name),
}
for _, option := range opts {
option(f)
}
return f
}
// Count returns the number of times the flag was set.
func (f *Flag) Count() int {
return f.count
}
// IsSet returns true if the flag was explicitly set.
func (f *Flag) IsSet() bool {
return f.count > 0
}
// Set sets the flag value.
func (f *Flag) Set(value string) {
f.count++
f.flag.Set(reflect.ValueOf(f.kind.Parse(value)))
f.value = value
}
// String returns the value as a string. Boolean flags are
// returned as "true" or "false" as strconv.FormatBool would.
//
// String implements the fmt.Stringer interface.
func (f *Flag) String() string {
if f == nil {
return ""
}
return f.value
}
// FlagKind represents the type of flag.
type FlagKind interface {
Parse(value string) interface{}
HasArg() bool
}
// flagString represents a string flag.
type flagString struct{}
// Parse returns the value as-is.
//
// Parse implements the FlagKind interface.
func (f flagString) Parse(value string) interface{} {
return value
}
// HasArg implements the FlagKind interface.
func (f flagString) HasArg() bool {
return true
}
// flagBool represents a boolean flag.
type flagBool struct{}
// Parse returns "true" if the value is
// 1, t, T, true, TRUE, True, y, Y, yes, YES, Yes.
//
// Parse implements the FlagKind interface.
func (f flagBool) Parse(value string) interface{} {
switch value {
case "1", "t", "T", "true", "TRUE", "True", "y", "Y", "yes", "YES", "Yes":
return true
}
return false
}
// HasArg implements the FlagKind interface.
func (f flagBool) HasArg() bool {
return false
}
// FlagOption represents a functional option for flag configuration.
type FlagOption func(*Flag)
// Kind sets the flag kind.
// This option is required unless the flag points to a string.
// This option must be used before the DefaultValue option.
func Kind(kind FlagKind) FlagOption {
return func(f *Flag) {
f.kind = kind
}
}
// Bool sets the flag kind to the built in boolean flag kind.
func Bool() FlagOption {
return Kind(flagBool{})
}
// ShortFlag sets the short flag.
func ShortFlag(name string) FlagOption {
return func(f *Flag) {
f.alias = name
}
}
// DefaultValue sets the flag default value.
func DefaultValue(value string) FlagOption {
return func(f *Flag) {
f.flag.Set(reflect.ValueOf(f.kind.Parse(value)))
f.value = value
f.defaultValue = value
}
}
// EnvironmentKey sets the flag environment variable key.
func EnvironmentKey(key string) FlagOption {
return func(f *Flag) {
f.envKey = key
}
}