From 606a4f39334a643807afd0509ee9650e42ff0a47 Mon Sep 17 00:00:00 2001 From: patdhlk Date: Fri, 11 Dec 2015 23:51:11 +0100 Subject: [PATCH] add support for hcl --- util.go | 10 +++++++++ viper.go | 4 ++-- viper_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/util.go b/util.go index dc60a44..0cc4553 100644 --- a/util.go +++ b/util.go @@ -22,6 +22,7 @@ import ( "unicode" "github.com/BurntSushi/toml" + "github.com/hashicorp/hcl" "github.com/magiconair/properties" "github.com/spf13/cast" jww "github.com/spf13/jwalterweatherman" @@ -144,6 +145,15 @@ func unmarshallConfigReader(in io.Reader, c map[string]interface{}, configType s return ConfigParseError{err} } + case "hcl": + obj, err := hcl.Parse(string(buf.Bytes())) + if err != nil { + return ConfigParseError{err} + } + if err = hcl.DecodeObject(&c, obj); err != nil { + return ConfigParseError{err} + } + case "toml": if _, err := toml.Decode(buf.String(), &c); err != nil { return ConfigParseError{err} diff --git a/viper.go b/viper.go index 6e166ba..6f204b1 100644 --- a/viper.go +++ b/viper.go @@ -179,7 +179,7 @@ func New() *Viper { // can use it in their testing as well. func Reset() { v = New() - SupportedExts = []string{"json", "toml", "yaml", "yml"} + SupportedExts = []string{"json", "toml", "yaml", "yml", "hcl"} SupportedRemoteProviders = []string{"etcd", "consul"} } @@ -218,7 +218,7 @@ type RemoteProvider interface { } // Universally supported extensions. -var SupportedExts []string = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop"} +var SupportedExts []string = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl"} // Universally supported remote providers. var SupportedRemoteProviders []string = []string{"etcd", "consul"} diff --git a/viper_test.go b/viper_test.go index aa62235..9f365a8 100644 --- a/viper_test.go +++ b/viper_test.go @@ -60,6 +60,24 @@ var jsonExample = []byte(`{ } }`) +var hclExample = []byte(` +id = "0001" +type = "donut" +name = "Cake" +ppu = 0.55 +batter { + type = "Regular" +} +batter { + type = "Chocolate" +} +batter { + type = "Blueberry" +} +batter { + type = "Devil's Food" +}`) + var propertiesExample = []byte(` p_id: 0001 p_type: donut @@ -95,6 +113,10 @@ func initConfigs() { SetConfigType("json") remote := bytes.NewReader(remoteExample) unmarshalReader(remote, v.kvstore) + + SetConfigType("hcl") + r = bytes.NewReader(hclExample) + unmarshalReader(r, v.config) } func initYAML() { @@ -129,6 +151,14 @@ func initTOML() { unmarshalReader(r, v.config) } +func initHcl() { + Reset() + SetConfigType("hcl") + r := bytes.NewReader(hclExample) + + unmarshalReader(r, v.config) +} + // make directories for testing func initDirs(t *testing.T) (string, string, func()) { @@ -270,6 +300,36 @@ func TestTOML(t *testing.T) { assert.Equal(t, "TOML Example", Get("title")) } +func TestHCL(t *testing.T) { + initHcl() + assert.Equal(t, "0001", Get("id")) + assert.Equal(t, 0.55, Get("ppu")) + assert.Equal(t, "donut", Get("type")) + assert.Equal(t, "Cake", Get("name")) + Set("id", "0002") + assert.Equal(t, "0002", Get("id")) + assert.NotEqual(t, "cronut", Get("type")) +} + +func TestHCLList(t *testing.T) { + initHcl() + batters := []map[string]interface{}{ + map[string]interface{}{ + "type": "Regular", + }, + map[string]interface{}{ + "type": "Chocolate", + }, + map[string]interface{}{ + "type": "Blueberry", + }, + map[string]interface{}{ + "type": "Devil's Food", + }, + } + assert.Equal(t, batters, Get("batter")) +} + func TestRemotePrecedence(t *testing.T) { initJSON()