Skip to content

Commit

Permalink
[Dotenv] Reimplementing symfony/flex' dump-env as a Symfony command
Browse files Browse the repository at this point in the history
  • Loading branch information
abdielcs authored and nicolas-grekas committed Sep 30, 2021
1 parent 7189ac0 commit dc1b877
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

5.4
---

* Add `dotenv:dump` command to compile the contents of the .env files into a PHP-optimized file called `.env.local.php`

5.1.0
-----

Expand Down
128 changes: 128 additions & 0 deletions Command/DotenvDumpCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Dotenv\Command;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Dotenv\Dotenv;

/**
* A console command to compile the contents of the .env files into a PHP-optimized file called .env.local.php.
*
* @internal
*/
final class DotenvDumpCommand extends Command
{
protected static $defaultName = 'dotenv:dump';
protected static $defaultDescription = 'Compiles .env files to .env.local.php';

/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setDescription('Compiles .env files to .env.local.php.')
->setDefinition([
new InputArgument('env', InputArgument::OPTIONAL, 'The application environment to dump .env files for - e.g. "prod".'),
])
->addOption('empty', null, InputOption::VALUE_NONE, 'Ignore the content of .env files')
->setHelp(<<<'EOT'
The <info>%command.name%</info> command compiles the contents of the .env files into a PHP-optimized file called .env.local.php.
<info>%command.full_name%</info>
EOT
)
;
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var Application $application */
$application = $this->getApplication();
$kernel = $application->getKernel();

if ($env = $input->getArgument('env')) {
$_SERVER['APP_ENV'] = $env;
}

$path = $kernel->getProjectDir().'/.env';

if (!$env || !$input->getOption('empty')) {
$vars = $this->loadEnv($path, $env, $kernel->getProjectDir().'/composer.json');
$env = $vars['APP_ENV'];
}

if ($input->getOption('empty')) {
$vars = ['APP_ENV' => $env];
}

$vars = var_export($vars, true);
$vars = <<<EOF
<?php
// This file was generated by running "php bin/console dotenv:dump $env"
return $vars;
EOF;
file_put_contents($path.'.local.php', $vars, \LOCK_EX);

$output->writeln('Successfully dumped .env files in <info>.env.local.php</>');

return Command::SUCCESS;
}

private function loadEnv(string $path, ?string $env, $composerFilePath): array
{
$globalsBackup = [$_SERVER, $_ENV];
unset($_SERVER['APP_ENV']);
$_ENV = ['APP_ENV' => $env];
$_SERVER['SYMFONY_DOTENV_VARS'] = implode(',', array_keys($_SERVER));
putenv('SYMFONY_DOTENV_VARS='.$_SERVER['SYMFONY_DOTENV_VARS']);

try {
$dotenv = new Dotenv();

if (!$env && file_exists($p = "$path.local")) {
$env = $_ENV['APP_ENV'] = $dotenv->parse(file_get_contents($p), $p)['APP_ENV'] ?? null;
}

if (!$env) {
throw new \RuntimeException('Please provide the name of the environment either by passing it as command line argument or by defining the "APP_ENV" variable in the ".env.local" file.');
}

$dotenv->loadEnv(
$path,
null,
'dev',
json_decode(file_get_contents($composerFilePath), true)['extra']['runtime']['test_envs'] ?? ['test']
);

if (isset($_ENV['SYMFONY_DOTENV_VARS'])) {
unset($_ENV['SYMFONY_DOTENV_VARS']);
}
$env = $_ENV;
} finally {
[$_SERVER, $_ENV] = $globalsBackup;
}

return $env;
}
}
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"symfony/deprecation-contracts": "^2.1"
},
"require-dev": {
"symfony/console": "^5.4|^6.0",
"symfony/filesystem": "^4.4|^5.0|^6.0",
"symfony/process": "^4.4|^5.0|^6.0"
},
"autoload": {
Expand Down

0 comments on commit dc1b877

Please sign in to comment.