1
0
Fork 0
mirror of https://github.com/eosswedenorg/thalos synced 2026-06-17 04:30:03 +02:00
thalos/internal/config/builder.go

105 lines
2 KiB
Go

package config
import (
"errors"
"io"
"os"
"github.com/mitchellh/mapstructure"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
// This is a simple module that encapsulate the creation
// of a config object and can override values from cli flags.
type Builder struct {
in io.Reader
flags *pflag.FlagSet
binds map[string]string
}
func NewBuilder() *Builder {
return &Builder{
binds: map[string]string{
"ship.start_block_num": "start-block",
"ship.end_block_num": "end-block",
},
}
}
// Set the config file to read
func (b *Builder) SetConfigFile(filename string) *Builder {
file, _ := os.Open(filename)
return b.SetSource(file)
}
// Set the source to read
func (b *Builder) SetSource(in io.Reader) *Builder {
b.in = in
return b
}
// Set all flags that the builder should use.
func (b *Builder) SetFlags(flags *pflag.FlagSet) *Builder {
b.flags = flags
return b
}
// Add a flag to the builder.
func (b *Builder) AddFlag(flag *pflag.Flag) *Builder {
b.flags.AddFlag(flag)
return b
}
// Build the config object from file, cli-flags
func (b *Builder) Build() (*Config, error) {
if b.in == nil {
return nil, errors.New("Config not set")
}
conf := New()
v := viper.New()
v.SetConfigType("yaml")
if b.flags != nil {
// bind flags in viper.
for key, flagname := range b.binds {
flag := b.flags.Lookup(flagname)
if flag == nil {
continue
}
if err := v.BindPFlag(key, flag); err != nil {
return nil, err
}
}
}
// Read config and unmarshal
if err := v.ReadConfig(b.in); err != nil {
return nil, err
}
decoders := mapstructure.ComposeDecodeHookFunc(
mapstructure.TextUnmarshallerHookFunc(),
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
decodeShorthandShipConfig,
)
err := v.Unmarshal(&conf, viper.DecodeHook(decoders))
if err != nil {
return nil, err
}
// Call custom handler.
if b.flags != nil {
if err := overrideCliFlags(&conf, b.flags); err != nil {
return nil, err
}
}
return &conf, nil
}