Closed Philipp-Binder closed 2 months ago
No one has complained about this functionality. So, there are 2 cases where this might be interesting:
Thanks.
Basically at this point, I'm looking for you to explain why the existing logic does not already do what you want (I believe you that it does not, but we should be clear as to why), and then an explanation of why this logic should live here rather than there.
Re-reading your PR description sounds like it lives here because this is specific to the configuration provider for reloads, and thus this may be my own unfamiliarity with that pattern, so please explain the reload case a bit more simply, as this is not something I have ever used before. Thanks.
Tried to answer some threads above, but I guess first of all we need to clarify which effect NoClobber
should have. That's the point why first of all I wrote I'm not sure about this one ;)
I will answer the other Threads/Topics after we get to a common understanding of NoClobber
Possible answer to this question (my thoughts, please add or comment to them)
We already have that comment Since the Load method does not take care of cloberring, We have to check it here!
in place, which already mentioned the problem.
In theory I would say you are right, we could solve the problem at a different level. Imho that would lead to the solution, that with NoClobber we
Env.Load()
) to contain the EnvVar-Value instead of the DotEnvFile-Value (regardless of the SetEnvVar Option)Env.Load()
) to have no entry for already existing EnvVars at all
--> both would be really bad and breaking changes, and contradicting to the principle, that the dotEnvKvps contains an exact list of all DotEnvFile-Entries (which is imho a really good principle and should not change).Short summary:
Env.Load()
) should always contains a "full list" of all DotEnvVar-EntriesAt this point I would defer to @cdroulers who wrote this original configuration provider code, and which I have very limited understanding of. The changes look possibly fine to me, and certainly limited in scope, but I'd like to have a better sense of what did not pass in the tests before the changes, and why that was not what was expected.
@rogusdev Hi there! After re-reading my own PR and looking a bit into this PR, I think I can give a bit of insight.
I think we misunderstood the "no-clobber" option when we wrote it, assuming it only meant if multiple files are loaded with the same variable, only the first is taken into account. Reading deeper in the Env.Load
method, it refers to overriding actual environment variables!
The assumed usage with the configuration provider was absolutely to never set environment variables, instead always relying on the other providers for the ConfigurationPRovider
, notably AddEnvironmentVariables
from Microsoft.
Using providers for configuration is usually readonly (e.g. load configuration from a list of sources, in order, usually the appsettings.json (multiple versions), then env vars, then command line args). The way we used it was always with LoadOptions.NoEnvVars()
and I would probably suggest that the API for this provider just not expose these options at all to follow the same API design as the rest of the providers. The behaviour for any provider is "last value wins", and the order is user-controlled.
I don't know which use-case found the bug here! I can make a PR later next week to remove options for the configuration provider that don't make sense!
@cdroulers if you want to review the code and make more tweaks, you are welcome to it :)
That said, at this point, I don't think anything strictly needs to be done, unless you believe there are more bugs, or ways for people to use this that would introduce bugs.
No bugs that I can see, the clean up would mostly be to remove the options unless I can understand why they are used!
I think I'd also update the readme section about using the configuration provider to explain the "expected" way to use it (E.g. NoEnvVars() always). I'm on a laptop on vacation, but will check next week!
On Wed, 7 Aug 2024 at 16:27, Chris Rogus @.***> wrote:
@cdroulers https://github.com/cdroulers if you want to review the code and make more tweaks, you are welcome to it :)
That said, at this point, I don't think anything strictly needs to be done, unless you believe there are more bugs, or ways for people to use this that would introduce bugs.
— Reply to this email directly, view it on GitHub https://github.com/tonerdo/dotnet-env/pull/90#issuecomment-2274289466, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFNBPWPSC2Y23ZVYGAAFLDZQJ7JTAVCNFSM6AAAAABLWQVHBWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZUGI4DSNBWGY . You are receiving this because you were mentioned.Message ID: @.***>
Problem Description
I'm not 100% sure about this one, because I'm not sure where and in which way
NoClobber
should be effective. My understading is as follows:If we set the NoClobber option, we want the configuration to return the initial Environment-Variable if present. And if the key is duplicated within the EnvFiles, we want to have the first occurrence (this is already working).
This is all working fine if we use the option
SetEnvVars
and let the configuration rely on the defaultEnvironmentVariablesConfigurationSource
only. This way we do not use the newEnvConfigurationSource
at all. One really poor thing about this: when reading the EnvFile takes place after building the Configuration, the updated EnvVars will not be used, because they do not reload by default in theEnvironmentVariablesConfigurationProvider
. So you are forced to read EnvFile first, or reload theConfigurationManager
manually after reading the EnvFiles/updating the EnvironmentVariables.With the
EnvConfigurationConfigurationSource
in place we get rid of the reload problem, because we do not care about theEnvironmentVariablesConfigurationSource
(except if someone adds theEnvConfigurationSource
before the defaultEnvironmentVariablesConfigurationSource
, which should be a rare scenario I guess). But we add the problem, that we now "hide/clobber" EnvironmentVariables while the option "NoClobber" is set.Solution
I see three possible solutions to this problem (all 3 only for NoClobber is set of course):
The current PR solves the problem with the 3rd option, which brings the most "independence" from other circumstances I think.
Additional Info about the solutions
First I solved it via option 2, which leads to some unexpected (while "correct") cases, where you miss specific values if you rely on EnvConfigurationSource only. (have a look at the first commit if interested, the problematic but correct behavior is shown in a test-case)
Solution 1 and 2 both rely directly on the order of providers to implement the "NoClobber"-option correctly. Solution 3 in contrast to this solves the NoClobber problem by "embedding" the resulting values directly in the provided values, which removes the direct dependency to the order of providers. Of course there is still a dependency to the order of providers, but that is the "default" order dependency, and by having the new provider after the default ones (the default case), we get the correct results. If someone changes this order on purpose (and it is near to impossible to change that order by fault) he is self-responsible for the correct order.