4
4
"context"
5
5
"flag"
6
6
"fmt"
7
+ "os"
7
8
"reflect"
8
9
"time"
9
10
@@ -12,11 +13,15 @@ import (
12
13
)
13
14
14
15
// Backend that loads configuration from the command line flags.
15
- type Backend struct {}
16
+ type Backend struct {
17
+ flags * flag.FlagSet
18
+ }
16
19
17
20
// NewBackend creates a flags backend.
18
21
func NewBackend () * Backend {
19
- return new (Backend )
22
+ return & Backend {
23
+ flags : flag .CommandLine ,
24
+ }
20
25
}
21
26
22
27
// LoadStruct takes a struct config, define flags based on it and parse the command line args.
@@ -34,80 +39,90 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
34
39
switch {
35
40
case f .Value .Type ().String () == "time.Duration" :
36
41
var val time.Duration
37
- flag .DurationVar (& val , f .Key , time .Duration (f .Default .Int ()), f .Description )
42
+ b . flags .DurationVar (& val , f .Key , time .Duration (f .Default .Int ()), f .Description )
38
43
if f .Short != "" {
39
- flag .DurationVar (& val , f .Short , time .Duration (f .Default .Int ()), shortDesc (f .Description ))
44
+ b . flags .DurationVar (& val , f .Short , time .Duration (f .Default .Int ()), shortDesc (f .Description ))
40
45
}
41
46
// this function must be executed after the flag.Parse call.
42
47
defer func () {
43
48
// if the user has set the flag, save the value in the field.
44
- if isFlagSet (f ) {
49
+ if b . isFlagSet (f ) {
45
50
f .Value .SetInt (int64 (val ))
46
51
}
47
52
}()
48
53
case k == reflect .Bool :
49
54
var val bool
50
- flag .BoolVar (& val , f .Key , f .Default .Bool (), f .Description )
55
+ b . flags .BoolVar (& val , f .Key , f .Default .Bool (), f .Description )
51
56
if f .Short != "" {
52
- flag .BoolVar (& val , f .Short , f .Default .Bool (), shortDesc (f .Description ))
57
+ b . flags .BoolVar (& val , f .Short , f .Default .Bool (), shortDesc (f .Description ))
53
58
}
54
59
defer func () {
55
- if isFlagSet (f ) {
60
+ if b . isFlagSet (f ) {
56
61
f .Value .SetBool (val )
57
62
}
58
63
}()
59
64
case k >= reflect .Int && k <= reflect .Int64 :
60
65
var val int
61
- flag .IntVar (& val , f .Key , int (f .Default .Int ()), f .Description )
66
+ b . flags .IntVar (& val , f .Key , int (f .Default .Int ()), f .Description )
62
67
if f .Short != "" {
63
- flag .IntVar (& val , f .Short , int (f .Default .Int ()), shortDesc (f .Description ))
68
+ b . flags .IntVar (& val , f .Short , int (f .Default .Int ()), shortDesc (f .Description ))
64
69
}
65
70
defer func () {
66
- if isFlagSet (f ) {
71
+ if b . isFlagSet (f ) {
67
72
f .Value .SetInt (int64 (val ))
68
73
}
69
74
}()
70
75
case k >= reflect .Uint && k <= reflect .Uint64 :
71
76
var val uint64
72
- flag .Uint64Var (& val , f .Key , f .Default .Uint (), f .Description )
77
+ b . flags .Uint64Var (& val , f .Key , f .Default .Uint (), f .Description )
73
78
if f .Short != "" {
74
- flag .Uint64Var (& val , f .Short , f .Default .Uint (), shortDesc (f .Description ))
79
+ b . flags .Uint64Var (& val , f .Short , f .Default .Uint (), shortDesc (f .Description ))
75
80
}
76
81
defer func () {
77
- if isFlagSet (f ) {
82
+ if b . isFlagSet (f ) {
78
83
f .Value .SetUint (val )
79
84
}
80
85
}()
81
86
case k >= reflect .Float32 && k <= reflect .Float64 :
82
87
var val float64
83
- flag .Float64Var (& val , f .Key , f .Default .Float (), f .Description )
88
+ b . flags .Float64Var (& val , f .Key , f .Default .Float (), f .Description )
84
89
if f .Short != "" {
85
- flag .Float64Var (& val , f .Short , f .Default .Float (), shortDesc (f .Description ))
90
+ b . flags .Float64Var (& val , f .Short , f .Default .Float (), shortDesc (f .Description ))
86
91
}
87
92
defer func () {
88
- if isFlagSet (f ) {
93
+ if b . isFlagSet (f ) {
89
94
f .Value .SetFloat (val )
90
95
}
91
96
}()
92
97
case k == reflect .String :
93
98
var val string
94
- flag .StringVar (& val , f .Key , f .Default .String (), f .Description )
99
+ b . flags .StringVar (& val , f .Key , f .Default .String (), f .Description )
95
100
if f .Short != "" {
96
- flag .StringVar (& val , f .Short , f .Default .String (), shortDesc (f .Description ))
101
+ b . flags .StringVar (& val , f .Short , f .Default .String (), shortDesc (f .Description ))
97
102
}
98
103
defer func () {
99
- if isFlagSet (f ) {
104
+ if b . isFlagSet (f ) {
100
105
f .Value .SetString (val )
101
106
}
102
107
}()
103
108
default :
104
- flag .Var (& flagValue {f }, f .Key , f .Description )
109
+ b . flags .Var (& flagValue {f }, f .Key , f .Description )
105
110
}
106
111
}
107
112
108
- flag .Parse ()
113
+ // Note: in the usual case, when b.flags is flag.CommandLine, this will exit
114
+ // rather than returning an error.
115
+ return b .flags .Parse (os .Args [1 :])
116
+ }
109
117
110
- return nil
118
+ func (b * Backend ) isFlagSet (config * confita.FieldConfig ) bool {
119
+ ok := false
120
+ b .flags .Visit (func (f * flag.Flag ) {
121
+ if f .Name == config .Key || f .Name == config .Short {
122
+ ok = true
123
+ }
124
+ })
125
+ return ok
111
126
}
112
127
113
128
type flagValue struct {
@@ -139,11 +154,3 @@ func (b *Backend) Name() string {
139
154
func shortDesc (description string ) string {
140
155
return fmt .Sprintf ("%s (short)" , description )
141
156
}
142
-
143
- func isFlagSet (config * confita.FieldConfig ) bool {
144
- flagset := make (map [* confita.FieldConfig ]bool )
145
- flag .Visit (func (f * flag.Flag ) { flagset [config ] = true })
146
-
147
- _ , ok := flagset [config ]
148
- return ok
149
- }
0 commit comments