diff --git a/config/services.php b/config/services.php index 0333bfb2..8bc47963 100644 --- a/config/services.php +++ b/config/services.php @@ -10,6 +10,7 @@ use Qossmic\Deptrac\Contract\Config\CollectorType; use Qossmic\Deptrac\Contract\Config\EmitterType; use Qossmic\Deptrac\Contract\Layer\LayerProvider; +use Qossmic\Deptrac\Contract\OutputFormatter\BaselineMapperInterface; use Qossmic\Deptrac\Core\Analyser\DependencyLayersAnalyser; use Qossmic\Deptrac\Core\Analyser\EventHandler\AllowDependencyHandler; use Qossmic\Deptrac\Core\Analyser\EventHandler\DependsOnDisallowedLayer; @@ -109,6 +110,7 @@ use Qossmic\Deptrac\Supportive\OutputFormatter\MermaidJSOutputFormatter; use Qossmic\Deptrac\Supportive\OutputFormatter\TableOutputFormatter; use Qossmic\Deptrac\Supportive\OutputFormatter\XMLOutputFormatter; +use Qossmic\Deptrac\Supportive\OutputFormatter\YamlBaselineMapper; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\EventDispatcher\EventDispatcher; @@ -404,11 +406,13 @@ ->set(UnmatchedSkippedViolations::class) ->tag('kernel.event_subscriber') ; - $services->set(EventHelper::class) + $services->set(YamlBaselineMapper::class) ->args([ '$skippedViolations' => param('skip_violations'), ]) ; + $services->alias(BaselineMapperInterface::class, YamlBaselineMapper::class); + $services->set(EventHelper::class); $services ->set(DependencyLayersAnalyser::class) ; diff --git a/src/Contract/Analyser/EventHelper.php b/src/Contract/Analyser/EventHelper.php index a4c93704..f135776a 100644 --- a/src/Contract/Analyser/EventHelper.php +++ b/src/Contract/Analyser/EventHelper.php @@ -5,6 +5,7 @@ namespace Qossmic\Deptrac\Contract\Analyser; use Qossmic\Deptrac\Contract\Layer\LayerProvider; +use Qossmic\Deptrac\Contract\OutputFormatter\BaselineMapperInterface; use Qossmic\Deptrac\Contract\Result\SkippedViolation; use Qossmic\Deptrac\Contract\Result\Violation; @@ -19,13 +20,16 @@ final class EventHelper private array $unmatchedSkippedViolation; /** - * @param array> $skippedViolations + * @var array> */ + private readonly array $skippedViolations; + public function __construct( - private readonly array $skippedViolations, public readonly LayerProvider $layerProvider, + private readonly BaselineMapperInterface $baselineMapper, ) { - $this->unmatchedSkippedViolation = $skippedViolations; + $this->skippedViolations = $this->baselineMapper->loadViolations(); + $this->unmatchedSkippedViolation = $this->skippedViolations; } /** diff --git a/src/Contract/OutputFormatter/BaselineMapperInterface.php b/src/Contract/OutputFormatter/BaselineMapperInterface.php new file mode 100644 index 00000000..18071e1d --- /dev/null +++ b/src/Contract/OutputFormatter/BaselineMapperInterface.php @@ -0,0 +1,23 @@ +> $groupedViolations + */ + public function fromPHPListToString(array $groupedViolations): string; + + /** + * Load the existing violation to ignore by custom mapper logic. + * + * @return array> + */ + public function loadViolations(): array; +} diff --git a/src/Supportive/OutputFormatter/BaselineOutputFormatter.php b/src/Supportive/OutputFormatter/BaselineOutputFormatter.php index 502e2f64..cdcab85b 100644 --- a/src/Supportive/OutputFormatter/BaselineOutputFormatter.php +++ b/src/Supportive/OutputFormatter/BaselineOutputFormatter.php @@ -4,13 +4,13 @@ namespace Qossmic\Deptrac\Supportive\OutputFormatter; +use Qossmic\Deptrac\Contract\OutputFormatter\BaselineMapperInterface; use Qossmic\Deptrac\Contract\OutputFormatter\OutputFormatterInput; use Qossmic\Deptrac\Contract\OutputFormatter\OutputFormatterInterface; use Qossmic\Deptrac\Contract\OutputFormatter\OutputInterface; use Qossmic\Deptrac\Contract\Result\OutputResult; use Qossmic\Deptrac\Contract\Result\SkippedViolation; use Qossmic\Deptrac\Contract\Result\Violation; -use Symfony\Component\Yaml\Yaml; use function array_values; use function ksort; @@ -23,6 +23,10 @@ final class BaselineOutputFormatter implements OutputFormatterInterface { private const DEFAULT_PATH = './deptrac.baseline.yaml'; + public function __construct( + private readonly BaselineMapperInterface $baselineMapper, + ) {} + public static function getName(): string { return 'baseline'; @@ -49,15 +53,7 @@ public function finish( } file_put_contents( $baselineFile, - Yaml::dump( - [ - 'deptrac' => [ - 'skip_violations' => $groupedViolations, - ], - ], - 4, - 2 - ) + $this->baselineMapper->fromPHPListToString($groupedViolations), ); $output->writeLineFormatted('Baseline dumped to '.realpath($baselineFile).''); } diff --git a/src/Supportive/OutputFormatter/YamlBaselineMapper.php b/src/Supportive/OutputFormatter/YamlBaselineMapper.php new file mode 100644 index 00000000..5cf9581c --- /dev/null +++ b/src/Supportive/OutputFormatter/YamlBaselineMapper.php @@ -0,0 +1,36 @@ +> $skippedViolations + */ + public function __construct( + private readonly array $skippedViolations, + ) {} + + public function fromPHPListToString(array $groupedViolations): string + { + return Yaml::dump( + [ + 'deptrac' => [ + 'skip_violations' => $groupedViolations, + ], + ], + 4, + 2 + ); + } + + public function loadViolations(): array + { + return $this->skippedViolations; + } +} diff --git a/tests/Contract/Analyser/EventHelperTest.php b/tests/Contract/Analyser/EventHelperTest.php index 5e605e70..c92fd683 100644 --- a/tests/Contract/Analyser/EventHelperTest.php +++ b/tests/Contract/Analyser/EventHelperTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use Qossmic\Deptrac\Contract\Analyser\EventHelper; use Qossmic\Deptrac\Contract\Layer\LayerProvider; +use Qossmic\Deptrac\Contract\OutputFormatter\BaselineMapperInterface; use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeToken; final class EventHelperTest extends TestCase @@ -24,7 +25,22 @@ public function testIsViolationSkipped(): void 'DependencyClass2', ], ]; - $helper = new EventHelper($configuration, new LayerProvider([])); + + $baselineMapper = new class($configuration) implements BaselineMapperInterface { + public function __construct(private readonly array $violations) {} + + public function fromPHPListToString(array $groupedViolations): string + { + return ''; + } + + public function loadViolations(): array + { + return $this->violations; + } + }; + + $helper = new EventHelper(new LayerProvider([]), $baselineMapper); self::assertTrue( $helper->shouldViolationBeSkipped( @@ -78,7 +94,22 @@ public function testUnmatchedSkippedViolations(): void 'DependencyClass2', ], ]; - $helper = new EventHelper($configuration, new LayerProvider([])); + + $baselineMapper = new class($configuration) implements BaselineMapperInterface { + public function __construct(private readonly array $violations) {} + + public function fromPHPListToString(array $groupedViolations): string + { + return ''; + } + + public function loadViolations(): array + { + return $this->violations; + } + }; + + $helper = new EventHelper(new LayerProvider([]), $baselineMapper); self::assertTrue( $helper->shouldViolationBeSkipped( diff --git a/tests/Core/Analyser/EventHandler/DependsOnInternalTokenTest.php b/tests/Core/Analyser/EventHandler/DependsOnInternalTokenTest.php index 6ee22c9e..a94244b8 100644 --- a/tests/Core/Analyser/EventHandler/DependsOnInternalTokenTest.php +++ b/tests/Core/Analyser/EventHandler/DependsOnInternalTokenTest.php @@ -17,6 +17,7 @@ use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeToken; use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeType; use Qossmic\Deptrac\Core\Dependency\Dependency; +use Qossmic\Deptrac\Supportive\OutputFormatter\YamlBaselineMapper; final class DependsOnInternalTokenTest extends TestCase { @@ -56,7 +57,7 @@ private function makeEvent( public function testInvoke(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnInternalToken($helper, ['internal_tag' => '@layer-internal']); $event = $this->makeEvent([], []); @@ -103,7 +104,7 @@ public function testInvoke(): void public function testDefaultInternalTag(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnInternalToken($helper, ['internal_tag' => null]); $event = $this->makeEvent([], ['@internal' => ['']]); diff --git a/tests/Core/Analyser/EventHandler/DependsOnPrivateLayerTest.php b/tests/Core/Analyser/EventHandler/DependsOnPrivateLayerTest.php index e7b963df..5cb1f5c6 100644 --- a/tests/Core/Analyser/EventHandler/DependsOnPrivateLayerTest.php +++ b/tests/Core/Analyser/EventHandler/DependsOnPrivateLayerTest.php @@ -18,6 +18,7 @@ use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeToken; use Qossmic\Deptrac\Core\Ast\AstMap\ClassLike\ClassLikeType; use Qossmic\Deptrac\Core\Dependency\Dependency; +use Qossmic\Deptrac\Supportive\OutputFormatter\YamlBaselineMapper; final class DependsOnPrivateLayerTest extends TestCase { @@ -52,7 +53,7 @@ private function makeEvent( public function testNoViolationsWhenDependentLayerIsPublic(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnPrivateLayer($helper); $event = $this->makeEvent('DependerLayer', 'DependentLayer', true); @@ -72,7 +73,7 @@ public function testNoViolationsWhenDependentLayerIsPublic(): void public function testPropagationContinuesWhenPrivateLayerDependsOnItself(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnPrivateLayer($helper); $event = $this->makeEvent('LayerA', 'LayerA', false); @@ -92,7 +93,7 @@ public function testPropagationContinuesWhenPrivateLayerDependsOnItself(): void public function testPropagationContinuesWhenPublicLayerDependsOnItself(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnPrivateLayer($helper); $event = $this->makeEvent('layerA', 'layerA', true); @@ -112,7 +113,7 @@ public function testPropagationContinuesWhenPublicLayerDependsOnItself(): void public function testPropagationStoppedWhenDependingOnPrivateLayer(): void { - $helper = new EventHelper([], new LayerProvider([])); + $helper = new EventHelper(new LayerProvider([]), new YamlBaselineMapper([])); $handler = new DependsOnPrivateLayer($helper); $event = $this->makeEvent('DependerLayer', 'DependentLayer', false); diff --git a/tests/Supportive/OutputFormatter/BaselineOutputFormatterTest.php b/tests/Supportive/OutputFormatter/BaselineOutputFormatterTest.php index bb796fb1..5a7921d5 100644 --- a/tests/Supportive/OutputFormatter/BaselineOutputFormatterTest.php +++ b/tests/Supportive/OutputFormatter/BaselineOutputFormatterTest.php @@ -22,6 +22,7 @@ use Qossmic\Deptrac\Supportive\Console\Symfony\Style; use Qossmic\Deptrac\Supportive\Console\Symfony\SymfonyOutput; use Qossmic\Deptrac\Supportive\OutputFormatter\BaselineOutputFormatter; +use Qossmic\Deptrac\Supportive\OutputFormatter\YamlBaselineMapper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Style\SymfonyStyle; @@ -31,7 +32,7 @@ class BaselineOutputFormatterTest extends TestCase { public function testGetName(): void { - static::assertSame('baseline', (new BaselineOutputFormatter())->getName()); + static::assertSame('baseline', (new BaselineOutputFormatter(new YamlBaselineMapper([])))->getName()); } public static function basicDataProvider(): iterable @@ -130,7 +131,7 @@ public function testBasic(array $rules, string $expectedOutput): void try { $output = new BufferedOutput(); - $formatter = new BaselineOutputFormatter(); + $formatter = new BaselineOutputFormatter(new YamlBaselineMapper([])); $formatter->finish( OutputResult::fromAnalysisResult($analysisResult), $this->createSymfonyOutput($output),