Open alfa-alex opened 2 months ago
š Thanks for reporting!
A maintainer will take a look at your issue shortly. š
In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.
ā° If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9
š£ If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:
https://twitter.com/sagikazarmark/status/1306904078967074816
Thank you! ā¤ļø
Thanks for the detailed report @alfa-alex!
It seems to me that you are right in your analysis of why it doesn't work properly.
I think we are hitting an edge case here where by default structs are translated to map[string]interface{}
.
One thing I would try is implementing a decode hook in the opposite direction: convert the struct into string. (No need to check the target in that case since it's just interface
)
I realize it may not be an elegant long-term solution, but it may uncover why it isn't working.
Preflight Checklist
Viper Version
master
Go Version
1.22
Config Source
Environment variables
Format
No response
Repl.it link
No response
Code reproducing the issue
Expected Behavior
I would expect the custom definition of a type like
CustomTypeWithUnexportedField
in the example to be decodeable with environment variables alone when theBindStruct
feature flag is turned on (orv1.18.1
is used, for simplicity).Actual Behavior
The decoding of the field only succeeds if I specify a default manually (like in the example) or load the value at least once from some config file (e.g. JSON). In other words, the recent fix to AutomaticEnv() doesn't work in this case.
Steps To Reproduce
BindStruct
feature flag.Additional Information
I noticed that in the scenario without any other config file / default etc. (i.e., the scenario that https://github.com/spf13/viper/pull/1429 was supposed to solve), the
structKeyMap
passed to flattenAndMergeMap still contains the value, but it is removed during that call.The
decodeStructKeys
cannot properly use the custom decoder hook function (customTypeHook()
in the example here) because the target type is amap[string]interface{}
here, not astring
(the latter is the case when viper does the decoding for the defaults / config files etc.).I'm not sure whether we're hitting a limitation of
mapstructure
here or ofviper
and how hard it would be to fix this. In any case, it's unexpected because theBindStruct
feature suggests that the behavior with additional config data and the behavior with only environment variables are the same.(PS: On a side note, the issue tracker still suggests providing the code via repl.it, but the Go version there is limited to
1.17
, which makes it impossible to run recent versions of viper there.)