-
Notifications
You must be signed in to change notification settings - Fork 51
Feature/decouple env vars #105
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
base: master
Are you sure you want to change the base?
Feature/decouple env vars #105
Conversation
Just realized some things which are not covered by tests. --> converted to draft |
385ecc9
to
939a237
Compare
I've reworked the whole draft, putting test-cases to the start of the PR. But right now I will postpone the work here until the migration to superpower in #106 is completed. |
I like the look of this! Please update for the superpower merge, and I'll go over more granularly. But I very much like where this is headed. |
939a237
to
f896bea
Compare
Updating to superpower-stuff was kinda easy, but still I need to invest some time and comment some cases. I will come back here soon. |
f896bea
to
dd61524
Compare
dd61524
to
522672a
Compare
I'm back at this implementation now and rebased it on the current Points to be discussed:
edit: strikethrough parts which were removed from this PR |
Before you go further on this, review existing dot env libraries and their behavior. In particular observe the references to 12 factor apps. And note that the entire point of .env files is to invisibly make the app treat them identically to env vars. Perhaps optional methods to find the specific differences between actual env and .env maybe exist in some implementations (not that I have seen in the past tho), but this is not a library to make people merge env vars with .env files on their own. It does that automatically, and that is the point. Please consider the intention of these libraries and consider how your vision should fit into that. |
I will have a deeper look, but here my first thoughts without checking the mentioned repos deeper: The main point seems to be:
I'm not sure what you are aiming at exactly. If it is about the raw values with Changing the Output of With the last changes I introduced too much. I will revert the new option regarding Environment Variables and maybe bring it with another PR, where we can have a deeper look into that. Are there any problems with the basics of decoupling only? |
0d5928e
to
b264aba
Compare
I will update the PR to return non-clobbered env-vars again. It will still return only the dictionary, which is the final "Environment"-like result for the user. And with each change I will update this comment: #105 (comment) edit: I won't do that change now, see discussion below, that leads more to the point, that the new behaviour should be favored. |
Checking the existing libraries I have two "different ways" in mind:
And there is an additional insight: every repos behaves differently (according to documentation, I did not test it). Following the first way, many features should just disappear, but that's not the way for this repo I guess. That said, coming to the second way, which will be the way of this repo I think. But if a language-specific tool is requested, this repo should serve the best integration possible, which means, support the default .Net way of things. All of this leads more to a general discussion of where should this repo evolve to. We should move that to a separate discussion instead of this PR I think. For this PR only, I don't see a point against that change.
I can just guess, that you point at my notes about the breaking change, explicitly these points:
The first says, that my new version does NOT return the non-clobbered keys from env, so it actually does not merge env and envFile. The current version does merge them. The second is about a public method, which can be used if someone wants to, but he does not need to. I would be happy to know what you see as problematic here. |
src/DotNetEnv/Env.cs
Outdated
var pairs = Parsers.ParseDotenvFile(contents, options.ClobberExistingVars, actualValues); | ||
|
||
// for NoClobber, remove pairs which are exactly contained in previousValues or present in EnvironmentVariables | ||
var unClobberedPairs = (options.ClobberExistingVars |
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.
Why do you need to check ClobberExistingVars
twice? It seems like this should only have to happen once.
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.
Parsers.ParseDotenvFile
returns all parsed values, no matter if it clobbers or not.
Interpolation needs clobber-setting to work while parsing, but the responsbility for setting EnvVars should move to the Env-scope, to remove the tight coupling there.
That's why it has to be checked here again.
If we don't want that, we need to return unclobbered values in the parser, but that would change the default Parser-logic, which return all values as IEnumerable --> we need to intercept and return if not clobbered only.
Have a look at the new way with ValueProviders, I think that makes it more precise now.
src/DotNetEnv/Env.cs
Outdated
{ | ||
if (options == null) options = LoadOptions.DEFAULT; | ||
|
||
previousValues = previousValues?.ToArray() ?? Array.Empty<KeyValuePair<string, string>>(); | ||
|
||
var envVarSnapshot = Environment.GetEnvironmentVariables().Cast<DictionaryEntry>() |
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.
One of the reasons for previous approaches is to explicitly avoid needing to collect all env vars, and only compare the ones in the file vs the ones out in the wild. It obviously gets weird with interpolation, but the goal is to take a minimal set, rather than get the whole thing, ideally.
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.
Asking this question was kind of a gamechanger, made me think about the concept of ValueProvider.
Snapshotting EnvVars is removed now, and the whole logic is reduced/simplified.
So, I have attempted to absorb this PR a couple times, and overall I think I'm onboard with the direction, but I'd like a breakdown of the changes -- their purpose and implications. Please add comments on major changes throughout the code explaining your thought process and goals. This is a hard one to follow, imo. If we were working a day job together, this is the kind of PR I would want a walkthrough on, so we'll do the best we can here, please :) |
And now you need to rebase with the changes for the new extra interpolation features. |
Shows additional testingIssues due to coupling to EnvironmentVariables (ParseInterpolatedNoEnvVarsTest, ParseInterpolatedTest)
…on when having NoClobber and NoEnvVars
…ess to EnvironmentVariables inside IValue; makes ParseInterploatedNoEnvVarsTest and ParseInterpolatedTest green again breaks many other tests at this stage, because IValue does not check EnvironmentVariables now
…able dependencies in the tests where it is possible (check values differently, to be independent from EnvironmentVariables) makes test AddSourceToBuilderAndLoadMultiWithClobber red, because EnvVarSnapshot gets a reset for each load-process (new multi-file-load problem)
…arsers to EnvironmentVariables)
…epending results with "not to be clobbered" EnvVars in Env.LoadContents makes LoadMultiTestNoEnvVars green
…nvFile by solving the EnvVarSet-Logic completely into Env.LoadContents
…ibility for "NoClobber", but if one needs raw values Parsers.ParseDotEnvFile has to be used directly
…aking it just an implementationDetail for LoadMulti
…m Env inside Parsers;
b264aba
to
1498d20
Compare
Done, all tests should be green, but no more time right now to check.
Absolutely, I will give some more advice as soon as time is available. |
…arates better between Parsed Values and already contained ones --> simplifies Env.LoadContents()
While making the latest changes I realized, that I updated the above comment, and there is only this breakng change now:
Still no time for an adequate walkthrough due to the latest changes ;) |
0fdcbb5
to
d53f295
Compare
Quite much time available at the moment :) The Main Goal of the PR is to decouple Parsers/IValue from Environment, and introduce precise responsibilities between Env and Parsers. IValueProvider Parsers Env EnvConfigurationProvider Testing About the breaking change Some words at the end |
I just read through the PR #110 for more Interpolation-features. That is a sample of what we can implement in next steps having this new approach with ValueProviders and separation of concerns. |
…so better understandable without usage of Aggregate here...
Solves #92
Decoupling the concerns of Parsers and Env leads to a more consistent behaviour with different LoadOptions.
Namely it solves the different behaviour of Interpolation, when setting SetEnvVars to true or false.
While the parsers main responsibility now is correct parsing and returning the values from the EnvFile, the Env-class takes the responsibility about setting EnvVars, preventing clobber and so on.
With a next step it would be additionally possible to add a LoadOptions-Parameter to be able to ignore (System-)Environment variables at all, which could be a good thing if you work on a system which is polluted with EnvVars by default, and you don't want to see any side effects from your systems EnvVars.