Commit graph

74 commits

Author SHA1 Message Date
akutz 0a4a93b685 [110] Default Values Specify Type
This patch adds a feature, if enabled, will infer a value's type from
its default value no matter from where else the value is set. This is
particularly important when working with environment variables. For
example:

    package main

    import (
      "fmt"
      "os"

      "github.com/spf13/viper"
    )

    func print(name string, val interface{}) {
      fmt.Printf("%-15[1]s%-15[2]T%[2]v\n", name, val)
    }

    func main() {
      viper.BindEnv("mykey", "MYPREFIX_MYKEY")
      viper.SetDefault("mykey", []string{})
      os.Setenv("MYPREFIX_MYKEY", "a b c")

      v1 := viper.GetStringSlice("mykey")
      v2 := viper.Get("mykey")

      print("v1", v1)
      print("v2", v2)
    }

When this program is executed the following is emitted:

    [0]akutz@pax:ex$ ./ex1
    v1             []string       [a b c]
    v2             string         a b c
    [0]akutz@pax:ex$

You may wonder, why is this important? Just use the GetStringSlice
function. Well, it *becomes* important when dealing with marshaling.
If we update the above program to this:

    package main

    import (
      "fmt"
      "os"

      "github.com/spf13/viper"
    )

    type Data struct {
      MyKey []string
    }

    func print(name string, val interface{}) {
      fmt.Printf("%-15[1]s%-15[2]T%[2]v\n", name, val)
    }

    func main() {
      viper.BindEnv("mykey", "MYPREFIX_MYKEY")
      viper.SetDefault("mykey", []string{})
      os.Setenv("MYPREFIX_MYKEY", "a b c")

      v1 := viper.GetStringSlice("mykey")
      v2 := viper.Get("mykey")

      print("v1", v1)
      print("v2", v2)

      d := &Data{}
      viper.Marshal(d)
      print("d.MyKey", d.MyKey)
    }

Now we can see the issue when we execute the updated program:

    [0]akutz@pax:ex$ ./ex2
    v1             []string       [a b c]
    v2             string         a b c
    d.MyKey        []string       []
    [0]akutz@pax:ex$

The marshalled data structure's field MyKey is empty when in fact it
should have a string slice equal to, in value, []string {"a", "b",
"c"}.

The problem is that viper's Marshal function calls AllSettings which
ultimately uses the Get function. The Get function does try to infer
the value's type, but it does so using the type of the value retrieved
using this logic:

    Get has the behavior of returning the value associated with the
    first place from where it is set. Viper will check in the
    following order:

      * override
      * flag
      * env
      * config file
      * key/value store
      * default

While the above order is the one we want when retrieving the values,
this patch enables users to decide if it's the order they want to be
used when inferring a value's type. To that end the function
SetTypeByDefaultValue is introduced. When SetTypeByDefaultValue(true)
is called, a call to the Get function will now first check a key's
default value, if set, when inferring a value's type. This is
demonstrated using a modified version of the same program above:

    package main

    import (
      "fmt"
      "os"

      "github.com/spf13/viper"
    )

    type Data struct {
      MyKey []string
    }

    func print(name string, val interface{}) {
      fmt.Printf("%-15[1]s%-15[2]T%[2]v\n", name, val)
    }

    func main() {
      viper.BindEnv("mykey", "MYPREFIX_MYKEY")
      viper.SetDefault("mykey", []string{})
      os.Setenv("MYPREFIX_MYKEY", "a b c")

      v1 := viper.GetStringSlice("mykey")
      v2 := viper.Get("mykey")

      print("v1", v1)
      print("v2", v2)

      d1 := &Data{}
      viper.Marshal(d1)
      print("d1.MyKey", d1.MyKey)

      viper.SetTypeByDefaultValue(true)

      d2 := &Data{}
      viper.Marshal(d2)
      print("d2.MyKey", d2.MyKey)
    }

Now the following is emitted:

    [0]akutz@pax:ex$ ./ex3
    v1             []string       [a b c]
    v2             string         a b c
    d1.MyKey       []string       []
    d2.MyKey       []string       [a b c]
    [0]akutz@pax:ex$
2015-09-08 08:23:06 -04:00
jackspirou 3c0ff861e3 running tests again 2015-08-26 08:50:40 -04:00
jackspirou 09ba0a6954 fixing second slice type needed 2015-08-26 08:50:40 -04:00
jackspirou d028fd65ba changing import statements back 2015-08-26 08:50:40 -04:00
jackspirou cc1c9a82a5 typo: slice type needed 2015-08-26 08:50:40 -04:00
jackspirou 0a12778a8c using my own version of github.com/spf13/cast for now 2015-08-26 08:50:40 -04:00
jackspirou b9316c3299 adding GetStringMapStringSlice method 2015-08-26 08:50:40 -04:00
Vlad Didenko 9fca10189b Fixed #73 2015-08-17 00:11:40 -05:00
Vlad Didenko fa137328f6 Fixed #68 2015-08-17 00:09:59 -05:00
Vlad Didenko f14e1baa25 Fixes #83 2015-07-30 10:35:06 -07:00
Kiril Zvezdarov db7ff930a1 AddSecureRemoteProvider adds the secret keyring to the default provider struct 2015-06-21 19:19:00 -04:00
Kiril Zvezdarov 8e930a9714 Revert "The AddSecureRemoteProvider function didn't add secretKeyring to the remoteProvider struct."
This reverts commit ca00a9b4f7.
2015-06-21 19:13:01 -04:00
chalupaul ca00a9b4f7 The AddSecureRemoteProvider function didn't add secretKeyring to the remoteProvider struct. 2015-06-21 19:09:06 -04:00
Dotan Nahum 28ada1e5b0 Nested keys properly recurse on map[interface{}]interface{} 2015-06-21 18:51:43 -04:00
bep be5ff3e484 Make the remote features optional 2015-05-30 21:28:45 +02:00
Kiril Zvezdarov 79ee5adf46 Removed CWD from default search path 2015-05-22 17:19:48 -04:00
oliveagle f3482afcd0 replace bytes.Buffer with io.Reader 2015-05-19 10:07:21 -04:00
oliveagle 4aa8f94511 clean a little: added watch and ReadBufConf 2015-05-19 10:07:21 -04:00
oliveagle 3492885e84 ReadBufConfig 2015-05-19 10:07:21 -04:00
Kiril Zvezdarov b22fa2b439 Reordered the debug dump of configs to print them in order of precedence 2015-05-01 22:52:16 -04:00
Kiril Zvezdarov c174e2427c Added accessing deep keys by recursive hierarchical search 2015-05-01 22:52:16 -04:00
Kiril Zvezdarov 54e585af54 Clean config register before reading in from file in order to avoid stale values 2015-04-26 15:08:10 -04:00
Wayne Walker ba3382dd23 59 - add properties file support to viper 2015-04-14 13:15:02 -05:00
Kiril Zvezdarov 40762f7541 Current working directory is added to the config search paths by default 2015-04-02 17:07:32 -04:00
Kiril Zvezdarov c861bdefb7 Set default values when binding the whole flagset 2015-04-02 17:04:19 -04:00
Kiril Zvezdarov 19ed496472 Added the pflags register to the debug output 2015-04-02 17:04:19 -04:00
Kiril Zvezdarov 24dd877ad7 Added BindPFlags function which binds all flags in a given flag set to the pflags register 2015-04-02 17:04:19 -04:00
Kiril Zvezdarov 9a0a6692b7 Added docstrings to all exported functions 2015-04-01 21:00:19 -04:00
Kiril Zvezdarov 2e2f3b2643 Marshal now gets the map via the AllSettings method
Conflicts:
	viper.go
2015-03-12 22:33:19 -04:00
Kiril Zvezdarov 700eefa74b Exported the Viper type in order to better support multiple Vipers
Conflicts:
	viper.go
2015-03-12 22:27:14 -04:00
Daniel Eloff e133904c4f Add GetSizeInBytes.
Useful to parse strings like 1GB or 12 mb into an unsigned integer number of bytes.
2015-03-12 22:19:13 -04:00
Anthony Fok 5b0b926e3d :%s/insensativiseMap/insensitiviseMap/g 2015-03-07 04:04:19 -07:00
Anthony Fok 8b99f53550 Avoid searching for config file in executable's path
Viper should not be searching for config.{json,toml,yaml,yml}
in the directory where the `hugo` executable binary is located,
i.e. do not try to look for e.g. $GOPATH/bin/config.toml or
/usr/local/bin/config.toml
2015-03-07 04:01:22 -07:00
Chance Zibolski 03fb74b5d7 Support rewriting env keys 2015-03-06 11:21:17 -08:00
Chance Zibolski ededa04e0b Add viper.GetDuration 2015-03-06 10:11:47 -08:00
Ross Cooperman 90734830d1 Move viper.Reset() back to the public interface
It is helpful for applications that use viper to be able to
reset their configurations between test runs.
2015-02-24 11:54:15 -05:00
spf13 d8f2aa78d4 More intelligent AutomaticEnv behavior and updated documentation. 2014-12-22 22:55:07 -05:00
spf13 1022d75c73 Adding Support for Environment variable prefixes 2014-12-22 18:31:11 -05:00
kgv 2909239689 Change from Get(key) to v.Get(key) in GetXXX(key string) and MarshalKey(key string, rawVal interface{}) functions. 2014-12-09 08:29:33 -05:00
spf13 91b076eec5 MarshallReader -> marshalReader 2014-12-06 09:48:28 +01:00
spf13 18a87c05c6 Adding documentation inline. Moving Reset() to viper_test.go 2014-12-05 17:04:40 +01:00
spf13 29f1858f87 Viper now supports multiple vipers. No API changes. 2014-12-05 03:55:51 +01:00
Andrew Cohen 5aa1437cf3 Fix missed path->filepath renaming
This fixes https://github.com/spf13/viper/issues/24

Caused by https://github.com/spf13/viper/pull/20
2014-11-13 16:23:17 -05:00
Steve Francia 64816e4860 Merge pull request #21 from cudevmaxwell/typo
Fixed typo
2014-11-12 16:54:00 -05:00
Kevin Bowrin 6c340f2886 Fixed typo 2014-11-07 18:14:27 +00:00
Joel Scoble 22f85e27c4 update to consistently use filepath instead of path and add looking in os.Getwd() for the config file to fix finding the config file in Windows issue 2014-11-05 18:23:02 -06:00
Brian Ketelsen 0562ef4c8b merge upstream/master 2014-10-28 22:09:30 -04:00
Brian Ketelsen 563f4d44c4 add support for consul 2014-10-27 21:14:46 -04:00
Brian Ketelsen 5e1d5e7207 removing some debugging printlns 2014-10-27 12:21:03 -04:00
Brian Ketelsen ea04102003 Actually return the kvstore retrieved from the kv server 2014-10-27 11:06:20 -04:00