Skip to content

Commit

Permalink
[FrameworkBundle][DependencyInjection] Skip removed ids in the lint c…
Browse files Browse the repository at this point in the history
…ontainer command and its associated pass
  • Loading branch information
fancyweb committed Dec 11, 2019
1 parent 25494fa commit 89e3c76
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\HttpKernel\Kernel;

final class ContainerLintCommand extends Command
{
Expand All @@ -47,13 +51,18 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$container = $this->getContainerBuilder();
$io = new SymfonyStyle($input, $output);
$errorIo = $io->getErrorStyle();

$container->setParameter('container.build_hash', 'lint_container');
$container->setParameter('container.build_time', time());
$container->setParameter('container.build_id', 'lint_container');
try {
$container = $this->getContainerBuilder();
} catch (RuntimeException $e) {
$errorIo->error($e->getMessage());

return 2;
}

$container->addCompilerPass(new CheckTypeDeclarationsPass(true), PassConfig::TYPE_AFTER_REMOVING, -100);
$container->setParameter('container.build_time', time());

$container->compile();

Expand All @@ -67,22 +76,44 @@ private function getContainerBuilder(): ContainerBuilder
}

$kernel = $this->getApplication()->getKernel();
$kernelContainer = $kernel->getContainer();

if (!$kernel->isDebug() || !(new ConfigCache($kernelContainer->getParameter('debug.container.dump'), true))->isFresh()) {
if (!$kernel instanceof Kernel) {
throw new RuntimeException("This command does not support the console application's kernel.");
}

if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
$buildContainer = \Closure::bind(function (): ContainerBuilder {
$this->initializeBundles();

return $this->buildContainer();
}, $kernel, \get_class($kernel));
$container = $buildContainer();

$skippedIds = [];
} else {
(new XmlFileLoader($container = new ContainerBuilder($parameterBag = new EnvPlaceholderParameterBag()), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
if (!$kernelContainer instanceof Container) {
throw new RuntimeException("This command does not support the console application kernel's container.");
}

(new XmlFileLoader($container = new ContainerBuilder($parameterBag = new EnvPlaceholderParameterBag()), new FileLocator()))->load($kernelContainer->getParameter('debug.container.dump'));

$refl = new \ReflectionProperty($parameterBag, 'resolved');
$refl->setAccessible(true);
$refl->setValue($parameterBag, true);

$passConfig = $container->getCompilerPassConfig();
$passConfig->setRemovingPasses([]);
$passConfig->setAfterRemovingPasses([]);

$skippedIds = $kernelContainer->getRemovedIds();
}

$container->setParameter('container.build_hash', 'lint_container');
$container->setParameter('container.build_id', 'lint_container');

$container->addCompilerPass(new CheckTypeDeclarationsPass(true, $skippedIds), PassConfig::TYPE_AFTER_REMOVING, -100);

return $this->containerBuilder = $container;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,30 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
private const SCALAR_TYPES = ['int', 'float', 'bool', 'string'];

private $autoload;
private $skippedIds;

private $expressionLanguage;

/**
* @param bool $autoload Whether services who's class in not loaded should be checked or not.
* Defaults to false to save loading code during compilation.
* @param array $skippedIds An array indexed by the service ids to skip and with truthy values.
*/
public function __construct(bool $autoload = false)
public function __construct(bool $autoload = false, array $skippedIds = [])
{
$this->autoload = $autoload;
$this->skippedIds = $skippedIds;
}

/**
* {@inheritdoc}
*/
protected function processValue($value, $isRoot = false)
{
if (isset($this->skippedIds[$this->currentId])) {
return parent::processValue($value, $isRoot);
}

if (!$value instanceof Definition || $value->hasErrors()) {
return parent::processValue($value, $isRoot);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,4 +669,16 @@ public function testProcessHandleNotFoundEnvPlaceholder()

$this->addToAssertionCount(1);
}

public function testProcessSkipSkippedIds()
{
$container = new ContainerBuilder();
$container
->register('foobar', BarMethodCall::class)
->addMethodCall('setArray', ['a string']);

(new CheckTypeDeclarationsPass(true, ['foobar' => true]))->process($container);

$this->addToAssertionCount(1);
}
}

0 comments on commit 89e3c76

Please sign in to comment.