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
Handle empty and null sources correctly #93
Conversation
We're currently handling empty (or comment-only) and null YAML sources incorrectly. This diff fixes both by simplifying the configuration provider even further. These sources are problematic for two reasons. First, we're not special-casing `io.EOF` errors when we use `yaml.Decoder`. More insidiously, when we unmarshal sources, we're not distinguishing between nil values caused by empty (or comment-only) sources and explicit top-level nulls. The latter is particularly problematic because an explicit null should be higher-priority than all defaults provided via `WithDefault`, even if that null is itself overriden by another YAML source. (For example, if `base.yaml` is just `~` and `production.yaml` is `foo: bar`, the explicit top-level null in `base.yaml` should trump any data supplied by `WithDefault`.) This commit fixes these issues by making three interrelated changes: 1. It changes all YAML options to eagerly consume `io.Reader`s, and changes the internal representation of YAML sources to byte slices instead of readers. This simplifies later changes, since we'll be consuming each source multiple times. 2. It special-cases `io.EOF` errors where appropriate, taking care to distinguish empty sources and explicit nulls. 3. It changes `WithDefault`'s internals to match the documentation: the implementation literally uses the user-supplied value as the lowest-priority search and deep-merges it with all other sources.
Codecov Report
@@ Coverage Diff @@
## master #93 +/- ##
=========================================
- Coverage 95.54% 94.35% -1.2%
=========================================
Files 8 8
Lines 382 390 +8
=========================================
+ Hits 365 368 +3
- Misses 11 14 +3
- Partials 6 8 +2
Continue to review full report at Codecov.
|
option.go
Outdated
all, err := ioutil.ReadAll(f) | ||
if err != nil { | ||
return failed(err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we close the file here after reading from it instead of relying on the closers
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point, will fix.
Since we're eagerly reading configuration files now, we don't need to keep a slice of `io.Closers`. This also simplifies `NewYAML`.
We're currently handling empty (or comment-only) and null YAML sources
incorrectly. This diff fixes both by simplifying the configuration
provider even further.
These sources are problematic for two reasons. First, we're not
special-casing
io.EOF
errors when we useyaml.Decoder
. Moreinsidiously, when we unmarshal sources, we're not distinguishing between
nil values caused by empty (or comment-only) sources and explicit
top-level nulls. The latter is particularly problematic because an
explicit null should be higher-priority than all defaults provided via
WithDefault
, even if that null is itself overriden by another YAMLsource. (For example, if
base.yaml
is just~
andproduction.yaml
is
foo: bar
, the explicit top-level null inbase.yaml
should trumpany data supplied by
WithDefault
.)This commit fixes these issues by making three interrelated changes:
io.Reader
s, andchanges the internal representation of YAML sources to byte slices
instead of readers. This simplifies later changes, since we'll be
consuming each source multiple times.
io.EOF
errors where appropriate, taking care todistinguish empty sources and explicit nulls.
WithDefault
's internals to match the documentation: theimplementation literally uses the user-supplied value as the
lowest-priority search and deep-merges it with all other sources.