merged branch vicb/finder-adapters (PR #6253)
This PR was squashed before being merged into the master branch (closes #6253).
Commits
-------
e62b5f7
[Finder] cleanup, fixes, improvements
Discussion
----------
[Finder] cleanup, fixes, improvements
This commit is contained in:
commit
1ec59f174e
@ -34,6 +34,22 @@ abstract class AbstractAdapter implements AdapterInterface
|
||||
protected $paths = array();
|
||||
protected $notPaths = array();
|
||||
|
||||
private static $areSupported = array();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
{
|
||||
$name = $this->getName();
|
||||
|
||||
if (!array_key_exists($name, self::$areSupported)) {
|
||||
self::$areSupported[$name] = $this->canBeUsed();
|
||||
}
|
||||
|
||||
return self::$areSupported[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -193,4 +209,17 @@ abstract class AbstractAdapter implements AdapterInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the adapter is supported in the current environment.
|
||||
*
|
||||
* This method should be implemented in all adapters. Do not implement
|
||||
* isSupported in the adapters as the generic implementation provides a cache
|
||||
* layer.
|
||||
*
|
||||
* @see isSupported
|
||||
*
|
||||
* @return Boolean Whether the adapter is supported
|
||||
*/
|
||||
abstract protected function canBeUsed();
|
||||
}
|
||||
|
@ -118,13 +118,14 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return $this->shell->testCommand('find');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command $command
|
||||
* @param string $dir
|
||||
*
|
||||
* @return Command
|
||||
*/
|
||||
@ -140,7 +141,7 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
/**
|
||||
* @param Command $command
|
||||
* @param string[] $names
|
||||
* @param bool $not
|
||||
* @param Boolean $not
|
||||
*/
|
||||
private function buildNamesFiltering(Command $command, array $names, $not = false)
|
||||
{
|
||||
@ -183,7 +184,8 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
* @param Command $command
|
||||
* @param string $dir
|
||||
* @param string[] $paths
|
||||
* @param bool $not
|
||||
* @param Boolean $not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
|
||||
@ -226,33 +228,23 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
foreach ($sizes as $i => $size) {
|
||||
$command->add($i > 0 ? '-and' : null);
|
||||
|
||||
if ('<=' === $size->getOperator()) {
|
||||
switch ($size->getOperator()) {
|
||||
case '<=':
|
||||
$command->add('-size -' . ($size->getTarget() + 1) . 'c');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('<' === $size->getOperator()) {
|
||||
$command->add('-size -'.$size->getTarget().'c');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('>=' === $size->getOperator()) {
|
||||
break;
|
||||
case '>=':
|
||||
$command->add('-size +'. ($size->getTarget() - 1) . 'c');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('>' === $size->getOperator()) {
|
||||
break;
|
||||
case '>':
|
||||
$command->add('-size +' . $size->getTarget() . 'c');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('!=' === $size->getOperator()) {
|
||||
break;
|
||||
case '!=':
|
||||
$command->add('-size -' . $size->getTarget() . 'c');
|
||||
$command->add('-size +' . $size->getTarget() . 'c');
|
||||
continue;
|
||||
case '<':
|
||||
default:
|
||||
$command->add('-size -' . $size->getTarget() . 'c');
|
||||
}
|
||||
|
||||
$command->add('-size '.$size->getTarget().'c');
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,39 +266,30 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
return;
|
||||
}
|
||||
|
||||
if ('<=' === $date->getOperator()) {
|
||||
switch ($date->getOperator()) {
|
||||
case '<=':
|
||||
$command->add('-mmin +' . ($mins - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('<' === $date->getOperator()) {
|
||||
$command->add('-mmin +'.$mins);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('>=' === $date->getOperator()) {
|
||||
break;
|
||||
case '>=':
|
||||
$command->add('-mmin -' . ($mins + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('>' === $date->getOperator()) {
|
||||
break;
|
||||
case '>':
|
||||
$command->add('-mmin -' . $mins);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('!=' === $date->getOperator()) {
|
||||
break;
|
||||
case '!=':
|
||||
$command->add('-mmin +' . $mins.' -or -mmin -' . $mins);
|
||||
continue;
|
||||
break;
|
||||
case '<':
|
||||
default:
|
||||
$command->add('-mmin +' . $mins);
|
||||
}
|
||||
|
||||
$command->add('-mmin '.$mins);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Command $command
|
||||
* @param array $contains
|
||||
* @param bool $not
|
||||
* @param Boolean $not
|
||||
*/
|
||||
private function buildContentFiltering(Command $command, array $contains, $not = false)
|
||||
{
|
||||
@ -323,8 +306,9 @@ abstract class AbstractFindAdapter extends AbstractAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\Finder\Shell\Command $command
|
||||
* @param Command $command
|
||||
* @param string $sort
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function buildSorting(Command $command, $sort)
|
||||
|
@ -17,14 +17,14 @@ namespace Symfony\Component\Finder\Adapter;
|
||||
interface AdapterInterface
|
||||
{
|
||||
/**
|
||||
* @param bool $followLinks
|
||||
* @param Boolean $followLinks
|
||||
*
|
||||
* @return AdapterInterface Current instance
|
||||
*/
|
||||
public function setFollowLinks($followLinks);
|
||||
|
||||
/**
|
||||
* @param int $mode
|
||||
* @param integer $mode
|
||||
*
|
||||
* @return AdapterInterface Current instance
|
||||
*/
|
||||
@ -94,14 +94,14 @@ interface AdapterInterface
|
||||
public function setFilters(array $filters);
|
||||
|
||||
/**
|
||||
* @param \Closure|int $sort
|
||||
* @param \Closure|integer $sort
|
||||
*
|
||||
* @return AdapterInterface Current instance
|
||||
*/
|
||||
public function setSort($sort);
|
||||
|
||||
/**
|
||||
* @param array $path
|
||||
* @param array $paths
|
||||
*
|
||||
* @return AdapterInterface Current instance
|
||||
*/
|
||||
@ -124,7 +124,7 @@ interface AdapterInterface
|
||||
/**
|
||||
* Tests adapter support for current platform.
|
||||
*
|
||||
* @return bool
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isSupported();
|
||||
|
||||
|
@ -22,14 +22,6 @@ use Symfony\Component\Finder\Shell\Command;
|
||||
*/
|
||||
class BsdFindAdapter extends AbstractFindAdapter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
{
|
||||
return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::isSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -38,12 +30,25 @@ class BsdFindAdapter extends AbstractFindAdapter
|
||||
return 'bsd_find';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildFormatSorting(Command $command, $format)
|
||||
{
|
||||
$command->get('find')->add('-print0 | xargs -0 stat -f')->arg($format.' %h/%f\\n')
|
||||
->add('| sort | cut')->arg('-d ')->arg('-f2-');
|
||||
$command
|
||||
->get('find')
|
||||
->add('-print0 | xargs -0 stat -f')
|
||||
->arg($format.' %h/%f\\n')
|
||||
->add('| sort | cut')
|
||||
->arg('-d ')
|
||||
->arg('-f2-');
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +22,6 @@ use Symfony\Component\Finder\Shell\Command;
|
||||
*/
|
||||
class GnuFindAdapter extends AbstractFindAdapter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
{
|
||||
return $this->shell->getType() === Shell::TYPE_UNIX && parent::isSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -43,8 +35,22 @@ class GnuFindAdapter extends AbstractFindAdapter
|
||||
*/
|
||||
protected function buildFormatSorting(Command $command, $format)
|
||||
{
|
||||
$command->get('find')->add('-printf')->arg($format.' %h/%f\\n')
|
||||
->add('| sort | cut')->arg('-d ')->arg('-f2-');
|
||||
$command
|
||||
->get('find')
|
||||
->add('-printf')
|
||||
->arg($format.' %h/%f\\n')
|
||||
->add('| sort | cut')
|
||||
->arg('-d ')
|
||||
->arg('-f2-')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,16 +83,16 @@ class PhpAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
public function getName()
|
||||
{
|
||||
return true;
|
||||
return 'php';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return 'php';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -65,9 +65,11 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
{
|
||||
$this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
|
||||
|
||||
$this->addAdapter(new GnuFindAdapter());
|
||||
$this->addAdapter(new BsdFindAdapter());
|
||||
$this->addAdapter(new PhpAdapter(), -50);
|
||||
$this
|
||||
->addAdapter(new GnuFindAdapter())
|
||||
->addAdapter(new BsdFindAdapter())
|
||||
->addAdapter(new PhpAdapter(), -50)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +88,7 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
* Registers a finder engine implementation.
|
||||
*
|
||||
* @param AdapterInterface $adapter An adapter instance
|
||||
* @param int $priority Highest is selected first
|
||||
* @param integer $priority Highest is selected first
|
||||
*
|
||||
* @return Finder The current Finder instance
|
||||
*/
|
||||
@ -418,9 +420,20 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds VCS patterns.
|
||||
*
|
||||
* @see ignoreVCS
|
||||
*
|
||||
* @param string|string[] $pattern VCS patterns to ignore
|
||||
*/
|
||||
public static function addVCSPattern($pattern)
|
||||
{
|
||||
self::$vcsPatterns[] = $pattern;
|
||||
foreach ((array) $pattern as $p) {
|
||||
self::$vcsPatterns[] = $p;
|
||||
}
|
||||
|
||||
self::$vcsPatterns = array_unique(self::$vcsPatterns);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,6 +704,8 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
* @param $dir
|
||||
*
|
||||
* @return \Iterator
|
||||
*
|
||||
* @throws \RuntimeException When none of the adapters are supported
|
||||
*/
|
||||
private function searchInDirectory($dir)
|
||||
{
|
||||
@ -703,16 +718,12 @@ class Finder implements \IteratorAggregate, \Countable
|
||||
}
|
||||
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if (!$adapter['adapter']->isSupported()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($adapter['adapter']->isSupported()) {
|
||||
try {
|
||||
return $this
|
||||
->buildAdapter($adapter['adapter'])
|
||||
->searchInDirectory($dir);
|
||||
} catch(ExceptionInterface $e) {
|
||||
continue;
|
||||
} catch(ExceptionInterface $e) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,16 +42,16 @@ class DummyAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
public function getName()
|
||||
{
|
||||
return true;
|
||||
return 'yes';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return 'yes';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,16 @@ class FailingAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
public function getName()
|
||||
{
|
||||
return true;
|
||||
return 'failing';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getName()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return 'failing';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -42,16 +42,16 @@ class NamedAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
public function getName()
|
||||
{
|
||||
return true;
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getName()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return $this->name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -29,16 +29,16 @@ class UnsupportedAdapter extends AbstractAdapter
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isSupported()
|
||||
public function getName()
|
||||
{
|
||||
return false;
|
||||
return 'unsupported';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function getName()
|
||||
protected function canBeUsed()
|
||||
{
|
||||
return 'unsupported';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -356,9 +356,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
*/
|
||||
public function testRelativePath($adapter)
|
||||
{
|
||||
$finder = $this->buildFinder($adapter);
|
||||
|
||||
$finder->in(self::$tmpDir);
|
||||
$finder = $this->buildFinder($adapter)->in(self::$tmpDir);
|
||||
|
||||
$paths = array();
|
||||
|
||||
@ -379,9 +377,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
*/
|
||||
public function testRelativePathname($adapter)
|
||||
{
|
||||
$finder = $this->buildFinder($adapter);
|
||||
|
||||
$finder->in(self::$tmpDir)->sortByName();
|
||||
$finder = $this->buildFinder($adapter)->in(self::$tmpDir)->sortByName();
|
||||
|
||||
$paths = array();
|
||||
|
||||
@ -450,8 +446,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
|
||||
public function testCountDirectories()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$directory = $finder->directories()->in(self::$tmpDir);
|
||||
$directory = Finder::create()->directories()->in(self::$tmpDir);
|
||||
$i = 0;
|
||||
|
||||
foreach ($directory as $dir) {
|
||||
@ -463,8 +458,7 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
|
||||
public function testCountFiles()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$files = $finder->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
|
||||
$i = 0;
|
||||
|
||||
foreach ($files as $file) {
|
||||
@ -474,17 +468,13 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
$this->assertCount($i, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testCountWithoutIn()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$finder->files();
|
||||
|
||||
try {
|
||||
$finder = Finder::create()->files();
|
||||
count($finder);
|
||||
$this->fail('Countable makes use of the getIterator command');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('LogicException', $e, '->getIterator() throws \LogicException when no logic has been entered');
|
||||
}
|
||||
}
|
||||
|
||||
protected function toAbsolute($files)
|
||||
@ -641,37 +631,10 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
return $this->buildTestData($tests);
|
||||
}
|
||||
|
||||
private function buildFinder(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
return Finder::create()
|
||||
->removeAdapters()
|
||||
->addAdapter($adapter);
|
||||
}
|
||||
|
||||
private function getValidAdapters()
|
||||
{
|
||||
return array_filter(
|
||||
array(new Adapter\GnuFindAdapter(), new Adapter\PhpAdapter()),
|
||||
function (Adapter\AdapterInterface $adapter) { return $adapter->isSupported(); }
|
||||
);
|
||||
}
|
||||
|
||||
private function buildTestData(array $tests)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($this->getValidAdapters() as $adapter) {
|
||||
foreach ($tests as $test) {
|
||||
$data[] = array_merge(array($adapter), $test);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestPathData
|
||||
*/
|
||||
public function testPath(Adapter\AdapterInterface $adapter, $matchPatterns, $noMatchPatterns, $expected)
|
||||
public function testPath(Adapter\AdapterInterface $adapter, $matchPatterns, $noMatchPatterns, array $expected)
|
||||
{
|
||||
$finder = $this->buildFinder($adapter);
|
||||
$finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
|
||||
@ -722,4 +685,37 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
|
||||
return $this->buildTestData($tests);
|
||||
}
|
||||
|
||||
private function buildTestData(array $tests)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($this->getValidAdapters() as $adapter) {
|
||||
foreach ($tests as $test) {
|
||||
$data[] = array_merge(array($adapter), $test);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function buildFinder(Adapter\AdapterInterface $adapter)
|
||||
{
|
||||
return Finder::create()
|
||||
->removeAdapters()
|
||||
->addAdapter($adapter);
|
||||
}
|
||||
|
||||
private function getValidAdapters()
|
||||
{
|
||||
return array_filter(
|
||||
array(
|
||||
new Adapter\BsdFindAdapter(),
|
||||
new Adapter\GnuFindAdapter(),
|
||||
new Adapter\PhpAdapter()
|
||||
),
|
||||
function (Adapter\AdapterInterface $adapter) {
|
||||
return $adapter->isSupported();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user