mirror of
https://github.com/symfony/dotenv.git
synced 2026-03-23 23:52:14 +01:00
Merge branch '7.4' into 8.0
* 7.4: prioritize property type over is/has/can accessors [Dotenv] Windows-related tweak [Dotenv] Use `APP_RUNTIME_OPTIONS` variable when dumping dotenv
This commit is contained in:
@@ -32,7 +32,7 @@ final class DebugCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
private string $kernelEnvironment,
|
||||
private string $projectDirectory,
|
||||
private string $projectDir,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -67,29 +67,17 @@ final class DebugCommand extends Command
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!$filePath = $_SERVER['SYMFONY_DOTENV_PATH'] ?? null) {
|
||||
$dotenvPath = $this->projectDirectory;
|
||||
$dotenvPath = $this->getDotenvPath();
|
||||
|
||||
if (is_file($composerFile = $this->projectDirectory.'/composer.json')) {
|
||||
$runtimeConfig = json_decode(file_get_contents($composerFile), true)['extra']['runtime'] ?? [];
|
||||
|
||||
if (isset($runtimeConfig['dotenv_path'])) {
|
||||
$dotenvPath = $this->projectDirectory.'/'.$runtimeConfig['dotenv_path'];
|
||||
}
|
||||
}
|
||||
|
||||
$filePath = $dotenvPath.'/.env';
|
||||
}
|
||||
|
||||
$envFiles = $this->getEnvFiles($filePath);
|
||||
$envFiles = $this->getEnvFiles($dotenvPath);
|
||||
$availableFiles = array_filter($envFiles, 'is_file');
|
||||
|
||||
if (\in_array(\sprintf('%s.local.php', $filePath), $availableFiles, true)) {
|
||||
$io->warning(\sprintf('Due to existing dump file (%s.local.php) all other dotenv files are skipped.', $this->getRelativeName($filePath)));
|
||||
if (\in_array(\sprintf('%s.local.php', $dotenvPath), $availableFiles, true)) {
|
||||
$io->warning(\sprintf('Due to existing dump file (%s.local.php) all other dotenv files are skipped.', $this->getRelativeName($dotenvPath)));
|
||||
}
|
||||
|
||||
if (is_file($filePath) && is_file(\sprintf('%s.dist', $filePath))) {
|
||||
$io->warning(\sprintf('The file %s.dist gets skipped due to the existence of %1$s.', $this->getRelativeName($filePath)));
|
||||
if (is_file($dotenvPath) && is_file(\sprintf('%s.dist', $dotenvPath))) {
|
||||
$io->warning(\sprintf('The file %s.dist gets skipped due to the existence of %1$s.', $this->getRelativeName($dotenvPath)));
|
||||
}
|
||||
|
||||
$io->section('Scanned Files (in descending priority)');
|
||||
@@ -165,12 +153,27 @@ final class DebugCommand extends Command
|
||||
|
||||
private function getAvailableVars(): array
|
||||
{
|
||||
$filePath = $_SERVER['SYMFONY_DOTENV_PATH'] ?? $this->projectDirectory.\DIRECTORY_SEPARATOR.'.env';
|
||||
$envFiles = $this->getEnvFiles($filePath);
|
||||
$envFiles = $this->getEnvFiles($this->getDotenvPath());
|
||||
|
||||
return array_keys($this->getVariables(array_filter($envFiles, 'is_file'), null));
|
||||
}
|
||||
|
||||
private function getDotenvPath(): string
|
||||
{
|
||||
$config = [];
|
||||
$projectDir = $this->projectDir;
|
||||
|
||||
if (is_file($projectDir)) {
|
||||
$config = ['dotenv_path' => basename($projectDir)];
|
||||
$projectDir = \dirname($projectDir);
|
||||
}
|
||||
|
||||
$composerFile = $projectDir.'/composer.json';
|
||||
$config += $_SERVER['APP_RUNTIME_OPTIONS'] ?? (is_file($composerFile) ? json_decode(file_get_contents($composerFile), true) : [])['extra']['runtime'] ?? [];
|
||||
|
||||
return $projectDir.'/'.($config['dotenv_path'] ?? '.env');
|
||||
}
|
||||
|
||||
private function getEnvFiles(string $filePath): array
|
||||
{
|
||||
$files = [
|
||||
@@ -194,8 +197,10 @@ final class DebugCommand extends Command
|
||||
|
||||
private function getRelativeName(string $filePath): string
|
||||
{
|
||||
if (str_starts_with($filePath, $this->projectDirectory)) {
|
||||
return substr($filePath, \strlen($this->projectDirectory) + 1);
|
||||
$projectDir = is_file($this->projectDir) ? \dirname($this->projectDir) : $this->projectDir;
|
||||
|
||||
if (str_starts_with($filePath, $projectDir.'/') || str_starts_with($filePath, $projectDir.\DIRECTORY_SEPARATOR)) {
|
||||
return substr($filePath, \strlen($projectDir) + 1);
|
||||
}
|
||||
|
||||
return basename($filePath);
|
||||
|
||||
@@ -61,14 +61,8 @@ final class DotenvDumpCommand extends Command
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$config = [];
|
||||
if (is_file($projectDir = $this->projectDir)) {
|
||||
$config = ['dotenv_path' => basename($projectDir)];
|
||||
$projectDir = \dirname($projectDir);
|
||||
}
|
||||
$dotenvPath = $this->getDotenvPath($config);
|
||||
|
||||
$composerFile = $projectDir.'/composer.json';
|
||||
$config += (is_file($composerFile) ? json_decode(file_get_contents($composerFile), true) : [])['extra']['runtime'] ?? [];
|
||||
$dotenvPath = $projectDir.'/'.($config['dotenv_path'] ?? '.env');
|
||||
$env = $input->getArgument('env') ?? $this->defaultEnv;
|
||||
$envKey = $config['env_var_name'] ?? 'APP_ENV';
|
||||
|
||||
@@ -90,11 +84,27 @@ final class DotenvDumpCommand extends Command
|
||||
EOF;
|
||||
file_put_contents($dotenvPath.'.local.php', $vars, \LOCK_EX);
|
||||
|
||||
$output->writeln(\sprintf('Successfully dumped .env files in <info>.env.local.php</> for the <info>%s</> environment.', $env));
|
||||
$output->writeln(\sprintf('Successfully dumped %s files in <info>%1$s.local.php</> for the <info>%s</> environment.', basename($dotenvPath), $env));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function getDotenvPath(array &$config): string
|
||||
{
|
||||
$config = [];
|
||||
$projectDir = $this->projectDir;
|
||||
|
||||
if (is_file($projectDir)) {
|
||||
$config = ['dotenv_path' => basename($projectDir)];
|
||||
$projectDir = \dirname($projectDir);
|
||||
}
|
||||
|
||||
$composerFile = $projectDir.'/composer.json';
|
||||
$config += $_SERVER['APP_RUNTIME_OPTIONS'] ?? (is_file($composerFile) ? json_decode(file_get_contents($composerFile), true) : [])['extra']['runtime'] ?? [];
|
||||
|
||||
return $projectDir.'/'.($config['dotenv_path'] ?? '.env');
|
||||
}
|
||||
|
||||
private function loadEnv(string $dotenvPath, string $env, array $config): array
|
||||
{
|
||||
$envKey = $config['env_var_name'] ?? 'APP_ENV';
|
||||
|
||||
@@ -290,6 +290,14 @@ class DebugCommandTest extends TestCase
|
||||
|
||||
private function executeCommand(string $projectDirectory, string $env, array $input = [], ?string $dotenvPath = null): string
|
||||
{
|
||||
if (null === $dotenvPath) {
|
||||
unset($_SERVER['APP_RUNTIME_OPTIONS']);
|
||||
} elseif (str_starts_with($dotenvPath, $projectDirectory.'/')) {
|
||||
$_SERVER['APP_RUNTIME_OPTIONS'] = ['dotenv_path' => substr($dotenvPath, \strlen($projectDirectory) + 1)];
|
||||
} else {
|
||||
$_SERVER['APP_RUNTIME_OPTIONS'] = ['dotenv_path' => $dotenvPath];
|
||||
}
|
||||
|
||||
$_SERVER['TEST_ENV_KEY'] = $env;
|
||||
(new Dotenv('TEST_ENV_KEY'))->bootEnv($dotenvPath ?? $projectDirectory.'/.env');
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ class DotenvDumpCommandTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
unset($_SERVER['SYMFONY_DOTENV_PATH']);
|
||||
unset($_SERVER['APP_RUNTIME_OPTIONS']);
|
||||
|
||||
file_put_contents(__DIR__.'/.env', <<<EOF
|
||||
APP_ENV=dev
|
||||
APP_SECRET=abc123
|
||||
@@ -36,8 +39,14 @@ class DotenvDumpCommandTest extends TestCase
|
||||
{
|
||||
@unlink(__DIR__.'/.env');
|
||||
@unlink(__DIR__.'/.env.local');
|
||||
@unlink(__DIR__.'/.env.path');
|
||||
@unlink(__DIR__.'/.env.path.local');
|
||||
@unlink(__DIR__.'/.env.local.php');
|
||||
@unlink(__DIR__.'/.env.path.local.php');
|
||||
@unlink(__DIR__.'/composer.json');
|
||||
|
||||
unset($_SERVER['SYMFONY_DOTENV_PATH']);
|
||||
unset($_SERVER['APP_RUNTIME_OPTIONS']);
|
||||
}
|
||||
|
||||
public function testExecute()
|
||||
@@ -92,6 +101,35 @@ class DotenvDumpCommandTest extends TestCase
|
||||
], $vars);
|
||||
}
|
||||
|
||||
public function testExecuteWithRuntimeOptionsDotenvPath()
|
||||
{
|
||||
file_put_contents(__DIR__.'/.env.path', <<<EOF
|
||||
APP_ENV=test
|
||||
APP_SECRET=newpath123
|
||||
EOF
|
||||
);
|
||||
file_put_contents(__DIR__.'/.env.path.local', <<<EOF
|
||||
LOCAL_PATH=yes
|
||||
EOF
|
||||
);
|
||||
|
||||
$_SERVER['APP_RUNTIME_OPTIONS'] = ['dotenv_path' => '.env.path'];
|
||||
|
||||
$command = $this->createCommand();
|
||||
$command->execute([
|
||||
'env' => 'dev',
|
||||
]);
|
||||
|
||||
$this->assertFileExists(__DIR__.'/.env.path.local.php');
|
||||
|
||||
$vars = require __DIR__.'/.env.path.local.php';
|
||||
$this->assertSame([
|
||||
'APP_ENV' => 'dev',
|
||||
'APP_SECRET' => 'newpath123',
|
||||
'LOCAL_PATH' => 'yes',
|
||||
], $vars);
|
||||
}
|
||||
|
||||
private function createCommand(): CommandTester
|
||||
{
|
||||
$application = new Application();
|
||||
|
||||
Reference in New Issue
Block a user