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
Make env file loading a clearer step when subclassing app #1190
Conversation
0bba5da
to
d0cefb9
Compare
end | ||
|
||
context "hanami env is development" do | ||
it "loads .env.development.local, .env.local, .env.development and .env (in this order) into ENV", :aggregate_failures do |
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.
FWIW, a lot of these tests now overlap with the ones I added in the (also open) #1186. Once these are both merged, I'll remove any redundant tests (leaving this file as the canonical set of tests exercising the .env
file loading behaviour).
In the meantime, I figured it made sense to let each PR stand on its own.
d0cefb9
to
b506730
Compare
Why was this needed? It doesn't sound like a good idea to load file contents in an inherited hook. The only thing that should depend on dotenv behavior is the settings object. I'm having trouble understanding why we need to load it so early (which makes the app coupled to dotenv). |
Thanks for checking in on this, @solnic :) There's a couple of different things that led me to this change. 1. We need to plug the gap left by the change of
|
@timriley thank you, this makes sense, and you're awesome 😄 I'm just a bit reluctant whenever I see complex logic added to inherited hook as it gave us a lot of pain in rom-rb in its early days. One idea I had to avoid it here was to make it very explicit by having an extra line in the generated class skeleton, like "load_dotenv" or something, just to make it clear that it's happening. We can of course stick to what you did and see how it goes. It's reassuring that this is how dotenv-rails works. I appreciate your thoughtful explanation ❤️ |
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.
@timriley LGTM. 👍
Left a couple of comments for potential enhancements.
lib/hanami/app.rb
Outdated
].compact | ||
|
||
require "dotenv" | ||
Dotenv.load(*dotenv_files) if defined?(Dotenv) |
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.
@timriley I want to double check this with you: what's the Public API to access env variables?
In H1 we had Hanami::Env
, reasons are written here: https://lucaguidi.com/2016/12/27/isolate-global-state/
I'm asking because we could populate Hanami::Env
, instead of ENV
, by using Dotenv.parse(*dotenv_files)
, which returns a Hash
.
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.
@jodosha It's a good question. This PR certainly doesn't have the ambition of providing such an interface — its job is just to populate ENV
as we've always done, but just in a clearer way.
As for whether we should provide a first party, "safer" interface to ENV, my current feeling is that it's probably not worthwhile it at this point: we should be encouraging our users to take advantage of our settings components to access relevant values from the env. Cases where that is not possible (like some of the scenarios I described in my comment above) are hopefully relatively minor and not the kind of thing that would be close to the actual working business logic of Hanami apps.
What do you think?
This makes more sense than loading it as a side effect of preparing the settings store. Yes, the settings are popualted from env vars, but that’s not the _only_ thing in an app that may rely upon them, so loading dotenv as early as possible makes more sense.
b506730
to
03a50e9
Compare
Thanks again @solnic for the initial prompt and @jodosha for checking all of this out 😄 @solnic as for your idea for having A related thing that I would like to consider in the post-2.0 world is some kind of well-defined, extensible structure for the overall framework app boot process. In this world, we could have "load dotenv" as one of the pre-defined steps in the boot, which a user could just explicitly disable if they didn't want it. Anyway, I'll merge this one in now and we can collectively keep an eye out for any issues. That said, my feel is that we'll be fine to bring this through to the 2.0 releases :) |
Yes I've had that idea for a long time but I thought about making it a feature in dry-system. It'd allow you to define a Unit of Work for the booting process where steps can have dependencies and then it's resolved, sorted and executed in the right order based on your configuration. When this process is hardcoded, you lose a lot of flexibility. |
This makes more sense than loading it as a side effect of preparing the settings store.
Yes, the settings are popualted from env vars, but that’s not the only thing in an app that may rely upon them, so loading dotenv as early as possible makes more sense.
To address this, we:
Hanami::App
(in particular the private.load_dotenv
) method.load_dotenv
as soon asApp
is subclassed, making the populatedENV
available as early as possible (this would be useful for e.g. referring toENV
vars inside theApp
subclass body)Hanami::Settings::DotenvStore
toEnvStore
.env
files that can be loaded