I've been exploring configuration management in Go using the viper package, which I learned about in another question. I'm having trouble understanding how to initialize a new configuration. What I want to do is to find system configurations if they exist, then user configuration, and then, if all else fails, to create (and then use) a new user configuration from defaults. The next time I run the app, I'd expect to find the configuration that I previously created. I'm using it like this:
import (
"fmt"
"github.com/spf13/viper"
"os"
"os/user"
"path/filepath"
)
usr, err := user.Current()
appMode := "test" // or "production" or...
configDir := filepath.Join(usr.HomeDir, ".myapp")
config := viper.New()
config.SetConfigName(appMode)
config.SetConfigType("json")
config.SetDefault("group1.key1", "value1.1")
config.SetDefault("group1.key2", 1234)
config.SetDefault("group2.key1", "value2.1")
config.SetDefault("group2.key2", 5678)
config.AddConfigPath("/usr/share/myapp/config")
config.AddConfigPath("/usr/local/share/myapp/config")
config.AddConfigPath(configDir)
if err := config.ReadInConfig(); err != nil {
filename := filepath(configDir, fmt.Sprintf("%s.json", appMode))
_, err := os.Create(filename)
if err != nil {
panic(fmt.Stringf("Failed to create %s", filename))
}
}
if err := config.ReadInConfig(); err != nil {
panic("Created %s, but Viper failed to read it: %s",
filename, err)
}
At this point, I would like for ~/.myapp/test.json to be created for me with the following:
{
"group1": {
"key1": "value1.1",
"key2": 1234
},
"group2": {
"key1": "value2.1",
"key2": 5678
}
}
The result is that the file is empty, and the second attempt to read the file also fails with the message "open : no such file or directory" even though it exists. If I hand-edit the file, Viper finds it and parses it. Obviously I can create the JSON file programatically, but this seems like such an obvious use case that I must be missing something here.