Skip to content

Commit

Permalink
Merge branch '6.4' into 7.0
Browse files Browse the repository at this point in the history
* 6.4:
  show overridden vars too
  Bump Symfony version to 6.4.8
  Update VERSION for 6.4.7
  Update CHANGELOG for 6.4.7
  Bump Symfony version to 5.4.40
  Update VERSION for 5.4.39
  Update CONTRIBUTORS for 5.4.39
  Update CHANGELOG for 5.4.39
  [FrameworkBundle] Fix indentation
  • Loading branch information
nicolas-grekas committed Apr 29, 2024
2 parents 0fd573c + 5faf09c commit c37515b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 53 deletions.
114 changes: 61 additions & 53 deletions Command/DebugCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -29,14 +30,10 @@
#[AsCommand(name: 'debug:dotenv', description: 'List all dotenv files with variables and values')]
final class DebugCommand extends Command
{
private string $kernelEnvironment;
private string $projectDirectory;

public function __construct(string $kernelEnvironment, string $projectDirectory)
{
$this->kernelEnvironment = $kernelEnvironment;
$this->projectDirectory = $projectDirectory;

public function __construct(
private string $kernelEnvironment,
private string $projectDirectory,
) {
parent::__construct();
}

Expand Down Expand Up @@ -70,21 +67,23 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return 1;
}

$envFiles = $this->getEnvFiles();
$availableFiles = array_filter($envFiles, fn (string $file) => is_file($this->getFilePath($file)));
$filePath = $_SERVER['SYMFONY_DOTENV_PATH'] ?? $this->projectDirectory.\DIRECTORY_SEPARATOR.'.env';

if (\in_array('.env.local.php', $availableFiles, true)) {
$io->warning('Due to existing dump file (.env.local.php) all other dotenv files are skipped.');
$envFiles = $this->getEnvFiles($filePath);
$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 (is_file($this->getFilePath('.env')) && is_file($this->getFilePath('.env.dist'))) {
$io->warning('The file .env.dist gets skipped due to the existence of .env.');
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)));
}

$io->section('Scanned Files (in descending priority)');
$io->listing(array_map(static fn (string $envFile) => \in_array($envFile, $availableFiles, true)
? sprintf('<fg=green>✓</> %s', $envFile)
: sprintf('<fg=red>⨯</> %s', $envFile), $envFiles));
$io->listing(array_map(fn (string $envFile) => \in_array($envFile, $availableFiles, true)
? sprintf('<fg=green>✓</> %s', $this->getRelativeName($envFile))
: sprintf('<fg=red>⨯</> %s', $this->getRelativeName($envFile)), $envFiles));

$nameFilter = $input->getArgument('filter');
$variables = $this->getVariables($availableFiles, $nameFilter);
Expand All @@ -93,8 +92,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if ($variables || null === $nameFilter) {
$io->table(
array_merge(['Variable', 'Value'], $availableFiles),
$this->getVariables($availableFiles, $nameFilter)
array_merge(['Variable', 'Value'], array_map($this->getRelativeName(...), $availableFiles)),
$variables
);

$io->comment('Note that values might be different between web and CLI.');
Expand All @@ -114,75 +113,84 @@ public function complete(CompletionInput $input, CompletionSuggestions $suggesti

private function getVariables(array $envFiles, ?string $nameFilter): array
{
$vars = $this->getAvailableVars();

$output = [];
$variables = [];
$fileValues = [];
foreach ($vars as $var) {
$dotenvVars = array_flip(explode(',', $_SERVER['SYMFONY_DOTENV_VARS'] ?? ''));

foreach ($envFiles as $envFile) {
$fileValues[$envFile] = $this->loadValues($envFile);
$variables += $fileValues[$envFile];
}

foreach ($variables as $var => $varDetails) {
if (null !== $nameFilter && 0 !== stripos($var, $nameFilter)) {
unset($variables[$var]);
continue;
}

$realValue = $_SERVER[$var];
$varDetails = [$var, $realValue];
foreach ($envFiles as $envFile) {
$values = $fileValues[$envFile] ??= $this->loadValues($envFile);
$varDetails = [$var, '<fg=green>'.OutputFormatter::escape($realValue).'</>'];
$varSeen = !isset($dotenvVars[$var]);

$varString = $values[$var] ?? '<fg=yellow>n/a</>';
$shortenedVar = $this->getHelper('formatter')->truncate($varString, 30);
$varDetails[] = $varString === $realValue ? '<fg=green>'.$shortenedVar.'</>' : $shortenedVar;
foreach ($envFiles as $envFile) {
if (null === $value = $fileValues[$envFile][$var] ?? null) {
$varDetails[] = '<fg=yellow>n/a</>';
continue;
}

$shortenedValue = OutputFormatter::escape($this->getHelper('formatter')->truncate($value, 30));
$varDetails[] = $value === $realValue && !$varSeen ? '<fg=green>'.$shortenedValue.'</>' : $shortenedValue;
$varSeen = $varSeen || $value === $realValue;
}

$output[] = $varDetails;
$variables[$var] = $varDetails;
}

return $output;
ksort($variables);

return $variables;
}

private function getAvailableVars(): array
{
$dotenvVars = $_SERVER['SYMFONY_DOTENV_VARS'] ?? '';

if ('' === $dotenvVars) {
return [];
}
$filePath = $_SERVER['SYMFONY_DOTENV_PATH'] ?? $this->projectDirectory.\DIRECTORY_SEPARATOR.'.env';
$envFiles = $this->getEnvFiles($filePath);

$vars = explode(',', $dotenvVars);
sort($vars);

return $vars;
return array_keys($this->getVariables(array_filter($envFiles, 'is_file'), null));
}

private function getEnvFiles(): array
private function getEnvFiles(string $filePath): array
{
$files = [
'.env.local.php',
sprintf('.env.%s.local', $this->kernelEnvironment),
sprintf('.env.%s', $this->kernelEnvironment),
sprintf('%s.local.php', $filePath),
sprintf('%s.%s.local', $filePath, $this->kernelEnvironment),
sprintf('%s.%s', $filePath, $this->kernelEnvironment),
];

if ('test' !== $this->kernelEnvironment) {
$files[] = '.env.local';
$files[] = sprintf('%s.local', $filePath);
}

if (!is_file($this->getFilePath('.env')) && is_file($this->getFilePath('.env.dist'))) {
$files[] = '.env.dist';
if (!is_file($filePath) && is_file(sprintf('%s.dist', $filePath))) {
$files[] = sprintf('%s.dist', $filePath);
} else {
$files[] = '.env';
$files[] = $filePath;
}

return $files;
}

private function getFilePath(string $file): string
private function getRelativeName(string $filePath): string
{
return $this->projectDirectory.\DIRECTORY_SEPARATOR.$file;
if (str_starts_with($filePath, $this->projectDirectory)) {
return substr($filePath, \strlen($this->projectDirectory) + 1);
}

return basename($filePath);
}

private function loadValues(string $file): array
private function loadValues(string $filePath): array
{
$filePath = $this->getFilePath($file);

if (str_ends_with($filePath, '.php')) {
return include $filePath;
}
Expand Down
3 changes: 3 additions & 0 deletions Tests/Command/DebugCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public function testEmptyDotEnvVarsList()
---------- ------- ------------ ------%S
Variable Value .env.local .env%S
---------- ------- ------------ ------%S
FOO baz bar%S
TEST123 n/a true%S
---------- ------- ------------ ------%S
// Note that values might be different between web and CLI.%S
%a
Expand Down

0 comments on commit c37515b

Please sign in to comment.