diff --git a/src/Rule/Rules/File/PhpFileFinder.php b/src/Rule/Rules/File/PhpFileFinder.php index 5d60fe53..ee271900 100644 --- a/src/Rule/Rules/File/PhpFileFinder.php +++ b/src/Rule/Rules/File/PhpFileFinder.php @@ -9,6 +9,7 @@ use Boundwize\StructArmed\File\SkipPathMatcher; use Boundwize\StructArmed\Util\Path; +use function array_keys; use function array_unique; use function array_values; use function is_dir; @@ -66,37 +67,39 @@ public function filesFromScope( array $scopeFiles, array $skipPaths = [], ): array { - $sourcePaths = $this->sourcePaths($basePath); - $filesByPath = []; - $skipPathMatcher = SkipPathMatcher::compile($basePath, $skipPaths); + $skipPathMatcher = SkipPathMatcher::compile($basePath, $skipPaths); + $directoryPrefixes = []; + + foreach ($this->sourcePaths($basePath) as $sourcePath) { + $directoryPrefixes[] = Path::normalise(Path::resolve($sourcePath, $basePath), canonicalise: true) . '/'; + } - foreach ($scopeFiles as $file) { - $file = Path::normalise($file, canonicalise: true); + $files = []; + + foreach ($scopeFiles as $scopeFile) { + $scopeFile = Path::normalise($scopeFile, canonicalise: true); - if (! str_ends_with($file, '.php') || $skipPathMatcher->isSkipped($file)) { + if (isset($files[$scopeFile])) { continue; } - $filesByPath[$file] = $file; - } - - $files = []; + if (! str_ends_with($scopeFile, '.php')) { + continue; + } - foreach ($sourcePaths as $sourcePath) { - $resolvedSourcePath = Path::resolve($sourcePath, $basePath); - $directoryPrefix = Path::normalise($resolvedSourcePath, canonicalise: true) . '/'; + if ($skipPathMatcher->isSkipped($scopeFile)) { + continue; + } - foreach ($filesByPath as $file) { - if (! str_starts_with($file, $directoryPrefix)) { - continue; + foreach ($directoryPrefixes as $directoryPrefix) { + if (str_starts_with($scopeFile, $directoryPrefix)) { + $files[$scopeFile] = true; + continue 2; } - - $files[] = $file; - unset($filesByPath[$file]); } } - return $files; + return array_keys($files); } /** @return list */ diff --git a/tests/Rule/File/PhpFileFinderTest.php b/tests/Rule/File/PhpFileFinderTest.php index e39027ee..29cdf38a 100644 --- a/tests/Rule/File/PhpFileFinderTest.php +++ b/tests/Rule/File/PhpFileFinderTest.php @@ -109,4 +109,18 @@ public function testEachFinderFiltersScopeUsingItsOwnSourcePaths(): void (new PhpFileFinder(['custom/']))->filesFromScope($basePath, $scopeFiles), ); } + + public function testIgnoresDuplicateScopeFiles(): void + { + $basePath = $this->makeTemporaryDirectory('structarmed-php-file-finder'); + mkdir($basePath . '/src'); + + $sourceFile = $basePath . '/src/Foo.php'; + file_put_contents($sourceFile, 'assertSame( + [Path::normalise($sourceFile, canonicalise: true)], + (new PhpFileFinder(['src/']))->filesFromScope($basePath, [$sourceFile, $sourceFile]), + ); + } }