Commit Graph

163 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 80ab6657f9 Copy and insensitivise maps in Set
Fixes #261
Closes #265
2016-10-24 21:20:41 +02:00
Benoît Masson 285f151019 Fixed AllKeys() to include env values added with BindEnv()
* Fixed: values bound with BindEnv added to AllKeys()

Cast was not working, and v.env wasn't used when merging keys.

Rewrote explicit and specific casts for maps storing strings or FlagValues.

* Added: test for BindEnv() and AllKeys()

To make sure AllSettings() and Unmarshal() will consider environment
variables added with BindEnv().
2016-10-23 23:04:21 +02:00
Benoît Masson 50515b700e Increase performance of nested keys search
* Fixed: insensitiviseMaps and tests

All keys (even nested ones) are now lower-cased recursively.

On the way, map[interface{}]interface{} are cast to map[string]interface{}

* Changed: simplified find() fast path and increase performance

Removed searchMapForKey(), fast path directly integrated into searchMap() and
searchMapWithPathPrefixes()
=> more generic (searchMapForKey() wasn't called everywhere it should have)

At the same time, significantly speed up searchMap() and searchMapWithPathPrefixes(),
which are still used for nested keys: the assumption that map keys are all
lower-cased allows to perform
    val = m[key]
instead of
    for k, v := range m {
      if strings.ToLower(k) == strings.ToLower(key) {
        val = v
      }
    }
=> i.e., directly access the map instead of enumerate the keys
2016-10-14 11:24:45 +02:00
Jonathan Anderson 44208030b3 Allow errors to propagate from getConfigFile(). (#161)
- propagate ConfigFileNotFoundError instead of using unsupported config type error when config file is not found
2016-10-13 13:33:30 +02:00
Bjørn Erik Pedersen 51f23d1f1c Restore performance for the simple case
```
BenchmarkGetBool-4            1021          481           -52.89%
BenchmarkGet-4                879           403           -54.15%
BenchmarkGetBoolFromMap-4     6.56          6.40          -2.44%

benchmark                     old allocs     new allocs     delta
BenchmarkGetBool-4            6              4              -33.33%
BenchmarkGet-4                6              4              -33.33%
BenchmarkGetBoolFromMap-4     0              0              +0.00%

benchmark                     old bytes     new bytes     delta
BenchmarkGetBool-4            113           49            -56.64%
BenchmarkGet-4                112           48            -57.14%
BenchmarkGetBoolFromMap-4     0             0             +0.00%
```

Fixes #249
Fixes https://github.com/spf13/hugo/issues/2536
2016-10-10 13:40:38 +02:00
Benoît Masson ec4eb2fa85 Nested maps (#195)
Fixes #71, #93, #158, #168, #209, #141, #160, #162, #190

* Fixed: indentation in comment
* Fixed: Get() returns nil when nested element not found
* Fixed: insensitiviseMaps() made recursive so that nested keys are lowercased
* Fixed: order of expected<=>actual in assert.Equal() statements
* Fixed: find() looks into "overrides" first
* Fixed: TestBindPFlags() to use a new Viper instance
* Fixed: removed extra aliases from display in Debug()
* Added: test for checking precedence of dot-containing keys.
* Fixed: Set() and SetDefault() insert nested values
* Added: tests for overriding nested values
* Changed: AllKeys() includes all keys / AllSettings() includes overridden nested values
* Added: test for shadowed nested key
* Fixed: properties parsing generates nested maps
* Fixed: Get() and IsSet() work correctly on nested values
* Changed: modifier README.md to reflect changes
2016-10-08 10:00:18 +02:00
Cameron Moore 670c42a85b Check for nil in viper.Sub
Fixes #191
2016-10-06 01:22:39 +02:00
Bjørn Erik Pedersen 382f87b929 Remove expensive TRACE logging
Also avoid doing a strings.Split in the Get common case.

Any TRACE statements in these hot paths must be totally turned off when not testing.

```
benchmark                     old ns/op     new ns/op     delta
BenchmarkGetBool-4            4090          409           -90.00%
BenchmarkGetBoolFromMap-4     6.33          6.28          -0.79%

benchmark                     old allocs     new allocs     delta
BenchmarkGetBool-4            6              3              -50.00%
BenchmarkGetBoolFromMap-4     0              0              +0.00%

benchmark                     old bytes     new bytes     delta
BenchmarkGetBool-4            129           33            -74.42%
BenchmarkGetBoolFromMap-4     0             0             +0.00%
```

Fixes #242
2016-09-26 17:04:02 +02:00
Yauhen Lazurkin e26d6aedc1 Support time.Duration in viper.Unmarshal (#205)
* Fixes #105
2016-09-24 01:20:44 +02:00
Cameron Moore ed0a9674c6 Fix retrieval of pflag stringSlice (#240)
Fixes #112
Changes some logging directives to use Printf
2016-09-22 20:19:24 +02:00
Albert a78f70b5b9 Small refactorings (#230)
* Fix typo in description of UnmarshalExact
* Omit 2nd values from range loops
* Delete findCWD method from util (was unused)
* Edit documentation according to golint
* Fix documentation in util
* Use RemoteProvider interface instead of defaultRemoteProvider
* Fix err variable in BindFlagValues
2016-09-20 10:17:41 +02:00
Max Wolter 2f6a41490b Prevent shadowning of keys when a nested key's value is nil. 2016-09-19 19:37:56 +02:00
Bjørn Erik Pedersen 346299ea79 Add getter for global Viper 2016-08-06 18:06:49 +02:00
Bjørn Erik Pedersen a59dcccc82 Move the Afero fs to the Viper type
And make a exported setter for it.
2016-08-05 09:45:58 +02:00
Albert d0c2644870 Add dot in BindPFlag comment 2016-08-05 09:25:24 +02:00
Matthieu Grieger 4cf0bd2789 Add support for Afero filesystems 2016-08-05 09:24:49 +02:00
Roland Schilter 5619c0edbe Reset cache on config name change
I stumbled over this when trying to merge multiple configs.

```
viper.SetConfigName("default")
err := viper.MergeInConfig()
```
which caches file path resolvemenet in `v.configFile`

and then
```
viper.SetConfigName("prod")
err := viper.MergeInConfig()
```

which reuses `v.configFile` without updating it accordingly to the new name.

See c1ccc378a0/viper.go (L1240)
2016-08-05 09:18:19 +02:00
Chuanjian Wang 64dc6f6810 Add GetInt64 2016-08-05 09:16:55 +02:00
Bjørn Erik Pedersen a0cdbddebd Remove kr/pretty dependency
See https://github.com/spf13/hugo/issues/2124
See https://github.com/kr/text/issues/6
2016-05-08 13:12:02 +02:00
Anthony Fok 8e57fea7a8 Update import path of fsnotify
Rename "gopkg.in/fsnotify.v1" to "github.com/fsnotify/fsnotify"
per upstream recommendation.

See https://github.com/fsnotify/fsnotify/issues/108 for rationale.
2016-04-20 21:51:22 +08:00
Tony Narlock 45b73b72ad Fix typo 2016-04-20 21:43:24 +08:00
dsp c975dc1b4e implementing a weak decode wrapper called UnmarshalExact that errors on non existant fields in the destination struct 2016-02-09 16:07:50 -07:00
Marcin Stanisławski e072d51737 use aliases in all keys list to enable proper Unmarshaling 2016-02-08 15:52:20 -05:00
Bjørn Erik Pedersen a212099cbe Watch the entire config dir for changes
Then checking the file name in the event handler. This seems to be the only robust way
of handling changes from a single file on multiple platforms and editors.

See #142
2016-01-11 16:07:23 +01:00
Bjørn Erik Pedersen cc70319ebc Fix config watch
* Only add *the* config file, not all possible folders
* Trigger reload on both write and create events;
  the latter is what we get from atomic save editors (like TextMate) once https://github.com/go-fsnotify/fsnotify/pull/111 is merged

See #142
2016-01-11 13:34:45 +01:00
Lei Feng 0c82789feb Handle the case Get() returns either map[interface{}]interface{} or map[string]interface{} 2015-12-26 09:08:49 +08:00
akutz 110492b300 Bugfix for Nested Key Casing
This patch fixes a bug with how Viper handle's key casing when keys are
nested. While Viper is generally case-insensitive, this was not the case
with regards to nested keys. This patch makes nested keys insensitive as
well.
2015-12-24 10:25:30 -05:00
akutz 991d18afb2 Adds MergeConfig functionality
This patch adds the `MergeConfig` and `MergeInConfig` functions to
enable reading new configuration files via a merge strategy rather
than replace. For example, take the following as the base YAML for a
configuration:

    hello:
        pop: 37890
        world:
        - us
        - uk
        - fr
        - de

Now imagine we want to read the following, new configuration data:

    hello:
        pop: 45000
        universe:
        - mw
        - ad
    fu: bar

Using the standard `ReadConfig` function the value returned by the
nested key `hello.world` would no longer be present after the second
configuration is read. This is because the `ReadConfig` function and
its relatives replace nested structures entirely.

The new `MergeConfig` function would produce the following config
after the second YAML snippet was merged with the first:

    hello:
        pop: 45000
        world:
        - us
        - uk
        - fr
        - de
        universe:
        - mw
        - ad
    fu: bar

Examples showing how this works can be found in the two unit tests
named `TestMergeConfig` and `TestMergeConfigNoMerge`.
2015-12-24 10:24:07 -05:00
David Calavera 66249a6550 Add FlagValue interface to support other flag systems.
Using an interface allows people to use their favourite flag system
with viper without being restricted to the semantics of pflag or the
standard library.

This change introduce two new functions `BindFlagValues` and
`BindFlagValue` that behave like `BindFlags` and `BindFlag` but using
the new interface as values.

This change also introduces two internal structures to transform
`*pflag.FlagSet` and `*pflag.Flag` into the new interface. This way,
viper keeps working as expected for people that are currently using the
pflag package without breaking backwards compatibility.

Signed-off-by: David Calavera <david.calavera@gmail.com>
2015-12-24 10:16:41 -05:00
Lei Feng 105e3d0d19 Add Sub() for Viper, which returns a branch of a Viper instance. 2015-12-24 22:44:14 +08:00
patdhlk 606a4f3933 add support for hcl 2015-12-15 14:44:21 -05:00
HuKeping 87d443c19b Fix tab issue.
As the title said.
2015-12-15 12:54:05 -05:00
akutz e3bc06f20c Refactored IsSet to examine keys
This patch refactors the IsSet function to examine the keys in order
to see if a key is set instead of simply checking if a value is nil.
This change is necessary due to the fact that default values via
flag bindings will result in the old logic always being true for
the IsSet function due to a type's default value such as 0 for an
integer or an empty string for a string. While a type's default
value may be preferable when getting the value for a key, it
results in a false positive when determining if a key is actually
set. This change enables users to detect whether a key is set by
only returning a flag's value if it has changed.
2015-12-11 16:17:57 -05:00
Jonathan Boulle ce08532bfd Correct "etcd" naming
The project should always be referred to in lowercase.
2015-12-11 16:14:08 -05:00
akutz c25387f10d AllKeys() now includes bound flag and env var keys
This patch fixes a bug where the function `AllKeys()` did not include
the keys for bound flags and environment variables.
2015-11-12 14:28:38 -06:00
spf13 e37b56e207 Add dynamic reading of config file support 2015-11-09 23:22:04 -05:00
akutz c374c6d0a9 Flag Binding Refactor
This patch alters the way flags are handled to coincide with the
documentation on the Viper README. The documentation indicated that flag
bindings were late, when in fact they were very, very early. This patch
changes flag bindings to behave as late bindings.
2015-11-09 19:24:13 -05:00
James Sweet 87b94ba486 Fixed #115: Added code in the find method to search for nested configuration parameters 2015-11-04 19:35:10 -05:00
Matt Surabian 1967d93db7 Fixed #36: Changed Marshal to Unmarshal throughout. 2015-09-08 08:24:57 -04:00
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
Brian Ketelsen d2d8f6caa1 added error for remote configuration not found 2014-10-27 11:03:11 -04:00
Brian Ketelsen c33e690687 add readremoteconfig for cases when there are no local configuration files 2014-10-27 10:14:45 -04:00
Brian Ketelsen f8939d9229 existing tests pass 2014-10-26 09:48:21 -04:00
Brian Ketelsen a28bee1fba adding preliminary etcd support 2014-10-26 09:42:03 -04:00
Brian Ketelsen 3d8182460c work in progress 2014-10-24 15:38:01 -04:00
Chris Hamant 1b8adf4854 fixing problem with case sensitivity with keys in env and flags maps 2014-10-09 16:39:24 -04:00
spf13 83fd92627c Adding automatic reading from ENV w/tests 2014-09-27 14:05:01 -07:00
spf13 aacc3049e2 Adding AllKeys and AllSettings functions and tests 2014-09-27 14:05:01 -07:00
spf13 181a3b5f3b Adding support for ENV variables 2014-09-27 14:04:50 -07:00
David Pelaez d56c59c66a Included .yml as supported extension.
Hi. Thanks for creating Viper, it's been very useful to me. I come from Ruby and .yaml is really never used there, .yml is the common extension. I verified online and it's valid known extension for Yaml files so I added it. I realized this when trying to use `config.yml` in a project and getting an error on my code. Does adding this makes sense? Pretty silly addition, but it did confuse me for a while to realize the error using my app on a server, so I think it's worth adding. Cheers.
2014-09-08 12:03:29 -04:00
Nate Finch 2b24bea958 fix issue #8
This fixes the aliases in config files bug.  Whenever we register an alias, if there is a value in
the config (or defaults or override) for the alias, we move that value to the new "real key".

Added a test for the bug, which fails without the changes and passes with the changes.

This also fixes a bug in Hugo, where specifying "Taxonomies" in your config file doesn't get recognized,
because Hugo aliases "Taxonomies" to "Indexes" which means that when the code does a Get("Taxnomies") it
got translated to Get("Indexes"), which didn't exist in the original config map.
2014-08-06 00:27:39 -04:00