Skip to content

Commit

Permalink
Merge pull request #402 from Rastusik/2.x
Browse files Browse the repository at this point in the history
Optimalization of the file system enumerator, which now uses the glob function (in Symfony Finder)
  • Loading branch information
lisachenko authored Jan 4, 2019
2 parents 0b066ad + 1169ccc commit 325133d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 14 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"jakubledl/dissect": "~1.0",
"doctrine/annotations": "^1.2.3",
"goaop/parser-reflection": "~1.4",
"doctrine/cache": "^1.5"
"doctrine/cache": "^1.5",
"symfony/finder": "^3.4|^4.2"
},

"require-dev": {
Expand Down
81 changes: 69 additions & 12 deletions src/Instrument/FileSystem/Enumerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@

namespace Go\Instrument\FileSystem;

use ArrayIterator;
use CallbackFilterIterator;
use InvalidArgumentException;
use LogicException;
use RecursiveIteratorIterator;
use SplFileInfo;
use Symfony\Component\Finder\Finder;
use UnexpectedValueException;

/**
* Enumerates files in the concrete directory, applying filtration logic
*/
Expand Down Expand Up @@ -54,23 +63,71 @@ public function __construct($rootDirectory, array $includePaths = [], array $exc
/**
* Returns an enumerator for files
*
* @return \CallbackFilterIterator|\RecursiveIteratorIterator|\SplFileInfo[]
* @return \Iterator|SplFileInfo[]
* @throws UnexpectedValueException
* @throws InvalidArgumentException
* @throws LogicException
*/
public function enumerate()
{
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
$this->rootDirectory,
\FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS
)
);
$finder = new Finder();
$finder->files()
->name('*.php')
->in($this->getInPaths());

foreach ($this->getExcludePaths() as $path) {
$finder->notPath($path);
}

$iterator = $finder->getIterator();

$callback = $this->getFilter();
$iterator = new \CallbackFilterIterator($iterator, $callback);
// on Windows platform the default iterator is unable to rewind, not sure why
if (strpos(PHP_OS, 'WIN') === 0) {
$iterator = new ArrayIterator(iterator_to_array($iterator));
}

return $iterator;
}

/**
* @return array
* @throws UnexpectedValueException
*/
private function getInPaths()
{
$inPaths = [];

foreach ($this->includePaths as $path) {
if (strpos($path, $this->rootDirectory, 0) === false) {
throw new UnexpectedValueException(sprintf('Path %s is not in %s', $path, $this->rootDirectory));
}

$path = str_replace('*', '', $path);
$inPaths[] = $path;
}

if (empty($inPaths)) {
$inPaths[] = $this->rootDirectory;
}

return $inPaths;
}

/**
* @return array
*/
private function getExcludePaths()
{
$excludePaths = [];

foreach ($this->excludePaths as $path) {
$path = str_replace('*', '.*', $path);
$excludePaths[] = '#' . str_replace($this->rootDirectory . '/', '', $path) . '#';
}

return $excludePaths;
}

/**
* Returns a filter callback for enumerating files
*
Expand All @@ -82,7 +139,7 @@ public function getFilter()
$includePaths = $this->includePaths;
$excludePaths = $this->excludePaths;

return function (\SplFileInfo $file) use ($rootDirectory, $includePaths, $excludePaths) {
return function (SplFileInfo $file) use ($rootDirectory, $includePaths, $excludePaths) {

if ($file->getExtension() !== 'php') {
return false;
Expand Down Expand Up @@ -124,11 +181,11 @@ public function getFilter()
* In a vfs the 'realPath' methode will always return false.
* So we have a chance to mock this single function to return different path.
*
* @param \SplFileInfo $file
* @param SplFileInfo $file
*
* @return string
*/
protected function getFileFullPath(\SplFileInfo $file)
protected function getFileFullPath(SplFileInfo $file)
{
return $file->getRealPath();
}
Expand Down
5 changes: 4 additions & 1 deletion tests/Go/Instrument/FileSystem/EnumeratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public function pathsProvider()
* @param array $expectedPaths
* @param array $includePaths
* @param array $excludePaths
* @throws \InvalidArgumentException
* @throws \LogicException
* @throws \UnexpectedValueException
*/
public function testExclude($expectedPaths, $includePaths, $excludePaths)
{
Expand All @@ -114,7 +117,7 @@ public function testExclude($expectedPaths, $includePaths, $excludePaths)
$iterator = $mock->enumerate();

foreach ($iterator as $file) {
$testPaths[] = $file->getPath();
$testPaths[] = str_replace(DIRECTORY_SEPARATOR, '/', $file->getPath());
}

sort($testPaths);
Expand Down

0 comments on commit 325133d

Please sign in to comment.