-
Notifications
You must be signed in to change notification settings - Fork 1
/
viper.go
71 lines (54 loc) · 2.11 KB
/
viper.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
package cli
import (
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.uber.org/zap"
)
var ReboundFlagAnnotation = "github.com/streamingfast/cli#rebound-key"
// ConfigureViperForCommand sets env prefix to 'prefix', automatic env to check in env
// for any flags coming from anywhere (flag, config, default, etc.) as well as
// scoping flags to the command it's defined in for global acces.
func ConfigureViperForCommand(root *cobra.Command, envPrefix string) {
viper.SetEnvPrefix(strings.ToUpper(envPrefix))
viper.AutomaticEnv()
// For backward compatibility, we support access through "_" and through "." for now,
// configuring the actual key delimiter use on the global viper instance is not
// possible.
replacer := strings.NewReplacer(".", "_", "-", "_")
viper.SetEnvKeyReplacer(replacer)
recurseCommands(root, nil)
}
func recurseCommands(root *cobra.Command, segments []string) {
if tracer.Enabled() {
zlog.Debug("re-binding flags", zap.String("cmd", root.Name()), zap.Strings("segments", segments))
defer func() {
zlog.Debug("reboung flags terminated", zap.String("cmd", root.Name()))
}()
}
persistentSegments := append(segments, "global")
root.PersistentFlags().VisitAll(func(f *pflag.Flag) {
rebindFlag("persistent", f, append(persistentSegments, f.Name))
})
root.LocalNonPersistentFlags().VisitAll(func(f *pflag.Flag) {
rebindFlag("local", f, append(segments, f.Name))
})
for _, cmd := range root.Commands() {
recurseCommands(cmd, append(segments, cmd.Name()))
}
}
func rebindFlag(tag string, f *pflag.Flag, segments []string) {
newVarDash := strings.Join(segments, "-")
newVarDot := strings.Join(segments, ".")
addAnnotation(f, ReboundFlagAnnotation, newVarDot)
viper.BindPFlag(newVarDash, f)
viper.BindPFlag(newVarDot, f)
zlog.Debug("binding "+tag+" flag", zap.String("actual", f.Name), zap.String("rebind_to", newVarDot+" (dash accepted)"))
}
func addAnnotation(flag *pflag.Flag, key string, value string) {
if flag.Annotations == nil {
flag.Annotations = map[string][]string{}
}
flag.Annotations[key] = append(flag.Annotations[key], value)
}