Skip to content

Commit 5092ea7

Browse files
bug #867 Fix reading config for symfony/runtime (nicolas-grekas)
This PR was merged into the 1.x branch. Discussion ---------- Fix reading config for symfony/runtime Fix #855 Commits ------- 335e44d Fix reading config for symfony/runtime
2 parents ea2a03c + 335e44d commit 5092ea7

File tree

6 files changed

+53
-37
lines changed

6 files changed

+53
-37
lines changed

src/Command/DumpEnvCommand.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Composer\Command\BaseCommand;
1515
use Composer\Config;
16-
use Composer\Factory;
1716
use Symfony\Component\Console\Input\InputArgument;
1817
use Symfony\Component\Console\Input\InputInterface;
1918
use Symfony\Component\Console\Input\InputOption;
@@ -48,19 +47,22 @@ protected function configure()
4847

4948
protected function execute(InputInterface $input, OutputInterface $output): int
5049
{
51-
if ($env = $input->getArgument('env')) {
52-
$_SERVER['APP_ENV'] = $env;
50+
$runtime = $this->options->get('runtime') ?? [];
51+
$envKey = $runtime['env_var_name'] ?? 'APP_ENV';
52+
53+
if ($env = $input->getArgument('env') ?? $runtime['env'] ?? null) {
54+
$_SERVER[$envKey] = $env;
5355
}
5456

55-
$path = $this->options->get('root-dir').'/.env';
57+
$path = $this->options->get('root-dir').'/'.($runtime['dotenv_path'] ?? '.env');
5658

5759
if (!$env || !$input->getOption('empty')) {
58-
$vars = $this->loadEnv($path, $env);
59-
$env = $vars['APP_ENV'];
60+
$vars = $this->loadEnv($path, $env, $runtime);
61+
$env = $vars[$envKey];
6062
}
6163

6264
if ($input->getOption('empty')) {
63-
$vars = ['APP_ENV' => $env];
65+
$vars = [$envKey => $env];
6466
}
6567

6668
$vars = var_export($vars, true);
@@ -79,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7981
return 0;
8082
}
8183

82-
private function loadEnv(string $path, ?string $env): array
84+
private function loadEnv(string $path, ?string $env, array $runtime): array
8385
{
8486
if (!file_exists($autoloadFile = $this->config->get('vendor-dir').'/autoload.php')) {
8587
throw new \RuntimeException(sprintf('Please run "composer install" before running this command: "%s" not found.', $autoloadFile));
@@ -91,9 +93,10 @@ private function loadEnv(string $path, ?string $env): array
9193
throw new \RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
9294
}
9395

96+
$envKey = $runtime['env_var_name'] ?? 'APP_ENV';
9497
$globalsBackup = [$_SERVER, $_ENV];
95-
unset($_SERVER['APP_ENV']);
96-
$_ENV = ['APP_ENV' => $env];
98+
unset($_SERVER[$envKey]);
99+
$_ENV = [$envKey => $env];
97100
$_SERVER['SYMFONY_DOTENV_VARS'] = implode(',', array_keys($_SERVER));
98101
putenv('SYMFONY_DOTENV_VARS='.$_SERVER['SYMFONY_DOTENV_VARS']);
99102

@@ -105,18 +108,17 @@ private function loadEnv(string $path, ?string $env): array
105108
}
106109

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

111114
if (!$env) {
112-
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.');
115+
throw new \RuntimeException(sprintf('Please provide the name of the environment either by passing it as command line argument or by defining the "%s" variable in the ".env.local" file.', $envKey));
113116
}
114117

115-
$config = @json_decode(file_get_contents(Factory::getComposerFile()), true);
116-
$testEnvs = $config['extra']['runtime']['test_envs'] ?? ['test'];
118+
$testEnvs = $runtime['test_envs'] ?? ['test'];
117119

118120
if (method_exists($dotenv, 'loadEnv')) {
119-
$dotenv->loadEnv($path, 'APP_ENV', 'dev', $testEnvs);
121+
$dotenv->loadEnv($path, $envKey, 'dev', $testEnvs);
120122
} else {
121123
// fallback code in case your Dotenv component is not 4.2 or higher (when loadEnv() was added)
122124
$dotenv->load(file_exists($path) || !file_exists($p = "$path.dist") ? $path : $p);

src/Command/InstallRecipesCommand.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Composer\Command\BaseCommand;
1515
use Composer\DependencyResolver\Operation\InstallOperation;
16+
use Composer\Util\ProcessExecutor;
1617
use Symfony\Component\Console\Exception\RuntimeException;
1718
use Symfony\Component\Console\Input\InputArgument;
1819
use Symfony\Component\Console\Input\InputInterface;
@@ -26,11 +27,13 @@ class InstallRecipesCommand extends BaseCommand
2627
/** @var Flex */
2728
private $flex;
2829
private $rootDir;
30+
private $dotenvPath;
2931

30-
public function __construct(/* cannot be type-hinted */ $flex, string $rootDir)
32+
public function __construct(/* cannot be type-hinted */ $flex, string $rootDir, string $dotenvPath = '.env')
3133
{
3234
$this->flex = $flex;
3335
$this->rootDir = $rootDir;
36+
$this->dotenvPath = $dotenvPath;
3437

3538
parent::__construct();
3639
}
@@ -120,12 +123,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
120123
$operations[] = new InstallOperation($pkg);
121124
}
122125

123-
if ($createEnvLocal = $force && file_exists($this->rootDir.'/.env') && file_exists($this->rootDir.'/.env.dist') && !file_exists($this->rootDir.'/.env.local')) {
124-
rename($this->rootDir.'/.env', $this->rootDir.'/.env.local');
126+
$dotenvFile = $this->dotenvPath;
127+
$dotenvPath = $this->rootDir.'/'.$dotenvFile;
128+
129+
if ($createEnvLocal = $force && file_exists($dotenvPath) && file_exists($dotenvPath.'.dist') && !file_exists($dotenvPath.'.local')) {
130+
rename($dotenvPath, $dotenvPath.'.local');
125131
$pipes = [];
126-
proc_close(proc_open(sprintf('git mv .env.dist .env > %s 2>&1 || %s .env.dist .env', $win ? 'NUL' : '/dev/null', $win ? 'rename' : 'mv'), $pipes, $pipes, $this->rootDir));
132+
proc_close(proc_open(sprintf('git mv %s %s > %s 2>&1 || %s %1$s %2$s', ProcessExecutor::escape($dotenvFile.'.dist'), ProcessExecutor::escape($dotenvFile), $win ? 'NUL' : '/dev/null', $win ? 'rename' : 'mv'), $pipes, $pipes, $this->rootDir));
127133
if (file_exists($this->rootDir.'/phpunit.xml.dist')) {
128-
touch($this->rootDir.'/.env.test');
134+
touch($dotenvPath.'.test');
129135
}
130136
}
131137

@@ -156,8 +162,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
156162
$output[] = '';
157163

158164
if ($createEnvLocal) {
165+
$root = '.' !== $this->rootDir ? $this->rootDir.'/' : '';
159166
$output[] = ' To revert the changes made to .env files, run';
160-
$output[] = sprintf(' <comment>git mv %s.env %1$s.env.dist</> && <comment>%s %1$s.env.local %1$s.env</>', '.' !== $this->rootDir ? $this->rootDir.'/' : '', $win ? 'rename' : 'mv');
167+
$output[] = sprintf(' <comment>git mv %s %s</> && <comment>%s %s %1$s</>', ProcessExecutor::escape($root.$dotenvFile), ProcessExecutor::escape($root.$dotenvFile.'.dist'), $win ? 'rename' : 'mv', ProcessExecutor::escape($root.$dotenvFile.'.local'));
161168
$output[] = '';
162169
}
163170

src/Configurator/EnvConfigurator.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function configure(Recipe $recipe, $vars, Lock $lock, array $options = []
2525
$this->write('Adding environment variable defaults');
2626

2727
$this->configureEnvDist($recipe, $vars, $options['force'] ?? false);
28-
if (!file_exists($this->options->get('root-dir').'/.env.test')) {
28+
if (!file_exists($this->options->get('root-dir').'/'.($this->options->get('runtime')['dotenv_path'] ?? '.env').'.test')) {
2929
$this->configurePhpUnit($recipe, $vars, $options['force'] ?? false);
3030
}
3131
}
@@ -49,7 +49,9 @@ public function update(RecipeUpdate $recipeUpdate, array $originalConfig, array
4949

5050
private function configureEnvDist(Recipe $recipe, $vars, bool $update)
5151
{
52-
foreach (['.env.dist', '.env'] as $file) {
52+
$dotenvPath = $this->options->get('runtime')['dotenv_path'] ?? '.env';
53+
54+
foreach ([$dotenvPath.'.dist', $dotenvPath] as $file) {
5355
$env = $this->options->get('root-dir').'/'.$file;
5456
if (!is_file($env)) {
5557
continue;
@@ -133,7 +135,9 @@ private function configurePhpUnit(Recipe $recipe, $vars, bool $update)
133135

134136
private function unconfigureEnvFiles(Recipe $recipe, $vars)
135137
{
136-
foreach (['.env', '.env.dist'] as $file) {
138+
$dotenvPath = $this->options->get('runtime')['dotenv_path'] ?? '.env';
139+
140+
foreach ([$dotenvPath, $dotenvPath.'.dist'] as $file) {
137141
$env = $this->options->get('root-dir').'/'.$file;
138142
if (!file_exists($env)) {
139143
continue;
@@ -200,7 +204,8 @@ private function generateRandomBytes($length = 16)
200204

201205
private function getContentsAfterApplyingRecipe(string $rootDir, Recipe $recipe, array $vars): array
202206
{
203-
$files = ['.env', '.env.dist', 'phpunit.xml.dist', 'phpunit.xml'];
207+
$dotenvPath = $this->options->get('runtime')['dotenv_path'] ?? '.env';
208+
$files = [$dotenvPath, $dotenvPath.'.dist', 'phpunit.xml.dist', 'phpunit.xml'];
204209

205210
if (0 === \count($vars)) {
206211
return array_fill_keys($files, null);
@@ -217,7 +222,7 @@ private function getContentsAfterApplyingRecipe(string $rootDir, Recipe $recipe,
217222
true
218223
);
219224

220-
if (!file_exists($rootDir.'/.env.test')) {
225+
if (!file_exists($rootDir.'/'.$dotenvPath.'.test')) {
221226
$this->configurePhpUnit(
222227
$recipe,
223228
$vars,

src/Configurator/MakefileConfigurator.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ private function configureMakefile(Recipe $recipe, array $definitions, bool $upd
7171
$data = "\n".ltrim($data, "\r\n");
7272

7373
if (!file_exists($makefile)) {
74+
$envKey = $this->options->get('runtime')['env_var_name'] ?? 'APP_ENV';
75+
$dotenvPath = $this->options->get('runtime')['dotenv_path'] ?? '.env';
7476
file_put_contents(
7577
$this->options->get('root-dir').'/Makefile',
7678
<<<EOF
77-
ifndef APP_ENV
78-
include .env
79+
ifndef {$envKey}
80+
include {$dotenvPath}
7981
endif
8082
8183
.DEFAULT_GOAL := help

src/Flex.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ class_exists(__NAMESPACE__.str_replace('/', '\\', substr($file, \strlen(__DIR__)
276276
$app->add(new Command\RemoveCommand($resolver));
277277
$app->add(new Command\UnpackCommand($resolver));
278278
$app->add(new Command\RecipesCommand($this, $this->lock, $rfs));
279-
$app->add(new Command\InstallRecipesCommand($this, $this->options->get('root-dir')));
279+
$app->add(new Command\InstallRecipesCommand($this, $this->options->get('root-dir'), $this->options->get('runtime')['dotenv_path'] ?? '.env'));
280280
$app->add(new Command\UpdateRecipesCommand($this, $this->downloader, $rfs, $this->configurator, $this->options->get('root-dir')));
281281
if (class_exists(Command\GenerateIdCommand::class)) {
282282
$app->add(new Command\GenerateIdCommand(null));
@@ -391,9 +391,11 @@ public function update(Event $event, $operations = [])
391391
public function install(Event $event)
392392
{
393393
$rootDir = $this->options->get('root-dir');
394+
$runtime = $this->options->get('runtime');
395+
$dotenvPath = $rootDir.'/'.($runtime['dotenv_path'] ?? '.env');
394396

395-
if (!file_exists("$rootDir/.env") && !file_exists("$rootDir/.env.local") && file_exists("$rootDir/.env.dist") && false === strpos(file_get_contents("$rootDir/.env.dist"), '.env.local')) {
396-
copy($rootDir.'/.env.dist', $rootDir.'/.env');
397+
if (!file_exists($dotenvPath) && !file_exists($dotenvPath.'.local') && file_exists($dotenvPath.'.dist') && false === strpos(file_get_contents($dotenvPath.'.dist'), '.env.local')) {
398+
copy($dotenvPath.'.dist', $dotenvPath);
397399
}
398400

399401
// Execute missing recipes
@@ -829,6 +831,7 @@ private function initOptions(): Options
829831
'var-dir' => 'var',
830832
'public-dir' => 'public',
831833
'root-dir' => $extra['symfony']['root-dir'] ?? '.',
834+
'runtime' => $extra['runtime'] ?? [],
832835
], $extra);
833836

834837
return new Options($options, $this->io);

tests/Command/DumpEnvCommandTest.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ public function testLoadLocalEnvWhenTestEnvIsNotEqual()
174174
$env = FLEX_TEST_DIR.'/.env';
175175
$envLocal = FLEX_TEST_DIR.'/.env.local';
176176
$envLocalPhp = FLEX_TEST_DIR.'/.env.local.php';
177-
$composer = FLEX_TEST_DIR.'/composer.json';
178177

179178
@unlink($envLocalPhp);
180179

@@ -184,9 +183,8 @@ public function testLoadLocalEnvWhenTestEnvIsNotEqual()
184183
APP_SECRET=abcdefgh123456789
185184
EOF
186185
);
187-
file_put_contents(FLEX_TEST_DIR.'/composer.json', '{"extra":{"runtime":{"test_envs":[]}}}');
188186

189-
$command = $this->createCommandDumpEnv();
187+
$command = $this->createCommandDumpEnv(['runtime' => ['test_envs' => []]]);
190188
$command->execute([
191189
'env' => 'test',
192190
]);
@@ -202,14 +200,13 @@ public function testLoadLocalEnvWhenTestEnvIsNotEqual()
202200
unlink($env);
203201
unlink($envLocal);
204202
unlink($envLocalPhp);
205-
unlink($composer);
206203
}
207204

208-
private function createCommandDumpEnv()
205+
private function createCommandDumpEnv(array $options = [])
209206
{
210207
$command = new DumpEnvCommand(
211208
new Config(false, __DIR__.'/../..'),
212-
new Options(['root-dir' => FLEX_TEST_DIR])
209+
new Options($options + ['root-dir' => FLEX_TEST_DIR])
213210
);
214211

215212
$application = new Application();

0 commit comments

Comments
 (0)