8000 [Component][Finder] ->path(), ->notPath() methods (with basic tests) · symfony/symfony@c36dfc1 · GitHub
[go: up one dir, main page]

Skip to content

Commit c36dfc1

Browse files
committed
[Component][Finder] ->path(), ->notPath() methods (with basic tests)
1 parent 2a23dbd commit c36dfc1

File tree

15 files changed

+459
-105
lines changed
  • Fixtures
  • Iterator
  • 15 files changed

    +459
    -105
    lines changed

    src/Symfony/Component/Finder/Adapter/AbstractAdapter.php

    Lines changed: 23 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -31,6 +31,8 @@ abstract class AbstractAdapter implements AdapterInterface
    3131
    protected $dates = array();
    3232
    protected $filters = array();
    3333
    protected $sort = false;
    34+
    protected $paths = array();
    35+
    protected $notPaths = array();
    3436

    3537
    /**
    3638
    * {@inheritdoc}
    @@ -171,4 +173,25 @@ public function setSort($sort)
    171173

    172174
    return $this;
    173175
    }
    176+
    177+
    /**
    178+
    * {@inheritdoc}
    179+
    */
    180+
    public function setPath(array $paths)
    181+
    {
    182+
    $this->paths = $paths;
    183+
    184+
    return $this;
    185+
    }
    186+
    187+
    /**
    188+
    * {@inheritdoc}
    189+
    */
    190+
    public function setNotPath(array $notPaths)
    191+
    {
    192+
    $this->notPaths = $notPaths;
    193+
    194+
    return $this;
    195+
    }
    196+
    174197
    }

    src/Symfony/Component/Finder/Adapter/PhpAdapter.php

    Lines changed: 4 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -73,6 +73,10 @@ public function searchInDirectory($dir)
    7373
    $iterator = $iteratorAggregate->getIterator();
    7474
    }
    7575

    76+
    if ($this->paths || $this->notPaths) {
    77+
    $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
    78+
    }
    79+
    7680
    return $iterator;
    7781
    }
    7882

    src/Symfony/Component/Finder/Finder.php

    Lines changed: 51 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -52,6 +52,8 @@ class Finder implements \IteratorAggregate, \Countable
    5252
    private $contains = array();
    5353
    private $notContains = array();
    5454
    private $adapters = array();
    55+
    private $paths = array();
    56+
    private $notPaths = array();
    5557

    5658
    private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
    5759

    @@ -283,6 +285,52 @@ public function notContains($pattern)
    283285
    return $this;
    284286
    }
    285287

    288+
    /**
    289+
    * Adds rules that filenames must match.
    290+
    *
    291+
    * You can use patterns (delimited with / sign) or simple strings.
    292+
    *
    293+
    * $finder->path('some/special/dir')
    294+
    * $finder->path('/some\/special\/dir/') // same as above
    295+
    *
    296+
    * Use only / as dirname separator.
    297+
    *
    298+
    * @param string $pattern A pattern (a regexp or a string)
    299+
    *
    300+
    * @return Finder The current Finder instance
    301+
    *
    302+
    * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
    303+
    */
    304+
    public function path($pattern)
    305+
    {
    306+
    $this->paths[] = $pattern;
    307+
    308+
    return $this;
    309+
    }
    310+
    311+
    /**
    312+
    * Adds rules that filenames must not match.
    313+
    *
    314+
    * You can use patterns (delimited with / sign) or simple strings.
    315+
    *
    316+
    * $finder->notPath('some/special/dir')
    317+
    * $finder->notPath('/some\/special\/dir/') // same as above
    318+
    *
    319+
    * Use only / as dirname separator.
    320+
    *
    321+
    * @param string $pattern A pattern (a regexp or a string)
    322+
    *
    323+
    * @return Finder The current Finder instance
    324+
    *
    325+
    * @see Symfony\Component\Finder\Iterator\FilenameFilterIterator
    326+
    */
    327+
    public function notPath($pattern)
    328+
    {
    329+
    $this->notPaths[] = $pattern;
    330+
    331+
    return $this;
    332+
    }
    333+
    286334
    /**
    287335
    * Adds tests for file sizes.
    288336
    *
    @@ -682,6 +730,8 @@ private function buildAdapter(AdapterInterface $adapter)
    682730
    ->setSizes($this->sizes)
    683731
    ->setDates($this->dates)
    684732
    ->setFilters($this->filters)
    685-
    ->setSort($this->sort);
    733+
    ->setSort($this->sort)
    734+
    ->setPath($this->paths)
    735+
    ->setNotPath($this->notPaths);
    686736
    }
    687737
    }
    Lines changed: 75 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,75 @@
    1+
    <?php
    2+
    3+
    /*
    4+
    * This file is part of the Symfony package.
    5+
    *
    6+
    * (c) Fabien Potencier <fabien@symfony.com>
    7+
    *
    8+
    * For the full copyright and license information, please view the LICENSE
    9+
    * file that was distributed with this source code.
    10+
    */
    11+
    12+
    namespace Symfony\Component\Finder\Iterator;
    13+
    14+
    /**
    15+
    * PathFilterIterator filters files by path patterns (e.g. some/special/dir).
    16+
    *
    17+
    * @author Fabien Potencier <fabien@symfony.com>
    18+
    * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
    19+
    */
    20+
    class PathFilterIterator extends MultiplePcreFilterIterator
    21+
    {
    22+
    23+
    /**
    24+
    * Filters the iterator values.
    25+
    *
    26+
    * @return Boolean true if the value should be kept, false otherwise
    27+
    */
    28+
    public function accept()
    29+
    {
    30+
    $filename = $this->current()->getRelativePathname();
    31+
    32+
    if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
    33+
    $filename = strtr($filename, '\\', '/');
    34+
    }
    35+
    36+
    // should at least not match one rule to exclude
    37+
    foreach ($this->noMatchRegexps as $regex) {
    38+
    if (preg_match($regex, $filename)) {
    39+
    return false;
    40+
    }
    41+
    }
    42+
    43+
    // should at least match one rule
    44+
    $match = true;
    45+
    if ($this->matchRegexps) {
    46+
    $match = false;
    47+
    foreach ($this->matchRegexps as $regex) {
    48+
    if (preg_match($regex, $filename)) {
    49+
    return true;
    50+
    }
    51+
    }
    52+
    }
    53+
    54+
    return $match;
    55+
    }
    56+
    57+
    /**
    58+
    * Converts strings to regexp.
    59+
    *
    60+
    * PCRE patterns are left unchanged.
    61+
    *
    62+
    * Default conversion:
    63+
    * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/'
    64+
    *
    65+
    * Use only / as directory separator (on Windows also).
    66+
    *
    67+
    * @param string $str Pattern: regexp or dirname.
    68+
    *
    69+
    * @return string regexp corresponding to a given string or regexp
    70+
    */
    71+
    protected function toRegex($str)
    72+
    {
    73+
    return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
    74+
    }
    75+
    }

    src/Symfony/Component/Finder/Tests/FinderTest.php

    Lines changed: 61 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -646,4 +646,65 @@ private function buildTestData(array $tests)
    646646

    647647
    return $data;
    648648
    }
    649+
    650+
    /**
    651+
    * @dataProvider getTestPathData
    652+
    */
    653+
    public function testPath($matchPatterns, $noMatchPatterns, $expected)
    654+
    {
    655+
    $finder = new Finder();
    656+
    $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
    657+
    ->path($matchPatterns)
    658+
    ->notPath($noMatchPatterns);
    659+
    660+
    $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
    661+
    }
    662+
    663+
    public function getTestPathData()
    664+
    {
    665+
    return array(
    666+
    array('', '', array()),
    667+
    668+
    array('/^A\/B\/C/', '/C$/',
    669+
    array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat')
    670+
    ),
    671+
    672+
    array('/^A\/B/', 'foobar',
    673+
    array(
    674+
    'A'.DIRECTORY_SEPARATOR.'B',
    675+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
    676+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
    677+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
    678+
    )
    679+
    ),
    680+
    681+
    array('A/B/C', 'foobar',
    682+
    array(
    683+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
    684+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
    685+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
    686+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
    687+
    )
    688+
    ),
    689+
    690+
    array('A/B', 'foobar',
    691+
    array(
    692+
    //dirs
    693+
    'A'.DIRECTORY_SEPARATOR.'B',
    694+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
    695+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
    696+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
    697+
    698+
    //files
    699+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
    700+
    'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
    701+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
    702+
    'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
    703+
    )
    704+
    ),
    705+
    706+
    707+
    );
    708+
    }
    709+
    649710
    }

    src/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Fixtures/A/a.dat

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy

    Whitespace-only changes.

    src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php

    Lines changed: 2 additions & 104 deletions
    Original file line numberDiff line numberDiff line change
    @@ -12,6 +12,8 @@
    1212
    namespace Symfony\Component\Finder\Tests\Iterator;
    1313

    1414
    use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
    15+
    use Symfony\Component\Finder\Tests\Iterator\MockSplFileInfo;
    16+
    use Symfony\Component\Finder\Tests\Iterator\MockFileListIterator;
    1517

    1618
    class FilecontentFilterIteratorTest extends IteratorTestCase
    1719
    {
    @@ -85,107 +87,3 @@ public function getTestFilterData()
    8587
    );
    8688
    }
    8789
    }
    88-
    89-
    class MockSplFileInfo extends \SplFileInfo
    90-
    {
    91-
    const TYPE_DIRECTORY = 1;
    92-
    const TYPE_FILE = 2;
    93-
    const TYPE_UNKNOWN = 3;
    94-
    95-
    private $contents = null;
    96-
    private $mode = null;
    97-
    private $type = null;
    98-
    99-
    public function __construct($param)
    100-
    {
    101-
    if (is_string($param)) {
    102-
    parent::__construct($param);
    103-
    } elseif (is_array($param)) {
    104-
    105-
    $defaults = array(
    106-
    'name' => 'file.txt',
    107-
    'contents' => null,
    108-
    'mode' => null,
    109-
    'type' => null
    110-
    );
    111-
    $defaults = array_merge($defaults, $param);
    112-
    parent::__construct($defaults['name']);
    113-
    $this->setContents($defaults['contents']);
    114-
    $this->setMode($defaults['mode']);
    115-
    $this->setType($defaults['type']);
    116-
    } else {
    117-
    throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
    118-
    }
    119-
    }
    120-
    121-
    public function isFile()
    122-
    {
    123-
    if ($this->type === null) {
    124-
    return preg_match('/file/', $this->getFilename());
    125-
    };
    126-
    127-
    return self::TYPE_FILE === $this->type;
    128-
    }
    129-
    130-
    public function isDir()
    131-
    {
    132-
    if ($this->type === null) {
    133-
    return preg_match('/directory/', $this->getFilename());
    134-
    }
    135-
    136-
    return self::TYPE_DIRECTORY === $this->type;
    137-
    }
    138-
    139-
    public function isReadable()
    140-
    {
    141-
    if ($this->mode === null) {
    142-
    return preg_match('/r\+/', $this->getFilename());
    143-
    }
    144-
    145-
    return preg_match('/r\+/', $this->mode);
    146-
    }
    147-
    148-
    public function getContents()
    149-
    {
    150-
    return $this->contents;
    151-
    }
    152-
    153-
    public function setContents($contents)
    154-
    {
    155-
    $this->contents = $contents;
    156-
    }
    157-
    158-
    public function setMode($mode)
    159-
    {
    160-
    $this->mode = $mode;
    161-
    }
    162-
    163-
    public function setType($type)
    164-
    {
    165-
    if (is_string($type)) {
    166-
    switch ($type) {
    167-
    case 'directory':
    168-
    case 'd':
    169-
    $this->type = self::TYPE_DIRECTORY;
    170-
    break;
    171-
    case 'file':
    172-
    case 'f':
    173-
    $this->type = self::TYPE_FILE;
    174-
    break;
    175-
    default:
    176-
    $this->type = self::TYPE_UNKNOWN;
    177-
    }
    178-
    } else {
    179-
    $this->type = $type;
    180-
    }
    181-
    }
    182-
    }
    183-
    184-
    class MockFileListIterator extends \ArrayIterator
    185-
    {
    186-
    public function __construct(array $filesArray = array())
    187-
    {
    188-
    $files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray);
    189-
    parent::__construct($files);
    190-
    }
    191-
    }
    Lines changed: 21 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,21 @@
    1+
    <?php
    2+
    3+
    /*
    4+
    * This file is part of the Symfony package.
    5+
    *
    6+
    * (c) Fabien Potencier <fabien@symfony.com>
    7+
    *
    8+
    * For the full copyright and license information, please view the LICENSE
    9+
    * file that was distributed with this source code.
    10+
    */
    11+
    12+
    namespace Symfony\Component\Finder\Tests\Iterator;
    13+
    14+
    class MockFileListIterator extends \ArrayIterator
    15+
    {
    16+
    public function __construct(array $filesArray = array())
    17+
    {
    18+
    $files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray);
    19+
    parent::__construct($files);
    20+
    }
    21+
    }

    0 commit comments

    Comments
     (0)
    0