title: Initializing a new Go configuration with Viper
body: <p>I've been exploring configuration management in Go using the <a href="https://github.com/spf13/viper" rel="nofollow noreferrer">viper package</a>, which I learned about in <a href="https://stackoverflow.com/questions/16465705/how-to-handle-configuration-in-go">another question</a>. 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:</p>
  
  <pre><code>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)
  }
  </code></pre>
  
  <p>At this point, I would like for ~/.myapp/test.json to be created for me with the following:</p>
  
  <pre><code>{
      "group1": {
          "key1": "value1.1",
          "key2": 1234
      },
      "group2": {
          "key1": "value2.1",
          "key2": 5678
      }
  }
  </code></pre>
  
  <p>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.</p>