Commit Graph

683 Commits

Author SHA1 Message Date
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 c8c6312ace Add information about flag interfaces to the readme file.
Signed-off-by: David Calavera <david.calavera@gmail.com>
2015-12-24 10:16:42 -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 79971f1ae7 add HCL support to the README file 2015-12-15 14:44:21 -05:00
patdhlk 8e6f2421dc add test structure for hcl 2015-12-15 14:44:21 -05:00
patdhlk 60e1b5f599 changed the test hcl config 2015-12-15 14:44:21 -05:00
patdhlk 606a4f3933 add support for hcl 2015-12-15 14:44:21 -05:00
Sanjay Bhandari 5c53af5e4f README: describe interworking with flag package 2015-12-15 12:58:30 -05:00
Abhinandan 823bc1371b Document the use of struct tags to map the dissimilar fields. 2015-12-15 12:57:56 -05:00
HuKeping 87d443c19b Fix tab issue.
As the title said.
2015-12-15 12:54:05 -05:00
Steve Francia 90b31f671f Merge pull request #138 from derekparker/fix-typo
readme: Fix typo
2015-12-11 21:21:22 -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
Derek Parker cc3dd557e0 readme: Fix typo 2015-12-03 11:47:09 -08: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
Vlad Didenko a7ef020a9a Clarify CWD search. Fixes #32 2015-11-06 14:50:12 -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
spf13 6a665317fd use docker based travis-ci 2015-11-04 18:15:48 -05:00
James Mintram 3041a43deb Noticed a couple ot typos 2015-11-04 18:06:12 -05:00
David Symonds 493be7d534 Fix import syntax in README.md. 2015-11-04 18:05:20 -05:00
Steve Francia d2f75b4bef Add logo to readme 2015-11-02 11:07:43 -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
jackspirou 2abb1bebfd Readme fixes and small edits 2015-07-30 10:46:19 -07:00
Vlad Didenko f14e1baa25 Fixes #83 2015-07-30 10:35:06 -07:00
Maxime Horcholle 1e6a237e05 Syntax highlighting 2015-07-30 10:28:50 -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
Vlad Didenko 12f7ec6566 Fixes #87 2015-06-21 18:58:48 -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
Bjørn Erik Pedersen d62d4bb4c6 Merge pull request #72 from kzvezdarov/cwd-fix
Removed CWD from default search path
2015-05-22 23:30:46 +02:00
Kiril Zvezdarov 79ee5adf46 Removed CWD from default search path 2015-05-22 17:19:48 -04:00
oliveagle 0d75ecea1c update README.md
[close #66]
2015-05-19 10:07:30 -04:00
oliveagle f3482afcd0 replace bytes.Buffer with io.Reader 2015-05-19 10:07:21 -04:00
oliveagle 2a7f7f40fc add README.md, and fix strings.ToLower(configType) 2015-05-19 10:07:21 -04:00