-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmermaid.go
134 lines (120 loc) · 3.05 KB
/
mermaid.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
package mermaid
import (
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/dig"
"strings"
)
// Mermaid .
type Mermaid struct {
Container *dig.Container
CMD *cobra.Command
Config *viper.Viper
Logger *log.Logger
ENVPrefix string
}
// NewMermaid return new mermaid worker.
func NewMermaid(
cmd *cobra.Command,
config *viper.Viper,
logger *log.Logger,
envPrefix string,
) (*Mermaid, error) {
worker := Mermaid{
Container: dig.New(),
CMD: cmd,
Config: config,
Logger: logger,
ENVPrefix: envPrefix,
}
if err := worker.Bind(); err != nil {
return nil, err
}
return &worker, nil
}
// Run .
func Run(cmd *cobra.Command, runable interface{}, initializers ...interface{}) error {
mermaid, err := NewMermaid(
cmd,
viper.New(),
NewLogger(),
cmd.Use,
)
if err != nil {
return err
}
return mermaid.Execute(runable, initializers...)
}
// Execute .
func (m *Mermaid) Execute(runable interface{}, initializers ...interface{}) error {
container := m.Container
// Provide config && logger by default.
initializers = append(initializers, func() *viper.Viper { return m.Config })
initializers = append(initializers, func() *log.Logger { return m.Logger })
for _, initFn := range initializers {
if err := container.Provide(initFn); err != nil {
m.Logger.Error(err)
return err
}
}
return dig.RootCause(container.Invoke(runable))
}
// Bind .
func (m *Mermaid) Bind() error {
m.BindViper()
if err := BindFlags(m.CMD, m.Config); err != nil {
m.Logger.Error(err)
return err
}
SetLoggerLevel(m.Logger, m.Config)
if err := BindContainer(m.Config, m.Container); err != nil {
m.Logger.Error(err)
return err
}
return nil
}
// BindViper will
// - load config file if exists.
// - load environment with prefix.
// - set default log level field.
func (m *Mermaid) BindViper() {
// Read config from giving file path or filename.yaml.
var cfgFile string
if cfgFlag := m.CMD.Flags().Lookup("config"); cfgFlag != nil {
cfgFile = cfgFlag.Value.String()
}
m.Config.SetDefault("config", cfgFile)
if cfgFile != "" {
m.Config.SetConfigFile(cfgFile)
m.Logger.Infof("Use config %s", cfgFile)
} else {
var cfgName string
if cfgFlag := m.CMD.Flags().Lookup("config_name"); cfgFlag != nil {
cfgName = cfgFlag.Value.String()
}
m.Config.SetDefault("config_name", cfgName)
m.Config.SetConfigName(cfgName)
m.Config.SetConfigType("yaml")
m.Config.AddConfigPath(".")
m.Config.AddConfigPath("/")
m.Config.AddConfigPath("$HOME")
m.Config.AddConfigPath("./config")
if len(cfgName) > 0 {
m.Logger.Infof("Use config name %s", cfgName)
} else {
m.Logger.Infof("Use default config name %s", "config")
}
}
if err := m.Config.ReadInConfig(); err != nil {
m.Logger.Warning(err)
} else {
m.Logger.Infof("Using config file %s", m.Config.ConfigFileUsed())
}
// Load var from env.
m.Config.AutomaticEnv()
m.Config.SetEnvPrefix(m.ENVPrefix)
m.Config.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// Set default log level.
m.Config.SetDefault("log_level", "info")
}