'Using env variables in YML with default value
I have the following code to read config files from yml which includes ENV variables too:
confContent, err := ioutil.ReadFile("config.yml")
if err != nil {
panic(err)
}
// expand environment variables
confContent = []byte(os.ExpandEnv(string(confContent)))
conf := &SysConfig{}
if err := yaml.Unmarshal(confContent, conf); err != nil {
panic(err)
}
config.yml
db:
name: ${DB_NAME:qm}
host: localhost
It is working but how can I get it to read default values if DB_NAME env is not given?
Solution 1:[1]
I recommend you use the awesome Viper package by spf13) to read conf files, it can solve your problem gracefully and you can use it to load many other type of conf files.
Solve your problem
- Get the package
go get github.com/spf13/viper
- conf file
Supposed you have conf file named db.yaml:
db:
name: somedb
host: localhost
- code example
As we can see, once Viper loads the conf file, we can get values by key. A Yaml file will be parsed as a nested structure which you can unmarshal into a Golang struct, We should use viper.GetString("db.name") to get the value, you can refer to this page to get more usage info.
import (
"fmt"
"github.com/spf13/viper"
)
func InitConf() {
viper.AutomaticEnv() // read system env
viper.SetConfigName("db") // conf file name to be load
viper.AddConfigPath(".") // conf file path
viper.SetDefault("db.name", "mysqldb") // you can set default da name value here
// do read conf file and handle error
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired
} else {
// Config file was found but another error was produced
}
}
fmt.Printf("db.name: %s", viper.GetString("db.name"))
}
viper.AutomaticEnv() this method will read system env automatically, suppose you have an env named ENV_XXX, then you can get it by viper.GetString("ENV_XXX"). If the env name is the same as one of conf file key, viper uses the env first
- when we do not set the
nameindb.yamlthe output will bedb.name: mysqldb - when we set the
namevalue:somedbin db.yaml the output will bedb.name: somedb
Hope you will find it useful! more details on usage see the Viper README file
Solution 2:[2]
I guess you had a struct for your conf like this:
Db *struct{
Name string
Host string
}
so for retrieve the default variable of Dbname, you must check it like this:
if conf.Db == nil || conf.Db.Name == "" {
conf.Db.Name = "test"
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alexis Wilke |
| Solution 2 | ttrasn |
