feature #27684 [FrameworkBundle] Debug container environment variables (ro0NL)
This PR was squashed before being merged into the 4.3-dev branch (closes #27684).
Discussion
----------
[FrameworkBundle] Debug container environment variables
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | no
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!-- required for new features -->
This PR is an attempt to ease debugging environment variables used by the container. Main purpose is to tell which are missing and show detailed usage information.
![image](https://user-images.githubusercontent.com/1047696/47601226-ae43c480-d9cd-11e8-926b-8c49069189fc.png)
![image](https://user-images.githubusercontent.com/1047696/47601234-d7645500-d9cd-11e8-9e3f-d1c2ad85dbc5.png)
Commits
-------
b813a05aa5
[FrameworkBundle] Debug container environment variables
This commit is contained in:
commit
47a2f58421
@ -58,6 +58,8 @@ class ContainerDebugCommand extends Command
|
|||||||
new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Displays a specific parameter for an application'),
|
new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Displays a specific parameter for an application'),
|
||||||
new InputOption('parameters', null, InputOption::VALUE_NONE, 'Displays parameters for an application'),
|
new InputOption('parameters', null, InputOption::VALUE_NONE, 'Displays parameters for an application'),
|
||||||
new InputOption('types', null, InputOption::VALUE_NONE, 'Displays types (classes/interfaces) available in the container'),
|
new InputOption('types', null, InputOption::VALUE_NONE, 'Displays types (classes/interfaces) available in the container'),
|
||||||
|
new InputOption('env-var', null, InputOption::VALUE_REQUIRED, 'Displays a specific environment variable used in the container'),
|
||||||
|
new InputOption('env-vars', null, InputOption::VALUE_NONE, 'Displays environment variables used in the container'),
|
||||||
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
|
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
|
||||||
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
|
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
|
||||||
])
|
])
|
||||||
@ -75,6 +77,14 @@ To see available types that can be used for autowiring, use the <info>--types</i
|
|||||||
|
|
||||||
<info>php %command.full_name% --types</info>
|
<info>php %command.full_name% --types</info>
|
||||||
|
|
||||||
|
To see environment variables used by the container, use the <info>--env-vars</info> flag:
|
||||||
|
|
||||||
|
<info>php %command.full_name% --env-vars</info>
|
||||||
|
|
||||||
|
Display a specific environment variable by specifying its name with the <info>--env-var</info> option:
|
||||||
|
|
||||||
|
<info>php %command.full_name% --env-var=APP_ENV</info>
|
||||||
|
|
||||||
Use the --tags option to display tagged <comment>public</comment> services grouped by tag:
|
Use the --tags option to display tagged <comment>public</comment> services grouped by tag:
|
||||||
|
|
||||||
<info>php %command.full_name% --tags</info>
|
<info>php %command.full_name% --tags</info>
|
||||||
@ -116,7 +126,11 @@ EOF
|
|||||||
$this->validateInput($input);
|
$this->validateInput($input);
|
||||||
$object = $this->getContainerBuilder();
|
$object = $this->getContainerBuilder();
|
||||||
|
|
||||||
if ($input->getOption('types')) {
|
if ($input->getOption('env-vars')) {
|
||||||
|
$options = ['env-vars' => true];
|
||||||
|
} elseif ($envVar = $input->getOption('env-var')) {
|
||||||
|
$options = ['env-vars' => true, 'name' => $envVar];
|
||||||
|
} elseif ($input->getOption('types')) {
|
||||||
$options = [];
|
$options = [];
|
||||||
$options['filter'] = [$this, 'filterToServiceTypes'];
|
$options['filter'] = [$this, 'filterToServiceTypes'];
|
||||||
} elseif ($input->getOption('parameters')) {
|
} elseif ($input->getOption('parameters')) {
|
||||||
@ -156,7 +170,7 @@ EOF
|
|||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && $input->isInteractive()) {
|
if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && !$input->getOption('env-vars') && !$input->getOption('env-var') && $input->isInteractive()) {
|
||||||
if ($input->getOption('tags')) {
|
if ($input->getOption('tags')) {
|
||||||
$errorIo->comment('To search for a specific tag, re-run this command with a search term. (e.g. <comment>debug:container --tag=form.type</comment>)');
|
$errorIo->comment('To search for a specific tag, re-run this command with a search term. (e.g. <comment>debug:container --tag=form.type</comment>)');
|
||||||
} elseif ($input->getOption('parameters')) {
|
} elseif ($input->getOption('parameters')) {
|
||||||
@ -209,12 +223,15 @@ EOF
|
|||||||
if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
|
if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
|
||||||
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
|
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
|
||||||
$container = $buildContainer();
|
$container = $buildContainer();
|
||||||
$container->getCompilerPassConfig()->setRemovingPasses([]);
|
|
||||||
$container->compile();
|
|
||||||
} else {
|
} else {
|
||||||
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
|
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
|
||||||
|
$container->setParameter('container.build_hash', $hash = ContainerBuilder::hash(__METHOD__));
|
||||||
|
$container->setParameter('container.build_id', hash('crc32', $hash.time()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$container->getCompilerPassConfig()->setRemovingPasses([]);
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
return $this->containerBuilder = $container;
|
return $this->containerBuilder = $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,9 @@ abstract class Descriptor implements DescriptorInterface
|
|||||||
case $object instanceof ParameterBag:
|
case $object instanceof ParameterBag:
|
||||||
$this->describeContainerParameters($object, $options);
|
$this->describeContainerParameters($object, $options);
|
||||||
break;
|
break;
|
||||||
|
case $object instanceof ContainerBuilder && !empty($options['env-vars']):
|
||||||
|
$this->describeContainerEnvVars($this->getContainerEnvVars($object), $options);
|
||||||
|
break;
|
||||||
case $object instanceof ContainerBuilder && isset($options['group_by']) && 'tags' === $options['group_by']:
|
case $object instanceof ContainerBuilder && isset($options['group_by']) && 'tags' === $options['group_by']:
|
||||||
$this->describeContainerTags($object, $options);
|
$this->describeContainerTags($object, $options);
|
||||||
break;
|
break;
|
||||||
@ -157,6 +160,11 @@ abstract class Descriptor implements DescriptorInterface
|
|||||||
*/
|
*/
|
||||||
abstract protected function describeContainerParameter($parameter, array $options = []);
|
abstract protected function describeContainerParameter($parameter, array $options = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes container environment variables.
|
||||||
|
*/
|
||||||
|
abstract protected function describeContainerEnvVars(array $envs, array $options = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes event dispatcher listeners.
|
* Describes event dispatcher listeners.
|
||||||
*
|
*
|
||||||
@ -311,4 +319,35 @@ abstract class Descriptor implements DescriptorInterface
|
|||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getContainerEnvVars(ContainerBuilder $container): array
|
||||||
|
{
|
||||||
|
$getEnvReflection = new \ReflectionMethod($container, 'getEnv');
|
||||||
|
$getEnvReflection->setAccessible(true);
|
||||||
|
$envs = [];
|
||||||
|
foreach (array_keys($container->getEnvCounters()) as $env) {
|
||||||
|
$processor = 'string';
|
||||||
|
if (false !== $i = strrpos($name = $env, ':')) {
|
||||||
|
$name = substr($env, $i + 1);
|
||||||
|
$processor = substr($env, 0, $i);
|
||||||
|
}
|
||||||
|
$defaultValue = ($hasDefault = $container->hasParameter("env($name)")) ? $container->getParameter("env($name)") : null;
|
||||||
|
if (false === ($runtimeValue = $_ENV[$name] ?? $_SERVER[$name] ?? getenv($name))) {
|
||||||
|
$runtimeValue = null;
|
||||||
|
}
|
||||||
|
$processedValue = ($hasRuntime = null !== $runtimeValue) || $hasDefault ? $getEnvReflection->invoke($container, $env) : null;
|
||||||
|
$envs[$name.$processor] = [
|
||||||
|
'name' => $name,
|
||||||
|
'processor' => $processor,
|
||||||
|
'default_available' => $hasDefault,
|
||||||
|
'default_value' => $defaultValue,
|
||||||
|
'runtime_available' => $hasRuntime,
|
||||||
|
'runtime_value' => $runtimeValue,
|
||||||
|
'processed_value' => $processedValue,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
ksort($envs);
|
||||||
|
|
||||||
|
return array_values($envs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Exception\LogicException;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -177,6 +178,14 @@ class JsonDescriptor extends Descriptor
|
|||||||
$this->writeData([$key => $parameter], $options);
|
$this->writeData([$key => $parameter], $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function describeContainerEnvVars(array $envs, array $options = [])
|
||||||
|
{
|
||||||
|
throw new LogicException('Using the JSON format to debug environment variables is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes data as json.
|
* Writes data as json.
|
||||||
*
|
*
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Exception\LogicException;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
@ -273,6 +274,14 @@ class MarkdownDescriptor extends Descriptor
|
|||||||
$this->write(isset($options['parameter']) ? sprintf("%s\n%s\n\n%s", $options['parameter'], str_repeat('=', \strlen($options['parameter'])), $this->formatParameter($parameter)) : $parameter);
|
$this->write(isset($options['parameter']) ? sprintf("%s\n%s\n\n%s", $options['parameter'], str_repeat('=', \strlen($options['parameter'])), $this->formatParameter($parameter)) : $parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function describeContainerEnvVars(array $envs, array $options = [])
|
||||||
|
{
|
||||||
|
throw new LogicException('Using the markdown format to debug environment variables is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
||||||
|
|
||||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||||
|
use Symfony\Component\Console\Helper\Dumper;
|
||||||
use Symfony\Component\Console\Helper\Table;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
@ -384,6 +385,71 @@ class TextDescriptor extends Descriptor
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function describeContainerEnvVars(array $envs, array $options = [])
|
||||||
|
{
|
||||||
|
$dump = new Dumper($this->output);
|
||||||
|
$options['output']->title('Symfony Container Environment Variables');
|
||||||
|
|
||||||
|
if (null !== $name = $options['name'] ?? null) {
|
||||||
|
$options['output']->comment('Displaying detailed environment variable usage matching '.$name);
|
||||||
|
|
||||||
|
$matches = false;
|
||||||
|
foreach ($envs as $env) {
|
||||||
|
if ($name === $env['name'] || false !== stripos($env['name'], $name)) {
|
||||||
|
$matches = true;
|
||||||
|
$options['output']->section('%env('.$env['processor'].':'.$env['name'].')%');
|
||||||
|
$options['output']->table([], [
|
||||||
|
['<info>Default value</>', $env['default_available'] ? $dump($env['default_value']) : 'n/a'],
|
||||||
|
['<info>Real value</>', $env['runtime_available'] ? $dump($env['runtime_value']) : 'n/a'],
|
||||||
|
['<info>Processed value</>', $env['default_available'] || $env['runtime_available'] ? $dump($env['processed_value']) : 'n/a'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$matches) {
|
||||||
|
$options['output']->block('None of the environment variables match this name.');
|
||||||
|
} else {
|
||||||
|
$options['output']->comment('Note real values might be different between web and CLI.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$envs) {
|
||||||
|
$options['output']->block('No environment variables are being used.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
$missing = [];
|
||||||
|
foreach ($envs as $env) {
|
||||||
|
if (isset($rows[$env['name']])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[$env['name']] = [
|
||||||
|
$env['name'],
|
||||||
|
$env['default_available'] ? $dump($env['default_value']) : 'n/a',
|
||||||
|
$env['runtime_available'] ? $dump($env['runtime_value']) : 'n/a',
|
||||||
|
];
|
||||||
|
if (!$env['default_available'] && !$env['runtime_available']) {
|
||||||
|
$missing[$env['name']] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$options['output']->table(['Name', 'Default value', 'Real value'], $rows);
|
||||||
|
$options['output']->comment('Note real values might be different between web and CLI.');
|
||||||
|
|
||||||
|
if ($missing) {
|
||||||
|
$options['output']->warning('The following variables are missing:');
|
||||||
|
$options['output']->listing(array_keys($missing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Exception\LogicException;
|
||||||
use Symfony\Component\DependencyInjection\Alias;
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||||
@ -131,6 +132,14 @@ class XmlDescriptor extends Descriptor
|
|||||||
$this->writeDocument($this->getContainerParameterDocument($parameter, $options));
|
$this->writeDocument($this->getContainerParameterDocument($parameter, $options));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function describeContainerEnvVars(array $envs, array $options = [])
|
||||||
|
{
|
||||||
|
throw new LogicException('Using the XML format to debug environment variables is not supported.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes DOM document.
|
* Writes DOM document.
|
||||||
*
|
*
|
||||||
|
@ -80,6 +80,75 @@ class ContainerDebugCommandTest extends WebTestCase
|
|||||||
$this->assertNotContains('No services found', $tester->getDisplay());
|
$this->assertNotContains('No services found', $tester->getDisplay());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDescribeEnvVars()
|
||||||
|
{
|
||||||
|
putenv('REAL=value');
|
||||||
|
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml']);
|
||||||
|
|
||||||
|
$application = new Application(static::$kernel);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$tester = new ApplicationTester($application);
|
||||||
|
$tester->run(['command' => 'debug:container', '--env-vars' => true], ['decorated' => false]);
|
||||||
|
|
||||||
|
$this->assertStringMatchesFormat(<<<'TXT'
|
||||||
|
|
||||||
|
Symfony Container Environment Variables
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
--------- ----------------- ------------
|
||||||
|
Name Default value Real value
|
||||||
|
--------- ----------------- ------------
|
||||||
|
JSON "[1, "2.5", 3]" n/a
|
||||||
|
REAL n/a "value"
|
||||||
|
UNKNOWN n/a n/a
|
||||||
|
--------- ----------------- ------------
|
||||||
|
|
||||||
|
// Note real values might be different between web and CLI.%w
|
||||||
|
|
||||||
|
[WARNING] The following variables are missing:%w
|
||||||
|
|
||||||
|
* UNKNOWN
|
||||||
|
|
||||||
|
TXT
|
||||||
|
, $tester->getDisplay(true));
|
||||||
|
|
||||||
|
putenv('REAL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDescribeEnvVar()
|
||||||
|
{
|
||||||
|
static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml']);
|
||||||
|
|
||||||
|
$application = new Application(static::$kernel);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$tester = new ApplicationTester($application);
|
||||||
|
$tester->run(['command' => 'debug:container', '--env-var' => 'js'], ['decorated' => false]);
|
||||||
|
|
||||||
|
$this->assertContains(<<<'TXT'
|
||||||
|
%env(float:key:2:json:JSON)%
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
----------------- -----------------
|
||||||
|
Default value "[1, "2.5", 3]"
|
||||||
|
Real value n/a
|
||||||
|
Processed value 3.0
|
||||||
|
----------------- -----------------
|
||||||
|
|
||||||
|
%env(int:key:2:json:JSON)%
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
----------------- -----------------
|
||||||
|
Default value "[1, "2.5", 3]"
|
||||||
|
Real value n/a
|
||||||
|
Processed value 3
|
||||||
|
----------------- -----------------
|
||||||
|
|
||||||
|
TXT
|
||||||
|
, $tester->getDisplay(true));
|
||||||
|
}
|
||||||
|
|
||||||
public function provideIgnoreBackslashWhenFindingService()
|
public function provideIgnoreBackslashWhenFindingService()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
imports:
|
imports:
|
||||||
- { resource: ../config/default.yml }
|
- { resource: ../config/default.yml }
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
env(JSON): '[1, "2.5", 3]'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
_defaults: { public: true }
|
_defaults: { public: true }
|
||||||
public:
|
public:
|
||||||
@ -10,3 +13,10 @@ services:
|
|||||||
public: false
|
public: false
|
||||||
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass:
|
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass:
|
||||||
class: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass
|
class: Symfony\Bundle\FrameworkBundle\Tests\Fixtures\BackslashClass
|
||||||
|
env:
|
||||||
|
class: stdClass
|
||||||
|
arguments:
|
||||||
|
- '%env(UNKNOWN)%'
|
||||||
|
- '%env(REAL)%'
|
||||||
|
- '%env(int:key:2:json:JSON)%'
|
||||||
|
- '%env(float:key:2:json:JSON)%'
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"fig/link-util": "^1.0",
|
"fig/link-util": "^1.0",
|
||||||
"symfony/asset": "~3.4|~4.0",
|
"symfony/asset": "~3.4|~4.0",
|
||||||
"symfony/browser-kit": "^4.3",
|
"symfony/browser-kit": "^4.3",
|
||||||
"symfony/console": "~3.4|~4.0",
|
"symfony/console": "^4.3",
|
||||||
"symfony/css-selector": "~3.4|~4.0",
|
"symfony/css-selector": "~3.4|~4.0",
|
||||||
"symfony/dom-crawler": "~3.4|~4.0",
|
"symfony/dom-crawler": "~3.4|~4.0",
|
||||||
"symfony/polyfill-intl-icu": "~1.0",
|
"symfony/polyfill-intl-icu": "~1.0",
|
||||||
@ -53,7 +53,7 @@
|
|||||||
"symfony/templating": "~3.4|~4.0",
|
"symfony/templating": "~3.4|~4.0",
|
||||||
"symfony/twig-bundle": "~2.8|~3.2|~4.0",
|
"symfony/twig-bundle": "~2.8|~3.2|~4.0",
|
||||||
"symfony/validator": "^4.1",
|
"symfony/validator": "^4.1",
|
||||||
"symfony/var-dumper": "~3.4|~4.0",
|
"symfony/var-dumper": "^4.3",
|
||||||
"symfony/workflow": "^4.3",
|
"symfony/workflow": "^4.3",
|
||||||
"symfony/yaml": "~3.4|~4.0",
|
"symfony/yaml": "~3.4|~4.0",
|
||||||
"symfony/property-info": "~3.4|~4.0",
|
"symfony/property-info": "~3.4|~4.0",
|
||||||
@ -69,7 +69,7 @@
|
|||||||
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
|
||||||
"symfony/asset": "<3.4",
|
"symfony/asset": "<3.4",
|
||||||
"symfony/browser-kit": "<4.3",
|
"symfony/browser-kit": "<4.3",
|
||||||
"symfony/console": "<3.4",
|
"symfony/console": "<4.3",
|
||||||
"symfony/dotenv": "<4.2",
|
"symfony/dotenv": "<4.2",
|
||||||
"symfony/form": "<4.3",
|
"symfony/form": "<4.3",
|
||||||
"symfony/messenger": "<4.3",
|
"symfony/messenger": "<4.3",
|
||||||
|
Reference in New Issue
Block a user