When merging a key where the target value is nil, the type of the target
and source do not match. What currently happens is an error is logged
and the key is skipped.
I have changed it so that it does the same thing as when the target key
is missing: copy the source value to the target.
Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
* Added support for accessing slices
* Processed PR feedback
- renamed searchMapWithPathPrefixes to searchIndexableWithPathPrefixes
- moved source type specific search logic to speparate functions
- Inverted if statments to avoid the arrow pattern
* Quickly return from searchSliceWithPathPrefixes and searchMapWithPathPrefixes functions without intermediate variables
This change modifies BindEnv to permit a list of environment variable
names in order to support multiple env. vars. for the same config key.
When this form is used, env. keys take precedence in the written order.
Closes#971
* add parsing for stringToString flags
* add logic to return flags default if not val set, add a test
* extract parsing into single func
* add a few more cases
* return nil if unable to parse instead of panicing
* return map[string]interface in order to work with cast.ToStringMap
* mostly copy pflags implementation of the conversion to a stringtostring
* Add support to save file with no extension
The support introduced for files with no file extension is only partial as trying to save the config file would fail with `<file name> requires valid extension`
This adds support to saving such files
* Only consider files without extension if the config type is explicitly specified
* Hides unused variable in test
* First check for config type then for file without extension
Default value should be looked for by Get(), but not by IsSet().
This logic should remain inside find(), to make sure that shadowing
of keys is handled properly.
Fixes Issue #276.
If the config file does not exist and the force flag is not set,
OpenFile would not use O_CREATE flag, causing viper to fail with
error "File not exist" and to not create the config file.
This patch changes the behavior of writeConfig() so that if force is set
to false, OpenFile will use O_EXCL flag, thus failing if the file
already exists or creating a new file otherwise.
Signed-off-by: Rodrigo Chiossi <rodrigo.chiossi@intel.com>
Defering can cause trouble because we're writing to the file outside the function
where the defering is registered, calling f.Sync() ensures that bytes are flushed
to disk even is Close() is called too soon.
* Added a new `DecoderConfigOption` type allowing the user to write custom
functions that can override the default mapstructure.DecoderConfig
settings
* Added a new `DecodeHook` function which returns
a `DecoderConfigOption`. This allows the user to easily set their own
Decode hooks when Unmarshaling
* Updated Unmarshal, UnmarshalKey and defaultDecoderConfig to support variadic
trailing `DecoderConfigOption` functions to allow for customisation of
the default mapstructure.DecoderConfig
* Added a test case with example usage
Support override of symlink to config file
Include tests for WatchConfig of regular files, as well
as config file which links to a folder which is itself a
link to another folder in the same "watch dir" (the way
Kubernetes exposes config files from ConfigMaps mounted
on a volume in a Pod)
Also:
- Add synchronization with WaitGroup to ensure that the WatchConfig
is properly started before returning
- Remove the watcher when the Config file is removed.
Fixes#284
Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
* Added method to write into TOML file.
* Added functionality to export configuration based on config type. The feature supports JSON and TOML.
* Added method to write into YAML file.
* Fixed the issue of incorrect defer and error checking order. The error checking must be first otherwise it will cause panic.
* Add WriteConfig methods
* Add support for toml
* Add shared write function and safe methods
* Fix incorrectly modified imports
* Remove extra comments
* Fix spelling
* Make marshal spelling consistent throughout
* Add support for remaining configuration types
This commit moves a significant portion of the code back to viper.go to
facilitate having access to the object when reading the files. The purpose is to
add properties to the viper object at read time, so that we can add the comments
back to the file when writing.
* Add tests for each written file type
* Modify test for updated HCL specification
* Modify to only support HCL write in Go 1.7
* Revert "Modify to only support HCL write in Go 1.7"
This reverts commit 12b34bc4eb92cbf8ebfd56b79519f448607e3e51.
* Need to truncate the file before writing
* Write all settings including overrides
* Use filename variable
* Lint remote.go
* Fix toml return count error
If the user creates a invalid config file while watching for config
changes, the previous, valid config is not retained. This commit only
overwrites the running config if unmarshalling was successful.
* 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().
* 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
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
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