1 package altsrc
2
3 import (
4 "fmt"
5 "path/filepath"
6 "strconv"
7 "syscall"
8
9 "github.com/urfave/cli/v2"
10 )
11
12
13
14 type FlagInputSourceExtension interface {
15 cli.Flag
16 ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error
17 }
18
19
20
21
22
23 func ApplyInputSourceValues(cCtx *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error {
24 for _, f := range flags {
25 inputSourceExtendedFlag, isType := f.(FlagInputSourceExtension)
26 if isType {
27 err := inputSourceExtendedFlag.ApplyInputSourceValue(cCtx, inputSourceContext)
28 if err != nil {
29 return err
30 }
31 }
32 }
33
34 return nil
35 }
36
37
38
39
40 func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc {
41 return func(cCtx *cli.Context) error {
42 inputSource, err := createInputSource()
43 if err != nil {
44 return fmt.Errorf("Unable to create input source: inner error: \n'%v'", err.Error())
45 }
46
47 return ApplyInputSourceValues(cCtx, inputSource, flags)
48 }
49 }
50
51
52
53
54 func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc {
55 return func(cCtx *cli.Context) error {
56 inputSource, err := createInputSource(cCtx)
57 if err != nil {
58 return fmt.Errorf("Unable to create input source with context: inner error: \n'%v'", err.Error())
59 }
60
61 return ApplyInputSourceValues(cCtx, inputSource, flags)
62 }
63 }
64
65
66 func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
67 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
68 return nil
69 }
70 for _, name := range f.GenericFlag.Names() {
71 if !isc.isSet(name) {
72 continue
73 }
74 value, err := isc.Generic(name)
75 if err != nil {
76 return err
77 }
78 if value == nil {
79 continue
80 }
81 for _, n := range f.Names() {
82 if err := f.set.Set(n, value.String()); err != nil {
83 return err
84 }
85 }
86 }
87
88 return nil
89 }
90
91
92 func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
93 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
94 return nil
95 }
96 for _, name := range f.StringSliceFlag.Names() {
97 if !isc.isSet(name) {
98 continue
99 }
100 value, err := isc.StringSlice(name)
101 if err != nil {
102 return err
103 }
104 if value == nil {
105 continue
106 }
107 var sliceValue = *(cli.NewStringSlice(value...))
108 for _, n := range f.Names() {
109 underlyingFlag := f.set.Lookup(n)
110 if underlyingFlag == nil {
111 continue
112 }
113 underlyingFlag.Value = &sliceValue
114 if err := f.set.Set(n, sliceValue.Serialize()); err != nil {
115 return err
116 }
117 }
118 if f.Destination != nil {
119 _ = f.Destination.Set(sliceValue.Serialize())
120 }
121 }
122 return nil
123 }
124
125
126 func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
127 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
128 return nil
129 }
130 for _, name := range f.IntSliceFlag.Names() {
131 if !isc.isSet(name) {
132 continue
133 }
134 value, err := isc.IntSlice(name)
135 if err != nil {
136 return err
137 }
138 if value == nil {
139 continue
140 }
141 var sliceValue = *(cli.NewIntSlice(value...))
142 for _, n := range f.Names() {
143 underlyingFlag := f.set.Lookup(n)
144 if underlyingFlag == nil {
145 continue
146 }
147 underlyingFlag.Value = &sliceValue
148 }
149 if f.Destination != nil {
150 if err := f.Destination.Set(sliceValue.Serialize()); err != nil {
151 return err
152 }
153 }
154 }
155 return nil
156 }
157
158
159 func (f *Int64SliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
160 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
161 return nil
162 }
163 for _, name := range f.Int64SliceFlag.Names() {
164 if !isc.isSet(name) {
165 continue
166 }
167 value, err := isc.Int64Slice(name)
168 if err != nil {
169 return err
170 }
171 if value == nil {
172 continue
173 }
174 var sliceValue = *(cli.NewInt64Slice(value...))
175 for _, n := range f.Names() {
176 underlyingFlag := f.set.Lookup(n)
177 if underlyingFlag == nil {
178 continue
179 }
180 underlyingFlag.Value = &sliceValue
181 }
182 if f.Destination != nil {
183 if err := f.Destination.Set(sliceValue.Serialize()); err != nil {
184 return err
185 }
186 }
187 }
188 return nil
189 }
190
191
192 func (f *Float64SliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
193 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
194 return nil
195 }
196 for _, name := range f.Float64SliceFlag.Names() {
197 if !isc.isSet(name) {
198 continue
199 }
200 value, err := isc.Float64Slice(name)
201 if err != nil {
202 return err
203 }
204 if value == nil {
205 continue
206 }
207 var sliceValue = *(cli.NewFloat64Slice(value...))
208 for _, n := range f.Names() {
209 underlyingFlag := f.set.Lookup(n)
210 if underlyingFlag == nil {
211 continue
212 }
213 underlyingFlag.Value = &sliceValue
214 }
215 if f.Destination != nil {
216 if err := f.Destination.Set(sliceValue.Serialize()); err != nil {
217 return err
218 }
219 }
220 }
221 return nil
222 }
223
224
225 func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
226 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
227 return nil
228 }
229 for _, name := range f.BoolFlag.Names() {
230 if !isc.isSet(name) {
231 continue
232 }
233 value, err := isc.Bool(name)
234 if err != nil {
235 return err
236 }
237 for _, n := range f.Names() {
238 if err := f.set.Set(n, strconv.FormatBool(value)); err != nil {
239 return err
240 }
241 }
242 }
243 return nil
244 }
245
246
247 func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
248 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
249 return nil
250 }
251 for _, name := range f.StringFlag.Names() {
252 if !isc.isSet(name) {
253 continue
254 }
255 value, err := isc.String(name)
256 if err != nil {
257 return err
258 }
259 for _, n := range f.Names() {
260 if err := f.set.Set(n, value); err != nil {
261 return err
262 }
263 }
264 }
265 return nil
266 }
267
268
269 func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
270 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
271 return nil
272 }
273 for _, name := range f.PathFlag.Names() {
274 if !isc.isSet(name) {
275 continue
276 }
277 value, err := isc.String(name)
278 if err != nil {
279 return err
280 }
281 if value == "" {
282 continue
283 }
284 for _, n := range f.Names() {
285 if !filepath.IsAbs(value) && isc.Source() != "" {
286 basePathAbs, err := filepath.Abs(isc.Source())
287 if err != nil {
288 return err
289 }
290 value = filepath.Join(filepath.Dir(basePathAbs), value)
291 }
292 if err := f.set.Set(n, value); err != nil {
293 return err
294 }
295 }
296 }
297 return nil
298 }
299
300
301 func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
302 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
303 return nil
304 }
305 for _, name := range f.IntFlag.Names() {
306 if !isc.isSet(name) {
307 continue
308 }
309 value, err := isc.Int(name)
310 if err != nil {
311 return err
312 }
313 for _, n := range f.Names() {
314 if err := f.set.Set(n, strconv.FormatInt(int64(value), 10)); err != nil {
315 return err
316 }
317 }
318 }
319 return nil
320 }
321
322 func (f *Int64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
323 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
324 return nil
325 }
326 for _, name := range f.Int64Flag.Names() {
327 if !isc.isSet(name) {
328 continue
329 }
330 value, err := isc.Int64(name)
331 if err != nil {
332 return err
333 }
334 for _, n := range f.Names() {
335 if err := f.set.Set(n, strconv.FormatInt(value, 10)); err != nil {
336 return err
337 }
338 }
339 }
340 return nil
341 }
342
343 func (f *UintFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
344 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
345 return nil
346 }
347 for _, name := range f.UintFlag.Names() {
348 if !isc.isSet(name) {
349 continue
350 }
351 value, err := isc.Uint(name)
352 if err != nil {
353 return err
354 }
355 for _, n := range f.Names() {
356 if err := f.set.Set(n, strconv.FormatUint(uint64(value), 10)); err != nil {
357 return err
358 }
359 }
360 }
361 return nil
362 }
363
364 func (f *Uint64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
365 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
366 return nil
367 }
368 for _, name := range f.Uint64Flag.Names() {
369 if !isc.isSet(name) {
370 continue
371 }
372 value, err := isc.Uint64(name)
373 if err != nil {
374 return err
375 }
376 for _, n := range f.Names() {
377 if err := f.set.Set(n, strconv.FormatUint(value, 10)); err != nil {
378 return err
379 }
380 }
381 }
382 return nil
383 }
384
385
386 func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
387 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
388 return nil
389 }
390 for _, name := range f.DurationFlag.Names() {
391 if !isc.isSet(name) {
392 continue
393 }
394 value, err := isc.Duration(name)
395 if err != nil {
396 return err
397 }
398 for _, n := range f.Names() {
399 if err := f.set.Set(n, value.String()); err != nil {
400 return err
401 }
402 }
403 }
404 return nil
405 }
406
407
408 func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
409 if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) {
410 return nil
411 }
412 for _, name := range f.Float64Flag.Names() {
413 if !isc.isSet(name) {
414 continue
415 }
416 value, err := isc.Float64(name)
417 if err != nil {
418 return err
419 }
420 floatStr := float64ToString(value)
421 for _, n := range f.Names() {
422 if err := f.set.Set(n, floatStr); err != nil {
423 return err
424 }
425 }
426 }
427 return nil
428 }
429
430 func isEnvVarSet(envVars []string) bool {
431 for _, envVar := range envVars {
432 if _, ok := syscall.Getenv(envVar); ok {
433
434
435
436 return true
437 }
438 }
439
440 return false
441 }
442
443 func float64ToString(f float64) string {
444 return fmt.Sprintf("%v", f)
445 }
446
View as plain text