Build Status Code quality Code coverage
A simple yet powerful configuration package.
On any project I've made personnally or for a company, except if the project was really (really) small, I always needed at some point to be able to configure a component in the project (the http listening port, the database credentials, a business configuration, ...). I've been using viper for some times now, but I was not really happy about it for some reasons (usage of strings keys to get configuration, globally defined configuration which are a p.i.t.a. in big project to understand what's used where, and to concurently use and modify in test, ...). I also used confita from which this project was inspired.
From my point of view a configuration package should:
- have a priorization of "sources" (for example file < env < cli args)
- be strongly typed (it should never use string keys to get a value, or return interface{} left for the call to cast)
- be modulable (add a new "source" to retrieve configuration from vauld or consul for example)
- handle defaults values (without string keys, and as close as the configuration definition)
- have a clear and easy to use API
- be light
- encourage and follow the best practices
That's what I tried to do in this configuration package which is made of 4 components:
- the default setter which handles defaults
- the sources (anything that implements one of the two sources interfaces) responsible for the retrieval of the configuration
- the "loader" which is responsible to set the
defaultif any and to call eachsources - additionally, a validation can be made to make sure configuration is valid
// let's define a structure that hold our http configuration, for example type HTTPConfig struct { Debug bool ListenAddress string RequestTimeout time.Duration MACSecret []byte } // SetDefault sets sane default for http config. func (c *HTTPConfig) SetDefault() { c.ListenAddress = ":8080" c.RequestTimeout = 3 * time.Second } // Validate checks whenever the config is properly set. func (c *HTTPConfig) Validate() error { if c.RequestTimeout < time.Second { return errors.New("request timeout is too short (min 1s)") } } func main() { // export PREFIX_DEBUG="true" // export PREFIX_MACSECRET="secret" // echo "{ "listen-address": ":8082" }" > ./conf.json var cfg HTTPConfig if err := config.Load(&cfg, config.WithSources(config.Source{ sourcefile.New("./conf.json"), sourceenv.New("prefix"), })); err != nil { panic(err) } if err := config.Validate(&cfg); err != nil { panic(err) } // cfg.Debug = "true" // cfg.ListenAddress = ":8082" // cfg.RequestTimeout = "3s" // cfg.MACSecret = "secret" }
More doc and examples in the config's godoc
This project is under the MIT licence, please see the LICENCE file.