From 95bb54353eb404a22e365fef62e937a371833af9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 7 Nov 2018 11:57:18 +0100 Subject: [PATCH] Allow to override .env files per env --- .../2.1/features/bootstrap/bootstrap.php | 10 +-- phpunit/phpunit/4.7/.env.test | 4 + phpunit/phpunit/4.7/manifest.json | 1 + phpunit/phpunit/4.7/phpunit.xml.dist | 10 +-- phpunit/phpunit/4.7/tests/.gitignore | 0 phpunit/phpunit/4.7/tests/bootstrap.php | 5 ++ symfony/console/3.3/bin/console | 22 ++---- symfony/flex/1.0/{.env.dist => .env} | 2 +- symfony/flex/1.0/manifest.json | 2 +- symfony/framework-bundle/3.3/public/index.php | 18 +---- symfony/framework-bundle/3.3/src/Kernel.php | 75 +++++++++++++++++++ symfony/framework-bundle/4.2/manifest.json | 3 +- symfony/framework-bundle/4.2/public/index.php | 18 +---- symfony/framework-bundle/4.2/src/Kernel.php | 27 +++++++ symfony/phpunit-bridge/3.3/.env.test | 6 ++ symfony/phpunit-bridge/3.3/bin/phpunit | 12 ++- symfony/phpunit-bridge/3.3/manifest.json | 1 + symfony/phpunit-bridge/3.3/phpunit.xml.dist | 6 -- symfony/phpunit-bridge/4.1/.env.test | 6 ++ symfony/phpunit-bridge/4.1/bin/phpunit | 12 ++- symfony/phpunit-bridge/4.1/manifest.json | 1 + symfony/phpunit-bridge/4.1/phpunit.xml.dist | 6 -- 22 files changed, 157 insertions(+), 90 deletions(-) create mode 100644 phpunit/phpunit/4.7/.env.test delete mode 100644 phpunit/phpunit/4.7/tests/.gitignore create mode 100644 phpunit/phpunit/4.7/tests/bootstrap.php rename symfony/flex/1.0/{.env.dist => .env} (60%) create mode 100644 symfony/phpunit-bridge/3.3/.env.test create mode 100644 symfony/phpunit-bridge/4.1/.env.test diff --git a/behat/symfony2-extension/2.1/features/bootstrap/bootstrap.php b/behat/symfony2-extension/2.1/features/bootstrap/bootstrap.php index 3dd503814..371e1b2cf 100644 --- a/behat/symfony2-extension/2.1/features/bootstrap/bootstrap.php +++ b/behat/symfony2-extension/2.1/features/bootstrap/bootstrap.php @@ -1,11 +1,3 @@ load(__DIR__.'/../../.env'); -} +App\Kernel::bootstrapEnv('test'); diff --git a/phpunit/phpunit/4.7/.env.test b/phpunit/phpunit/4.7/.env.test new file mode 100644 index 000000000..f0cf8392b --- /dev/null +++ b/phpunit/phpunit/4.7/.env.test @@ -0,0 +1,4 @@ +# define your env variables for the test env here +KERNEL_CLASS=App\\Kernel +APP_SECRET='s$cretf0rt3st' +SHELL_VERBOSITY=-1 diff --git a/phpunit/phpunit/4.7/manifest.json b/phpunit/phpunit/4.7/manifest.json index 0e82b71f2..e82151c97 100644 --- a/phpunit/phpunit/4.7/manifest.json +++ b/phpunit/phpunit/4.7/manifest.json @@ -1,5 +1,6 @@ { "copy-from-recipe": { + ".env.test": ".env.test", "phpunit.xml.dist": "phpunit.xml.dist", "tests/": "tests/" }, diff --git a/phpunit/phpunit/4.7/phpunit.xml.dist b/phpunit/phpunit/4.7/phpunit.xml.dist index bce561d8d..a306d95b7 100644 --- a/phpunit/phpunit/4.7/phpunit.xml.dist +++ b/phpunit/phpunit/4.7/phpunit.xml.dist @@ -2,19 +2,13 @@ - - - - - - diff --git a/phpunit/phpunit/4.7/tests/.gitignore b/phpunit/phpunit/4.7/tests/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/phpunit/phpunit/4.7/tests/bootstrap.php b/phpunit/phpunit/4.7/tests/bootstrap.php new file mode 100644 index 000000000..fec999bd0 --- /dev/null +++ b/phpunit/phpunit/4.7/tests/bootstrap.php @@ -0,0 +1,5 @@ +load(__DIR__.'/../.env'); -} - -$input = new ArgvInput(); -$env = $input->getParameterOption(['--env', '-e'], $_SERVER['APP_ENV'] ?? 'dev', true); -$debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env)) && !$input->hasParameterOption('--no-debug', true); +Kernel::bootstrapCli($_SERVER['argv']); +Kernel::bootstrapEnv(); -if ($debug) { +if ($_SERVER['APP_DEBUG']) { umask(0000); if (class_exists(Debug::class)) { @@ -34,6 +24,6 @@ if ($debug) { } } -$kernel = new Kernel($env, $debug); +$kernel = new Kernel($_SERVER['APP_ENV'], $_SERVER['APP_DEBUG']); $application = new Application($kernel); -$application->run($input); +$application->run(); diff --git a/symfony/flex/1.0/.env.dist b/symfony/flex/1.0/.env similarity index 60% rename from symfony/flex/1.0/.env.dist rename to symfony/flex/1.0/.env index 2148dfc4f..d0c43fbc0 100644 --- a/symfony/flex/1.0/.env.dist +++ b/symfony/flex/1.0/.env @@ -1,3 +1,3 @@ # This file is a "template" of which env vars need to be defined for your application -# Copy this file to .env file for development, create environment variables when deploying to production +# Override the variables you want in .env.local for development, create environment variables when deploying to production # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration diff --git a/symfony/flex/1.0/manifest.json b/symfony/flex/1.0/manifest.json index b7bcea82a..56f64a60e 100644 --- a/symfony/flex/1.0/manifest.json +++ b/symfony/flex/1.0/manifest.json @@ -1,5 +1,5 @@ { "copy-from-recipe": { - ".env.dist": ".env.dist" + ".env": ".env" } } diff --git a/symfony/framework-bundle/3.3/public/index.php b/symfony/framework-bundle/3.3/public/index.php index 5283b7ceb..c10bbd577 100644 --- a/symfony/framework-bundle/3.3/public/index.php +++ b/symfony/framework-bundle/3.3/public/index.php @@ -2,23 +2,13 @@ use App\Kernel; use Symfony\Component\Debug\Debug; -use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpFoundation\Request; -require __DIR__.'/../vendor/autoload.php'; +require dirname(__DIR__).'/vendor/autoload.php'; -// The check is to ensure we don't use .env in production -if (!isset($_SERVER['APP_ENV']) && !isset($_ENV['APP_ENV'])) { - if (!class_exists(Dotenv::class)) { - throw new \RuntimeException('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.'); - } - (new Dotenv())->load(__DIR__.'/../.env'); -} - -$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev'; -$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env)); +Kernel::bootstrapEnv(); -if ($debug) { +if ($_SERVER['APP_DEBUG']) { umask(0000); Debug::enable(); @@ -32,7 +22,7 @@ Request::setTrustedHosts(explode(',', $trustedHosts)); } -$kernel = new Kernel($env, $debug); +$kernel = new Kernel($_SERVER['APP_ENV'], $_SERVER['APP_DEBUG']); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); diff --git a/symfony/framework-bundle/3.3/src/Kernel.php b/symfony/framework-bundle/3.3/src/Kernel.php index dc2f242c7..559effee0 100644 --- a/symfony/framework-bundle/3.3/src/Kernel.php +++ b/symfony/framework-bundle/3.3/src/Kernel.php @@ -6,6 +6,7 @@ use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\Routing\RouteCollectionBuilder; @@ -58,4 +59,78 @@ protected function configureRoutes(RouteCollectionBuilder $routes) $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); } + + public static function bootstrapCli(array &$argv) + { + // consume --env and --no-debug from the command line + + // when using symfony/console v4.2 or higher, this should + // be replaced by a call to Application::bootstrapEnv() + + for ($i = 0; $i < \count($argv) && '--' !== $v = $argv[$i]; ++$i) { + if ('--no-debug' === $v) { + putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); + $argvUnset[$i] = true; + break; + } + } + + for ($i = 0; $i < \count($argv) && '--' !== $v = $argv[$i]; ++$i) { + if (!$v || '-' !== $v[0] || !preg_match('/^-(?:-env(?:=|$)|e=?)(.*)$/D', $v, $v)) { + continue; + } + if (!empty($v[1]) || !empty($argv[1 + $i])) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = empty($v[1]) ? $argv[1 + $i] : $v[1]); + $argvUnset[$i] = $argvUnset[$i + empty($v[1])] = true; + } + break; + } + + if (!empty($argvUnset)) { + $argv = array_values(array_diff_key($argv, $argvUnset)); + } + } + + public static function bootstrapEnv($env = null) + { + if (null !== $env) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $env); + } + + if ('prod' !== $_SERVER['APP_ENV'] = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) { + if (!class_exists(Dotenv::class)) { + throw new \RuntimeException('The "APP_ENV" environment variable is not defined. You need to set it or run "composer require symfony/dotenv" to load it from a ".env" file.'); + } + + // when using symfony/dotenv v4.2 or higher, this call and the related methods + // below should be replaced by a call to the new Dotenv::loadEnv() method + self::loadEnv(new Dotenv(), \dirname(__DIR__).'/.env'); + } + + $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : 'dev'; + $_SERVER['APP_DEBUG'] = isset($_SERVER['APP_DEBUG']) ? $_SERVER['APP_DEBUG'] : (isset($_ENV['APP_DEBUG']) ? $_ENV['APP_DEBUG'] : 'prod' !== $_SERVER['APP_ENV']); + $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; + } + + private static function loadEnv(Dotenv $dotenv, $path) + { + $dotenv->load($path); + + if (null === $env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) { + $dotenv->populate(array('APP_ENV' => $env = 'dev')); + } + + if ('test' !== $env && file_exists($p = "$path.local")) { + $dotenv->load($p); + $env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : $env); + } + + if (file_exists($p = "$path.$env")) { + $dotenv->load($p); + } + + if (file_exists($p = "$path.$env.local")) { + $dotenv->load($p); + } + } } diff --git a/symfony/framework-bundle/4.2/manifest.json b/symfony/framework-bundle/4.2/manifest.json index 34798d550..bffbcfe77 100644 --- a/symfony/framework-bundle/4.2/manifest.json +++ b/symfony/framework-bundle/4.2/manifest.json @@ -18,7 +18,8 @@ "#TRUSTED_HOSTS": "localhost,example.com" }, "gitignore": [ - "/.env", + "/.env.local", + "/.env.*.local", "/%PUBLIC_DIR%/bundles/", "/%VAR_DIR%/", "/vendor/" diff --git a/symfony/framework-bundle/4.2/public/index.php b/symfony/framework-bundle/4.2/public/index.php index bdcf5f4dd..c10bbd577 100644 --- a/symfony/framework-bundle/4.2/public/index.php +++ b/symfony/framework-bundle/4.2/public/index.php @@ -2,23 +2,13 @@ use App\Kernel; use Symfony\Component\Debug\Debug; -use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpFoundation\Request; -require __DIR__.'/../vendor/autoload.php'; +require dirname(__DIR__).'/vendor/autoload.php'; -// The check is to ensure we don't use .env if APP_ENV is defined -if (!isset($_SERVER['APP_ENV']) && !isset($_ENV['APP_ENV'])) { - if (!class_exists(Dotenv::class)) { - throw new \RuntimeException('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.'); - } - (new Dotenv())->load(__DIR__.'/../.env'); -} - -$env = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? 'dev'; -$debug = (bool) ($_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? ('prod' !== $env)); +Kernel::bootstrapEnv(); -if ($debug) { +if ($_SERVER['APP_DEBUG']) { umask(0000); Debug::enable(); @@ -32,7 +22,7 @@ Request::setTrustedHosts(explode(',', $trustedHosts)); } -$kernel = new Kernel($env, $debug); +$kernel = new Kernel($_SERVER['APP_ENV'], $_SERVER['APP_DEBUG']); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); diff --git a/symfony/framework-bundle/4.2/src/Kernel.php b/symfony/framework-bundle/4.2/src/Kernel.php index dc2f242c7..76ebf628d 100644 --- a/symfony/framework-bundle/4.2/src/Kernel.php +++ b/symfony/framework-bundle/4.2/src/Kernel.php @@ -5,7 +5,9 @@ use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Console\Application; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpKernel\Kernel as BaseKernel; use Symfony\Component\Routing\RouteCollectionBuilder; @@ -58,4 +60,29 @@ protected function configureRoutes(RouteCollectionBuilder $routes) $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); } + + public static function bootstrapCli(array &$argv) + { + // consume --env and --no-debug from the command line + Application::bootstrapEnv($argv); + } + + public static function bootstrapEnv(string $env = null) + { + if (null !== $env) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $env); + } + + if ('prod' !== $_SERVER['APP_ENV'] = $_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) { + if (!class_exists(Dotenv::class)) { + throw new \RuntimeException('The "APP_ENV" environment variable is not defined. You need to set it or run "composer require symfony/dotenv" to load it from a ".env" file.'); + } + + (new Dotenv())->loadEnv(\dirname(__DIR__).'/.env'); + } + + $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $_SERVER['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'dev'; + $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; + $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; + } } diff --git a/symfony/phpunit-bridge/3.3/.env.test b/symfony/phpunit-bridge/3.3/.env.test new file mode 100644 index 000000000..5ae9f7de6 --- /dev/null +++ b/symfony/phpunit-bridge/3.3/.env.test @@ -0,0 +1,6 @@ +# define your env variables for the test env here +KERNEL_CLASS=App\\Kernel +APP_SECRET='s$cretf0rt3st' +SHELL_VERBOSITY=-1 +SYMFONY_DEPRECATIONS_HELPER=999999 +SYMFONY_PHPUNIT_VERSION=6.5 diff --git a/symfony/phpunit-bridge/3.3/bin/phpunit b/symfony/phpunit-bridge/3.3/bin/phpunit index 6baa2857e..e4f3c26f4 100755 --- a/symfony/phpunit-bridge/3.3/bin/phpunit +++ b/symfony/phpunit-bridge/3.3/bin/phpunit @@ -5,16 +5,14 @@ if (!file_exists(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-php echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; exit(1); } -if (false === getenv('SYMFONY_DEPRECATIONS_HELPER')) { - // see https://symfony.com/doc/current/components/phpunit_bridge.html#making-tests-fail - putenv('SYMFONY_DEPRECATIONS_HELPER=999999'); -} + +$classLoader = require dirname(__DIR__).'/vendor/autoload.php'; +App\Kernel::bootstrapEnv('test'); +$classLoader->unregister(); + if (false === getenv('SYMFONY_PHPUNIT_REMOVE')) { putenv('SYMFONY_PHPUNIT_REMOVE=symfony/yaml'); } -if (false === getenv('SYMFONY_PHPUNIT_VERSION')) { - putenv('SYMFONY_PHPUNIT_VERSION=6.5'); -} if (false === getenv('SYMFONY_PHPUNIT_DIR')) { putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit'); } diff --git a/symfony/phpunit-bridge/3.3/manifest.json b/symfony/phpunit-bridge/3.3/manifest.json index cfb6c1acb..6a0aab996 100644 --- a/symfony/phpunit-bridge/3.3/manifest.json +++ b/symfony/phpunit-bridge/3.3/manifest.json @@ -1,5 +1,6 @@ { "copy-from-recipe": { + ".env.test": ".env.test", "bin/": "%BIN_DIR%/", "config/": "%CONFIG_DIR%/", "phpunit.xml.dist": "phpunit.xml.dist", diff --git a/symfony/phpunit-bridge/3.3/phpunit.xml.dist b/symfony/phpunit-bridge/3.3/phpunit.xml.dist index 195001531..ae501d84f 100644 --- a/symfony/phpunit-bridge/3.3/phpunit.xml.dist +++ b/symfony/phpunit-bridge/3.3/phpunit.xml.dist @@ -9,12 +9,6 @@ > - - - - - - diff --git a/symfony/phpunit-bridge/4.1/.env.test b/symfony/phpunit-bridge/4.1/.env.test new file mode 100644 index 000000000..5ae9f7de6 --- /dev/null +++ b/symfony/phpunit-bridge/4.1/.env.test @@ -0,0 +1,6 @@ +# define your env variables for the test env here +KERNEL_CLASS=App\\Kernel +APP_SECRET='s$cretf0rt3st' +SHELL_VERBOSITY=-1 +SYMFONY_DEPRECATIONS_HELPER=999999 +SYMFONY_PHPUNIT_VERSION=6.5 diff --git a/symfony/phpunit-bridge/4.1/bin/phpunit b/symfony/phpunit-bridge/4.1/bin/phpunit index 79aa012e3..f28f65f80 100755 --- a/symfony/phpunit-bridge/4.1/bin/phpunit +++ b/symfony/phpunit-bridge/4.1/bin/phpunit @@ -5,16 +5,14 @@ if (!file_exists(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-php echo "Unable to find the `simple-phpunit` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; exit(1); } -if (false === getenv('SYMFONY_DEPRECATIONS_HELPER')) { - // see https://symfony.com/doc/current/components/phpunit_bridge.html#making-tests-fail - putenv('SYMFONY_DEPRECATIONS_HELPER=999999'); -} + +$classLoader = require dirname(__DIR__).'/vendor/autoload.php'; +App\Kernel::bootstrapEnv('test'); +$classLoader->unregister(); + if (false === getenv('SYMFONY_PHPUNIT_REMOVE')) { putenv('SYMFONY_PHPUNIT_REMOVE='); } -if (false === getenv('SYMFONY_PHPUNIT_VERSION')) { - putenv('SYMFONY_PHPUNIT_VERSION=6.5'); -} if (false === getenv('SYMFONY_PHPUNIT_DIR')) { putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit'); } diff --git a/symfony/phpunit-bridge/4.1/manifest.json b/symfony/phpunit-bridge/4.1/manifest.json index 94b468631..01a2e0543 100644 --- a/symfony/phpunit-bridge/4.1/manifest.json +++ b/symfony/phpunit-bridge/4.1/manifest.json @@ -1,5 +1,6 @@ { "copy-from-recipe": { + ".env.test": ".env.test", "bin/": "%BIN_DIR%/", "phpunit.xml.dist": "phpunit.xml.dist", "tests/": "tests/" diff --git a/symfony/phpunit-bridge/4.1/phpunit.xml.dist b/symfony/phpunit-bridge/4.1/phpunit.xml.dist index 440ff8dc6..e283e8dba 100644 --- a/symfony/phpunit-bridge/4.1/phpunit.xml.dist +++ b/symfony/phpunit-bridge/4.1/phpunit.xml.dist @@ -9,12 +9,6 @@ > - - - - - -