-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unset env-vars does not play nicely with custom decode functions #61
Comments
I don't understand. Why can't you just set a default envconfig value to another value? type SomeType struct {
// ..other fields
LogLevel zapcore.Level `env:"LEVEL,omitempty,default=debug"`
} I'm also not sure what you mean by "env var overrides". |
https://go.dev/play/p/amK4b3kwJ97 Envconfig is overriding a field that was loaded from a file, even though the environment variable is not set. Using default doesn't work because then envconfig overrides with the default value, and the config file has a different value than the default. For an example using zapcore, https://go.dev/play/p/Ug1VlORuxjS. In either of these examples, removing |
**:warning: Breaking!** Envconfig no longer runs decoders on unset values! To restore the old behavior, add the `decodeunset` struct field annotation or pass the `DefaultDecodeUnset` configuration option as `true`. Prior to this change, envconfig would always call decoding functions, even for unset or empty values. This proved problematic for some libraries like `url` and `zap` which implement `TextUnmarshaller`, but error on the empty string (#61). #62 changed the behavior to only call the decoder if a value was explicitly provided, but that broke users unexpectedly (#64), so the change was reverted. After much discussion, we decided to keep the existing behavior until the 1.0 release. However, after further reflection, I think we need to support a user-level configurable option. Some fields and structs may still want the decoder to run on empty values. This PR changes envconfig to only process a field if any of the following are true: - A value was provided (the value can be set to the empty string, there is a distinction between "unset" and "set to empty") - A default value was provided - The `decodeunset` struct field tag is set - The `DefaultDecodeUnset` configuration option is true
**:warning: Breaking!** Envconfig no longer runs decoders on unset values! To restore the old behavior, add the `decodeunset` struct field annotation or pass the `DefaultDecodeUnset` configuration option as `true`. Prior to this change, envconfig would always call decoding functions, even for unset or empty values. This proved problematic for some libraries like `url` and `zap` which implement `TextUnmarshaller`, but error on the empty string (#61). #62 changed the behavior to only call the decoder if a value was explicitly provided, but that broke users unexpectedly (#64), so the change was reverted. After much discussion, we decided to keep the existing behavior until the 1.0 release. However, after further reflection, I think we need to support a user-level configurable option. Some fields and structs may still want the decoder to run on empty values. This PR changes envconfig to only process a field if any of the following are true: - A value was provided (the value can be set to the empty string, there is a distinction between "unset" and "set to empty") - A default value was provided - The `decodeunset` struct field tag is set - The `DefaultDecodeUnset` configuration option is true
envconfig.go has this specific block of logic:
go-envconfig/envconfig.go
Lines 570 to 581 in 39c9bc7
I agree with the sentiment of the block logic: custom decoders may want to process empty env vars in a specific way, rather than return early.
However, if an env for is not set at all, it is currently loaded as an empty string (here:
go-envconfig/envconfig.go
Lines 468 to 491 in 39c9bc7
It seems as if env var overrides should not be applied if the env var does not exist. In my code, this is conflict with a type that uses a field like so,
I specifically define in my config file that the level is debug. The zapcore code handles empty input to
UnmarshalText
as ok and writes the log level to info (see here: https://github.com/uber-go/zap/blob/6f34060764b5ea1367eecda380ba8a9a0de3f0e6/zapcore/level.go#L142-L143), and I have no control to stop this override.My only current option is to wrap this type in another type that specifically handles the empty string as a no-op. Unfortunately, this breaks the potentially desired behavior of when an empty string is actually specified changing the level to info.
ISTM that the better default would be to not process env vars if the env var does not exist.
The text was updated successfully, but these errors were encountered: