From 0e37ea6196b676c8090798bb2a0f5db27bdbc459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Verena=20R=C3=B6=C3=B6sli?= Date: Thu, 21 Oct 2021 09:38:23 +0200 Subject: [PATCH] Added pattern exclusion support for "-implementation" packages --- .../FilterDependencyCollectionCommand.php | 29 +++++++++++++++---- ...lectFilteredDependenciesCommandHandler.php | 18 ++++++++++-- src/Console/Command/UnusedCommand.php | 4 +-- tests/Integration/UnusedCommandTest.php | 17 +++++++++++ .../IgnorePatternPackages/composer.json | 8 +++++ 5 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 tests/assets/TestProjects/IgnorePatternPackages/composer.json diff --git a/src/Command/FilterDependencyCollectionCommand.php b/src/Command/FilterDependencyCollectionCommand.php index 8b6b1647..0586f589 100644 --- a/src/Command/FilterDependencyCollectionCommand.php +++ b/src/Command/FilterDependencyCollectionCommand.php @@ -10,23 +10,34 @@ final class FilterDependencyCollectionCommand { - private const GLOBAL_EXCLUSION = [ - 'composer-plugin-api', + private const GLOBAL_NAMED_EXCLUSION = [ + 'composer-plugin-api' + ]; + + private const GLOBAL_PATTERN_EXCLUSION = [ + '/-implementation$/i' ]; /** @var DependencyCollection */ private $requiredDependencyCollection; /** @var array */ private $namedExclusion; + /** @var array */ + private $patternExclusion; /** * @param DependencyCollection $requiredDependencyCollection * @param array $namedExclusion + * @param array $patternExclusion */ - public function __construct(DependencyCollection $requiredDependencyCollection, array $namedExclusion) - { + public function __construct( + DependencyCollection $requiredDependencyCollection, + array $namedExclusion = [], + array $patternExclusion = [] + ) { $this->requiredDependencyCollection = $requiredDependencyCollection; - $this->namedExclusion = array_merge(self::GLOBAL_EXCLUSION, $namedExclusion); + $this->namedExclusion = array_merge(self::GLOBAL_NAMED_EXCLUSION, $namedExclusion); + $this->patternExclusion = array_merge(self::GLOBAL_PATTERN_EXCLUSION, $patternExclusion); } public function getRequiredDependencyCollection(): DependencyCollection @@ -41,4 +52,12 @@ public function getNamedExclusion(): array { return $this->namedExclusion; } + + /** + * @return array + */ + public function getPatternExclusion(): array + { + return $this->patternExclusion; + } } diff --git a/src/Command/Handler/CollectFilteredDependenciesCommandHandler.php b/src/Command/Handler/CollectFilteredDependenciesCommandHandler.php index 7d4a00da..147c79b4 100644 --- a/src/Command/Handler/CollectFilteredDependenciesCommandHandler.php +++ b/src/Command/Handler/CollectFilteredDependenciesCommandHandler.php @@ -12,9 +12,23 @@ final class CollectFilteredDependenciesCommandHandler public function collect(FilterDependencyCollectionCommand $command): DependencyCollection { $namedExclusion = $command->getNamedExclusion(); + $patternExclusion = $command->getPatternExclusion(); - return $command->getRequiredDependencyCollection()->filter(static function ($dependency) use ($namedExclusion) { - return !in_array($dependency->getName(), $namedExclusion); + return $command->getRequiredDependencyCollection()->filter(static function ($dependency) use ( + $namedExclusion, + $patternExclusion + ) { + if (in_array($dependency->getName(), $namedExclusion)) { + return false; + } + + foreach ($patternExclusion as $exclusion) { + if (preg_match($exclusion, $dependency->getName())) { + return false; + } + } + + return true; }); } } diff --git a/src/Console/Command/UnusedCommand.php b/src/Console/Command/UnusedCommand.php index e52ce1f1..1aa8221e 100644 --- a/src/Console/Command/UnusedCommand.php +++ b/src/Console/Command/UnusedCommand.php @@ -97,7 +97,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int new CollectConsumedSymbolsCommand( $baseDir, $rootPackage - // TODO add excludes ) ); @@ -112,7 +111,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $requiredDependencyCollection = $this->collectFilteredDependenciesCommandHandler->collect( new FilterDependencyCollectionCommand( $unfilteredRequiredDependencyCollection, - $input->getOption('excludePackage') + $input->getOption('excludePackage'), + [] // TODO use pattern exclude option from command line ) ); diff --git a/tests/Integration/UnusedCommandTest.php b/tests/Integration/UnusedCommandTest.php index 7c6f7d92..0a077467 100644 --- a/tests/Integration/UnusedCommandTest.php +++ b/tests/Integration/UnusedCommandTest.php @@ -138,4 +138,21 @@ public function itShouldNotReportExcludedPackages(): void self::assertStringNotContainsString('dummy/test-package', $output->fetch()); } + + /** + * @test + */ + public function itShouldNotReportPatternExcludedPackages(): void + { + chdir(__DIR__ . '/../assets/TestProjects/IgnorePatternPackages'); + + $output = new BufferedOutput(); + + $this->getApplication()->run( + new ArrayInput(['unused']), + $output + ); + + self::assertStringNotContainsString('-implementation', $output->fetch()); + } } diff --git a/tests/assets/TestProjects/IgnorePatternPackages/composer.json b/tests/assets/TestProjects/IgnorePatternPackages/composer.json new file mode 100644 index 00000000..3e8ba03b --- /dev/null +++ b/tests/assets/TestProjects/IgnorePatternPackages/composer.json @@ -0,0 +1,8 @@ +{ + "name": "ns/lib", + "require": { + "dummy/test-package": "1.0", + "psr/log-implementation": "1.0.0", + "dummy/ff-implementation": "1.0.0" + } +}