Skip to content

Instantly share code, notes, and snippets.

@landaire
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save landaire/0a1efe7738f5defd990f to your computer and use it in GitHub Desktop.
Save landaire/0a1efe7738f5defd990f to your computer and use it in GitHub Desktop.
Revel config rework
diff --git a/config.go b/config.go
index 0bc9da1..7363a69 100644
--- a/config.go
+++ b/config.go
@@ -1,18 +1,27 @@
package revel
import (
+ "encoding/json"
+ "encoding/xml"
"errors"
- "github.com/robfig/config"
+ "fmt"
+ "os"
"path"
"strings"
+
+ "github.com/BurntSushi/toml"
+ "github.com/robfig/config"
+ "gopkg.in/yaml.v2"
)
+type unmarshalFunc func(data []byte, v interface{}) error
+
// This handles the parsing of app.conf
// It has a "preferred" section that is checked first for option queries.
// If the preferred section does not have the option, the DEFAULT section is
// checked fallback.
type MergedConfig struct {
- config *config.Config
+ config map[string]interface{}
section string // Check this section first, then fall back to DEFAULT
}
@@ -20,22 +29,43 @@ func NewEmptyConfig() *MergedConfig {
return &MergedConfig{config.NewDefault(), ""}
}
-func LoadConfig(confName string) (*MergedConfig, error) {
+func LoadConfig() (*map[string]interface{}, error) {
var err error
+
+ unmarhsalers := map[string]unmarshalFunc{
+ "toml": toml.Unmarshal,
+ "yaml": yaml.Unmarshal,
+ "json": json.Unmarshal,
+ "xml": xml.Unmarshal,
+ }
+
for _, confPath := range ConfPaths {
- conf, err := config.ReadDefault(path.Join(confPath, confName))
- if err == nil {
- return &MergedConfig{conf, ""}, nil
+ for extension, unmarshaler := range unmarhsalers {
+ // Check if a config.toml, config.yaml, etc. file exists
+ if _, err := os.Stat(path.Join(confPath, fmt.Sprintf("config.%s", extension))); os.IsNotExist(err) {
+ // Continue the unmarshaler loop here if the config file does not exist
+ // we could easily check to see if the file does exist and plop our code in here, but
+ // nesting four-levels doesn't look too nice
+ continue
+ }
+
+ var conf map[string]interface{}
+ err = unmarshaler(os.Read & conf)
+ conf, err := config.ReadDefault(path.Join(confPath, confName))
+ if err == nil {
+ return &MergedConfig{conf, ""}, nil
+ }
}
}
+
if err == nil {
err = errors.New("not found")
}
return nil, err
}
-func (c *MergedConfig) Raw() *config.Config {
- return c.config
+func (c *MergedConfig) Raw() *map[string]interface{} {
+ return &(c.config)
}
func (c *MergedConfig) SetSection(section string) {
@@ -132,3 +162,24 @@ func stripQuotes(s string) string {
return s
}
+
+func getKey(path string, config *map[string]interface{}) (value interface{}, found bool) {
+ parts := strings.Split(path, ".")
+
+ value, found := config[parts[0]]
+ if !found {
+ return
+ }
+
+ if len(parts) > 1 {
+ path = strings.Join(parts[1:len(parts)])
+
+ // Try casting the value as a map
+ subMap, success := value.(map[string]interface{})
+ if success {
+ return getKey(path, &subMap)
+ }
+ }
+
+ return nil, false
+}
diff --git a/revel.go b/revel.go
index 88cf01a..bd0de6a 100644
--- a/revel.go
+++ b/revel.go
@@ -148,7 +148,7 @@ func Init(mode, importPath, srcPath string) {
// Load app.conf
var err error
- Config, err = LoadConfig("app.conf")
+ Config, err = LoadConfig()
if err != nil || Config == nil {
log.Fatalln("Failed to load app.conf:", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment