-
-
Notifications
You must be signed in to change notification settings - Fork 481
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
Add checks for Dotenv before calling it #247
Conversation
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.
Pull request passes validation.
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.
Pull request passes validation.
@@ -3,6 +3,6 @@ | |||
use Symfony\Component\Dotenv\Dotenv; | |||
|
|||
// The check is to ensure we don't use .env in production | |||
if (!isset($_SERVER['APP_ENV'])) { | |||
if (class_exists(Dotenv::class) && !isset($_SERVER['APP_ENV'])) { |
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 be done after the call to isset
for perf.
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.
Pull request passes validation.
Good call @dunglas. Updated. |
I don't think this is a good strategy as the app will fail as the env vars are not defined. We should only support 2 use cases:
With this PR, you make it possible to have neither. That will not work and should be avoided. What we can do is throwing an exception when the env vars are not defined and DotEnv is not available explaining that the user must either define all env vars or install 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.
Pull request passes validation.
Indeed, the application will still fail, just a little bit later once it tries to use a variable that was not provided through the actual env or dotenv. I was originally thinking of "this could let you run a subset of the app that didn't need all the env parameters". An example of that being It's a weird twilight zone that works more through luck than judgement and is brittle, so I'm happy to say all bets are off, Symfony doesn't support that and to provide a more relevant error message. I now throw an error instead of powering through. Let me know if that's good wording (I'm not familiar with the conventions that Symfony uses for messaging, this was based off the other class_exists check in the console) and I'll squash and rebase. |
@@ -4,5 +4,8 @@ | |||
|
|||
// The check is to ensure we don't use .env in production | |||
if (!isset($_SERVER['APP_ENV'])) { | |||
if (!class_exists(Dotenv::class)) { | |||
throw new \RuntimeException('You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency'); |
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.
What about something along the lines of:
APP_ENV environment variable is not defined. All project's environment variables should be defined or set via a .env file (for which you need to require "symfony/dotenv" as a Composer dependency).
I'm not very satisfied with the should be defined or set
part as I'm not sure it's easily understandable. We could probably find something better.
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.
What about straightforward; Loading project environment variables requires symfony/dotenv ~3.4|4.0
?
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.
I'd go for Loading project environment variables from .env file requires symfony/dotenv
, so we don't need to show anything about the version
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.
(Whoops, life got busy)
@ro0NL & @Pierstoval: I think the "this is your next step" message should make it clear that Symfony prefers using env variables rather than a .env in production. Thus this ends up being a bit wordy as the user has two options dependant on what they want to do. Given you're more likely to run into this issue while building for production (as dotenv is installed by default in dev) it's worth starting off talking about env variables, rather than directing people straight to dotenv IMO.
The existing message takes inspiration from the other class_exists check in bin/console
(see below). I think it's worth keeping the voice between these two messages somewhat consistent, which is why I started with "You need to...".
if (!class_exists(Application::class)) {
throw new \RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.');
}
How about APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.
?
And then updating Application class check message to Application class does not exist. You need to add "symfony/framework-bundle" as a Composer dependency.
Which keeps a "[why the check failed] [how to fix it]" format.
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.
@BPScott Your proposal sounds good to me. Can you update the PR?
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.
Pull request passes validation.
@fabpot updated, squashed and rebased onto latest master. |
symfony/console/3.3/bin/console
Outdated
@@ -12,10 +12,13 @@ set_time_limit(0); | |||
require __DIR__.'/../vendor/autoload.php'; | |||
|
|||
if (!class_exists(Application::class)) { | |||
throw new \RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.'); | |||
throw new \RuntimeException('Application class does not exist. You need to add "symfony/framework-bundle" as a Composer dependency.'); |
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.
I would remove this addition as it does not add anything useful for the user. Nobody knows what this Application
class is and why it is useful (and nobody should care to be honest). Moreover this error message should never be displayed anyway.
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.
Done.
`composer install --no-dev` fails when Dotenv is a dev dependency (which it is in skeleton) and you're running in an environment without an APP_ENV variable set. Throw exception when no env variables are set and Dotenv is absent so the user knows to either require DotEnv or specify an APP_ENV variable.
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.
Pull request passes validation.
This unfortunately breaks if you don't want to use env-Vars all the way (as in our case we have to copy the env vars to around 10 different places instead of one Why do we force recipes/symfony/console/3.3/bin/console Lines 26 to 27 in b3c5ff1
Is it not an option to just have: $env = $_SERVER['APP_ENV'] ?? 'dev';
$debug = $_SERVER['APP_DEBUG'] ?? ('prod' !== $env);
if ($debug && class_exists(Dotenv::class)) {
(new Dotenv())->load(__DIR__.'/../.env');
} ... which would satisfy both worlds, the ones that go all the |
@fabpot @nicolas-grekas what do you think about the last comment? |
@apfelbox please open PR so we can keep track of any discussion :) |
@nicolas-grekas oh sure! Yeah, discussing in a closed PR is not the best idea. 👍 See #340 |
composer install --no-dev
fails when Dotenv is a dev dependency (whichit is in skeleton) and you're running in an environment without an
APP_ENV variable set (say you're testing prod-like settings locally).
After that
bin/console help
also fails, as doesbin/console --env=prod help
(as Dotenv is loaded before the argumentcan be read).
APP_ENV=prod bin/console help
works but instead lets avoid needing toremember that by only trying to load Dotenv if it actually exists.
Strictly speaking this is only required for console, however I have
placed the check in the other places Dotenv is included for consistency.
See symfony/skeleton#32 for some initial pondering relating to this.