init ConfigMerger to prevent memory leaks

This commit is contained in:
TomasVotruba 2017-12-22 01:07:26 +01:00
parent b87b6b4bd5
commit 5af077fbb8
4 changed files with 87 additions and 32 deletions

View File

@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace Rector\Configuration;
final class ConfigMerger
{
/**
* @todo resolve nicely, memory leak at the moment: https://travis-ci.org/rectorphp/rector/jobs/319947148#L641
*
* This magic will merge array recursively without making any extra duplications.
*
* Only array_merge doesn't work in this case.
*
* @param mixed[] $configs
* @return mixed[]
*/
public function mergeConfigs(array $configs): array
{
dump($configs);
if (count($configs) <= 1) {
return $configs[0];
}
$mergedConfigs = [];
foreach ($configs as $config) {
$mergedConfigs = array_merge(
$mergedConfigs,
$config,
array_replace_recursive($mergedConfigs, $config)
);
}
return $mergedConfigs;
}
}

View File

@ -2,6 +2,7 @@
namespace Rector\DependencyInjection\Extension;
use Rector\Configuration\ConfigMerger;
use Rector\Configuration\Normalizer\RectorClassNormalizer;
use Rector\Configuration\Validator\RectorClassValidator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -19,12 +20,19 @@ final class RectorsExtension extends Extension
*/
private $rectorClassNormalizer;
/**
* @var ConfigMerger
*/
private $configMerger;
public function __construct(
RectorClassValidator $rectorClassValidator,
RectorClassNormalizer $rectorClassNormalizer
RectorClassNormalizer $rectorClassNormalizer,
ConfigMerger $configurationMerger
) {
$this->rectorClassValidator = $rectorClassValidator;
$this->rectorClassNormalizer = $rectorClassNormalizer;
$this->configMerger = $configurationMerger;
}
/**
@ -36,43 +44,18 @@ final class RectorsExtension extends Extension
return;
}
$rectors = $this->mergeAllConfigsRecursively($configs);
$rectors = $this->configMerger->mergeConfigs($configs);
$rectors = $this->rectorClassNormalizer->normalize($rectors);
$this->rectorClassValidator->validate(array_keys($rectors));
foreach ($rectors as $rectorClass => $arguments) {
$rectorDefinition = $containerBuilder->autowire($rectorClass);
if (! count($arguments)) {
if (! $arguments) {
continue;
}
$rectorDefinition->setArguments([$arguments]);
}
}
/**
* This magic will merge array recursively
* without making any extra duplications.
*
* Only array_merge doesn't work in this case.
*
* @param mixed[] $configs
* @return mixed[]
*/
private function mergeAllConfigsRecursively(array $configs): array
{
$mergedConfigs = [];
foreach ($configs as $config) {
$mergedConfigs = array_merge(
$mergedConfigs,
$config,
array_replace_recursive($mergedConfigs, $config)
);
}
return $mergedConfigs;
}
}

View File

@ -2,6 +2,7 @@
namespace Rector\DependencyInjection;
use Rector\Configuration\ConfigMerger;
use Rector\Configuration\Normalizer\RectorClassNormalizer;
use Rector\Configuration\Validator\RectorClassValidator;
use Rector\DependencyInjection\Extension\RectorsExtension;
@ -11,9 +12,6 @@ final class RectorBundle extends Bundle
{
public function getContainerExtension(): RectorsExtension
{
return new RectorsExtension(
new RectorClassValidator(),
new RectorClassNormalizer()
);
return new RectorsExtension(new RectorClassValidator(), new RectorClassNormalizer(), new ConfigMerger());
}
}

View File

@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace Rector\Tests\Configuration;
use PHPUnit\Framework\TestCase;
use Rector\Configuration\ConfigMerger;
final class ConfigMergerTest extends TestCase
{
/**
* @var ConfigMerger
*/
private $configMerger;
protected function setUp(): void
{
$this->configMerger = new ConfigMerger();
}
public function test(): void
{
$result = $this->configMerger->mergeConfigs([
['SomeRector' => ['key' => 'value']]
]);
$this->assertSame(['SomeRector' => ['key' => 'value']], $result);
$result = $this->configMerger->mergeConfigs([
['SomeRector' => ['key' => ['value']]],
['SomeRector' => ['key' => ['another_value']]]
]);
$this->assertSame(['SomeRector' => ['key' => 'value']], $result);
}
}