Completed
Pull Request — 2.x (#402)
by
unknown
01:58
created

Enumerator::dumpForAppVeyor()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/*
3
 * Go! AOP framework
4
 *
5
 * @copyright Copyright 2015, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\Instrument\FileSystem;
12
13
use CallbackFilterIterator;
14
use InvalidArgumentException;
15
use LogicException;
16
use RecursiveIteratorIterator;
17
use SplFileInfo;
18
use Symfony\Component\Finder\Finder;
19
use UnexpectedValueException;
20
21
/**
22
 * Enumerates files in the concrete directory, applying filtration logic
23
 */
24
class Enumerator
25
{
26
27
    /**
28
     * Path to the root directory, where enumeration should start
29
     *
30
     * @var string
31
     */
32
    private $rootDirectory;
33
34
    /**
35
     * List of additional include paths, should be below rootDirectory
36
     *
37
     * @var array
38
     */
39
    private $includePaths;
40
41
    /**
42
     * List of additional exclude paths, should be below rootDirectory
43
     *
44
     * @var array
45
     */
46
    private $excludePaths;
47
48
    /**
49
     * Initializes an enumerator
50
     *
51
     * @param string $rootDirectory Path to the root directory
52
     * @param array  $includePaths  List of additional include paths
53
     * @param array  $excludePaths  List of additional exclude paths
54
     */
55 7
    public function __construct($rootDirectory, array $includePaths = [], array $excludePaths = [])
56
    {
57 7
        $this->rootDirectory = $rootDirectory;
58 7
        $this->includePaths = $includePaths;
59 7
        $this->excludePaths = $excludePaths;
60 7
    }
61
62
    /**
63
     * Returns an enumerator for files
64
     *
65
     * @return CallbackFilterIterator|RecursiveIteratorIterator|\IteratorIterator|SplFileInfo[]
66
     * @throws UnexpectedValueException
67
     * @throws InvalidArgumentException
68
     * @throws LogicException
69
     */
70 7
    public function enumerate()
71
    {
72 7
        $finder = new Finder();
73 7
        $finder->files()
74 7
            ->name('*.php')
75 7
            ->in($this->getInPaths());
76
77 7
        foreach ($this->getExcludePaths() as $path) {
78 4
            $finder->notPath($path);
79
        }
80
81 7
        $this->dumpForAppVeyor($finder->getIterator());
82 7
        $iterator = new \RecursiveIteratorIterator(
83 7
            new \RecursiveDirectoryIterator(
84 7
                $this->rootDirectory,
85 7
                \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS
86
            )
87
        );
88
89 7
        $callback = $this->getFilter();
90 7
        $iterator = new \CallbackFilterIterator($iterator, $callback);
91
92 7
        $this->dumpForAppVeyor($iterator);
93
94 7
        return $finder->getIterator();
95
    }
96
97 7
    private function dumpForAppVeyor($iterator)
98
    {
99 7
        echo 'start' . PHP_EOL . PHP_EOL;
100
101 7
        foreach ($iterator as $thing) {
102 5
            var_dump($thing->getRealPath());
0 ignored issues
show
Security Debugging Code introduced by
var_dump($thing->getRealPath()); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
103
        }
104 7
    }
105
106
    /**
107
     * @return array
108
     * @throws UnexpectedValueException
109
     */
110 7
    private function getInPaths()
111
    {
112 7
        $inPaths = [];
113
114 7
        foreach ($this->includePaths as $path) {
115 1
            if (strpos($path, $this->rootDirectory, 0) === false) {
116
                throw new UnexpectedValueException(sprintf('Path %s is not in %s', $path, $this->rootDirectory));
117
            }
118
119 1
            $path = str_replace('*', '', $path);
120 1
            $inPaths[] = $path;
121
        }
122
123 7
        if (empty($inPaths)) {
124 6
            $inPaths[] = $this->rootDirectory;
125
        }
126
127 7
        return $inPaths;
128
    }
129
130
    /**
131
     * @return array
132
     */
133 7
    private function getExcludePaths()
134
    {
135 7
        $excludePaths = [];
136
137 7
        foreach ($this->excludePaths as $path) {
138 4
            $path = str_replace('*', '.*', $path);
139 4
            $excludePaths[] = '#' . str_replace($this->rootDirectory . '/', '', $path) . '#';
140
        }
141
142 7
        return $excludePaths;
143
    }
144
145
    /**
146
     * Returns a filter callback for enumerating files
147
     *
148
     * @return \Closure
149
     */
150 7
    public function getFilter()
151
    {
152 7
        $rootDirectory = $this->rootDirectory;
153 7
        $includePaths = $this->includePaths;
154 7
        $excludePaths = $this->excludePaths;
155
156 7
        return function (SplFileInfo $file) use ($rootDirectory, $includePaths, $excludePaths) {
157
158 7
            if ($file->getExtension() !== 'php') {
159
                return false;
160
            }
161
162 7
            $fullPath = $this->getFileFullPath($file);
163
            // Do not touch files that not under rootDirectory
164 7
            if (strpos($fullPath, $rootDirectory) !== 0) {
165
                return false;
166
            }
167
168 7
            if (!empty($includePaths)) {
169 1
                $found = false;
170 1
                foreach ($includePaths as $includePattern) {
171 1
                    if (fnmatch("{$includePattern}*", $fullPath, FNM_NOESCAPE)) {
172 1
                        $found = true;
173 1
                        break;
174
                    }
175
                }
176 1
                if (!$found) {
177
                    return false;
178
                }
179
            }
180
181 7
            foreach ($excludePaths as $excludePattern) {
182 4
                if (fnmatch("{$excludePattern}*", $fullPath, FNM_NOESCAPE)) {
183 4
                    return false;
184
                }
185
            }
186
187 5
            return true;
188 7
        };
189
    }
190
191
    /**
192
     * Return the real path of the given file
193
     *
194
     * This is used for testing purpose with virtual file system.
195
     * In a vfs the 'realPath' methode will always return false.
196
     * So we have a chance to mock this single function to return different path.
197
     *
198
     * @param SplFileInfo $file
199
     *
200
     * @return string
201
     */
202 1
    protected function getFileFullPath(SplFileInfo $file)
203
    {
204 1
        return $file->getRealPath();
205
    }
206
207
}
208