aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/symfony/filesystem
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/filesystem')
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore4
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md18
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php24
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php24
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php471
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE19
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md45
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php982
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json31
-rw-r--r--vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist28
10 files changed, 1646 insertions, 0 deletions
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore b/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore
new file mode 100644
index 00000000..44de97a3
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore
@@ -0,0 +1,4 @@
1vendor/
2composer.lock
3phpunit.xml
4
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md b/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md
new file mode 100644
index 00000000..e6aee66a
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md
@@ -0,0 +1,18 @@
1CHANGELOG
2=========
3
42.3.0
5-----
6
7 * added the dumpFile() method to atomically write files
8
92.2.0
10-----
11
12 * added a delete option for the mirror() method
13
142.1.0
15-----
16
17 * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value
18 * created the component
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php
new file mode 100644
index 00000000..bc9748d7
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php
@@ -0,0 +1,24 @@
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
12namespace Symfony\Component\Filesystem\Exception;
13
14/**
15 * Exception interface for all exceptions thrown by the component.
16 *
17 * @author Romain Neutron <imprec@gmail.com>
18 *
19 * @api
20 */
21interface ExceptionInterface
22{
23
24}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php
new file mode 100644
index 00000000..5b27e661
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php
@@ -0,0 +1,24 @@
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
12namespace Symfony\Component\Filesystem\Exception;
13
14/**
15 * Exception class thrown when a filesystem operation failure happens
16 *
17 * @author Romain Neutron <imprec@gmail.com>
18 *
19 * @api
20 */
21class IOException extends \RuntimeException implements ExceptionInterface
22{
23
24}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php
new file mode 100644
index 00000000..6e015b4b
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php
@@ -0,0 +1,471 @@
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
12namespace Symfony\Component\Filesystem;
13
14use Symfony\Component\Filesystem\Exception\IOException;
15
16/**
17 * Provides basic utility to manipulate the file system.
18 *
19 * @author Fabien Potencier <fabien@symfony.com>
20 */
21class Filesystem
22{
23 /**
24 * Copies a file.
25 *
26 * This method only copies the file if the origin file is newer than the target file.
27 *
28 * By default, if the target already exists, it is not overridden.
29 *
30 * @param string $originFile The original filename
31 * @param string $targetFile The target filename
32 * @param boolean $override Whether to override an existing file or not
33 *
34 * @throws IOException When copy fails
35 */
36 public function copy($originFile, $targetFile, $override = false)
37 {
38 if (stream_is_local($originFile) && !is_file($originFile)) {
39 throw new IOException(sprintf('Failed to copy %s because file not exists', $originFile));
40 }
41
42 $this->mkdir(dirname($targetFile));
43
44 if (!$override && is_file($targetFile)) {
45 $doCopy = filemtime($originFile) > filemtime($targetFile);
46 } else {
47 $doCopy = true;
48 }
49
50 if ($doCopy) {
51 // https://bugs.php.net/bug.php?id=64634
52 $source = fopen($originFile, 'r');
53 $target = fopen($targetFile, 'w+');
54 stream_copy_to_stream($source, $target);
55 fclose($source);
56 fclose($target);
57 unset($source, $target);
58
59 if (!is_file($targetFile)) {
60 throw new IOException(sprintf('Failed to copy %s to %s', $originFile, $targetFile));
61 }
62 }
63 }
64
65 /**
66 * Creates a directory recursively.
67 *
68 * @param string|array|\Traversable $dirs The directory path
69 * @param integer $mode The directory mode
70 *
71 * @throws IOException On any directory creation failure
72 */
73 public function mkdir($dirs, $mode = 0777)
74 {
75 foreach ($this->toIterator($dirs) as $dir) {
76 if (is_dir($dir)) {
77 continue;
78 }
79
80 if (true !== @mkdir($dir, $mode, true)) {
81 throw new IOException(sprintf('Failed to create %s', $dir));
82 }
83 }
84 }
85
86 /**
87 * Checks the existence of files or directories.
88 *
89 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to check
90 *
91 * @return Boolean true if the file exists, false otherwise
92 */
93 public function exists($files)
94 {
95 foreach ($this->toIterator($files) as $file) {
96 if (!file_exists($file)) {
97 return false;
98 }
99 }
100
101 return true;
102 }
103
104 /**
105 * Sets access and modification time of file.
106 *
107 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to create
108 * @param integer $time The touch time as a unix timestamp
109 * @param integer $atime The access time as a unix timestamp
110 *
111 * @throws IOException When touch fails
112 */
113 public function touch($files, $time = null, $atime = null)
114 {
115 foreach ($this->toIterator($files) as $file) {
116 $touch = $time ? @touch($file, $time, $atime) : @touch($file);
117 if (true !== $touch) {
118 throw new IOException(sprintf('Failed to touch %s', $file));
119 }
120 }
121 }
122
123 /**
124 * Removes files or directories.
125 *
126 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
127 *
128 * @throws IOException When removal fails
129 */
130 public function remove($files)
131 {
132 $files = iterator_to_array($this->toIterator($files));
133 $files = array_reverse($files);
134 foreach ($files as $file) {
135 if (!file_exists($file) && !is_link($file)) {
136 continue;
137 }
138
139 if (is_dir($file) && !is_link($file)) {
140 $this->remove(new \FilesystemIterator($file));
141
142 if (true !== @rmdir($file)) {
143 throw new IOException(sprintf('Failed to remove directory %s', $file));
144 }
145 } else {
146 // https://bugs.php.net/bug.php?id=52176
147 if (defined('PHP_WINDOWS_VERSION_MAJOR') && is_dir($file)) {
148 if (true !== @rmdir($file)) {
149 throw new IOException(sprintf('Failed to remove file %s', $file));
150 }
151 } else {
152 if (true !== @unlink($file)) {
153 throw new IOException(sprintf('Failed to remove file %s', $file));
154 }
155 }
156 }
157 }
158 }
159
160 /**
161 * Change mode for an array of files or directories.
162 *
163 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change mode
164 * @param integer $mode The new mode (octal)
165 * @param integer $umask The mode mask (octal)
166 * @param Boolean $recursive Whether change the mod recursively or not
167 *
168 * @throws IOException When the change fail
169 */
170 public function chmod($files, $mode, $umask = 0000, $recursive = false)
171 {
172 foreach ($this->toIterator($files) as $file) {
173 if ($recursive && is_dir($file) && !is_link($file)) {
174 $this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
175 }
176 if (true !== @chmod($file, $mode & ~$umask)) {
177 throw new IOException(sprintf('Failed to chmod file %s', $file));
178 }
179 }
180 }
181
182 /**
183 * Change the owner of an array of files or directories
184 *
185 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change owner
186 * @param string $user The new owner user name
187 * @param Boolean $recursive Whether change the owner recursively or not
188 *
189 * @throws IOException When the change fail
190 */
191 public function chown($files, $user, $recursive = false)
192 {
193 foreach ($this->toIterator($files) as $file) {
194 if ($recursive && is_dir($file) && !is_link($file)) {
195 $this->chown(new \FilesystemIterator($file), $user, true);
196 }
197 if (is_link($file) && function_exists('lchown')) {
198 if (true !== @lchown($file, $user)) {
199 throw new IOException(sprintf('Failed to chown file %s', $file));
200 }
201 } else {
202 if (true !== @chown($file, $user)) {
203 throw new IOException(sprintf('Failed to chown file %s', $file));
204 }
205 }
206 }
207 }
208
209 /**
210 * Change the group of an array of files or directories
211 *
212 * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change group
213 * @param string $group The group name
214 * @param Boolean $recursive Whether change the group recursively or not
215 *
216 * @throws IOException When the change fail
217 */
218 public function chgrp($files, $group, $recursive = false)
219 {
220 foreach ($this->toIterator($files) as $file) {
221 if ($recursive && is_dir($file) && !is_link($file)) {
222 $this->chgrp(new \FilesystemIterator($file), $group, true);
223 }
224 if (is_link($file) && function_exists('lchgrp')) {
225 if (true !== @lchgrp($file, $group)) {
226 throw new IOException(sprintf('Failed to chgrp file %s', $file));
227 }
228 } else {
229 if (true !== @chgrp($file, $group)) {
230 throw new IOException(sprintf('Failed to chgrp file %s', $file));
231 }
232 }
233 }
234 }
235
236 /**
237 * Renames a file or a directory.
238 *
239 * @param string $origin The origin filename or directory
240 * @param string $target The new filename or directory
241 * @param Boolean $overwrite Whether to overwrite the target if it already exists
242 *
243 * @throws IOException When target file or directory already exists
244 * @throws IOException When origin cannot be renamed
245 */
246 public function rename($origin, $target, $overwrite = false)
247 {
248 // we check that target does not exist
249 if (!$overwrite && is_readable($target)) {
250 throw new IOException(sprintf('Cannot rename because the target "%s" already exist.', $target));
251 }
252
253 if (true !== @rename($origin, $target)) {
254 throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target));
255 }
256 }
257
258 /**
259 * Creates a symbolic link or copy a directory.
260 *
261 * @param string $originDir The origin directory path
262 * @param string $targetDir The symbolic link name
263 * @param Boolean $copyOnWindows Whether to copy files if on Windows
264 *
265 * @throws IOException When symlink fails
266 */
267 public function symlink($originDir, $targetDir, $copyOnWindows = false)
268 {
269 if (!function_exists('symlink') && $copyOnWindows) {
270 $this->mirror($originDir, $targetDir);
271
272 return;
273 }
274
275 $this->mkdir(dirname($targetDir));
276
277 $ok = false;
278 if (is_link($targetDir)) {
279 if (readlink($targetDir) != $originDir) {
280 $this->remove($targetDir);
281 } else {
282 $ok = true;
283 }
284 }
285
286 if (!$ok) {
287 if (true !== @symlink($originDir, $targetDir)) {
288 $report = error_get_last();
289 if (is_array($report)) {
290 if (defined('PHP_WINDOWS_VERSION_MAJOR') && false !== strpos($report['message'], 'error code(1314)')) {
291 throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?');
292 }
293 }
294 throw new IOException(sprintf('Failed to create symbolic link from %s to %s', $originDir, $targetDir));
295 }
296 }
297 }
298
299 /**
300 * Given an existing path, convert it to a path relative to a given starting path
301 *
302 * @param string $endPath Absolute path of target
303 * @param string $startPath Absolute path where traversal begins
304 *
305 * @return string Path of target relative to starting path
306 */
307 public function makePathRelative($endPath, $startPath)
308 {
309 // Normalize separators on windows
310 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
311 $endPath = strtr($endPath, '\\', '/');
312 $startPath = strtr($startPath, '\\', '/');
313 }
314
315 // Split the paths into arrays
316 $startPathArr = explode('/', trim($startPath, '/'));
317 $endPathArr = explode('/', trim($endPath, '/'));
318
319 // Find for which directory the common path stops
320 $index = 0;
321 while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
322 $index++;
323 }
324
325 // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
326 $depth = count($startPathArr) - $index;
327
328 // Repeated "../" for each level need to reach the common path
329 $traverser = str_repeat('../', $depth);
330
331 $endPathRemainder = implode('/', array_slice($endPathArr, $index));
332
333 // Construct $endPath from traversing to the common path, then to the remaining $endPath
334 $relativePath = $traverser.(strlen($endPathRemainder) > 0 ? $endPathRemainder.'/' : '');
335
336 return (strlen($relativePath) === 0) ? './' : $relativePath;
337 }
338
339 /**
340 * Mirrors a directory to another.
341 *
342 * @param string $originDir The origin directory
343 * @param string $targetDir The target directory
344 * @param \Traversable $iterator A Traversable instance
345 * @param array $options An array of boolean options
346 * Valid options are:
347 * - $options['override'] Whether to override an existing file on copy or not (see copy())
348 * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink())
349 * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
350 *
351 * @throws IOException When file type is unknown
352 */
353 public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
354 {
355 $targetDir = rtrim($targetDir, '/\\');
356 $originDir = rtrim($originDir, '/\\');
357
358 // Iterate in destination folder to remove obsolete entries
359 if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
360 $deleteIterator = $iterator;
361 if (null === $deleteIterator) {
362 $flags = \FilesystemIterator::SKIP_DOTS;
363 $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
364 }
365 foreach ($deleteIterator as $file) {
366 $origin = str_replace($targetDir, $originDir, $file->getPathname());
367 if (!$this->exists($origin)) {
368 $this->remove($file);
369 }
370 }
371 }
372
373 $copyOnWindows = false;
374 if (isset($options['copy_on_windows']) && !function_exists('symlink')) {
375 $copyOnWindows = $options['copy_on_windows'];
376 }
377
378 if (null === $iterator) {
379 $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
380 $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
381 }
382
383 foreach ($iterator as $file) {
384 $target = str_replace($originDir, $targetDir, $file->getPathname());
385
386 if ($copyOnWindows) {
387 if (is_link($file) || is_file($file)) {
388 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
389 } elseif (is_dir($file)) {
390 $this->mkdir($target);
391 } else {
392 throw new IOException(sprintf('Unable to guess "%s" file type.', $file));
393 }
394 } else {
395 if (is_link($file)) {
396 $this->symlink($file, $target);
397 } elseif (is_dir($file)) {
398 $this->mkdir($target);
399 } elseif (is_file($file)) {
400 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
401 } else {
402 throw new IOException(sprintf('Unable to guess "%s" file type.', $file));
403 }
404 }
405 }
406 }
407
408 /**
409 * Returns whether the file path is an absolute path.
410 *
411 * @param string $file A file path
412 *
413 * @return Boolean
414 */
415 public function isAbsolutePath($file)
416 {
417 if (strspn($file, '/\\', 0, 1)
418 || (strlen($file) > 3 && ctype_alpha($file[0])
419 && substr($file, 1, 1) === ':'
420 && (strspn($file, '/\\', 2, 1))
421 )
422 || null !== parse_url($file, PHP_URL_SCHEME)
423 ) {
424 return true;
425 }
426
427 return false;
428 }
429
430 /**
431 * @param mixed $files
432 *
433 * @return \Traversable
434 */
435 private function toIterator($files)
436 {
437 if (!$files instanceof \Traversable) {
438 $files = new \ArrayObject(is_array($files) ? $files : array($files));
439 }
440
441 return $files;
442 }
443
444 /**
445 * Atomically dumps content into a file.
446 *
447 * @param string $filename The file to be written to.
448 * @param string $content The data to write into the file.
449 * @param integer $mode The file mode (octal).
450 * @throws IOException If the file cannot be written to.
451 */
452 public function dumpFile($filename, $content, $mode = 0666)
453 {
454 $dir = dirname($filename);
455
456 if (!is_dir($dir)) {
457 $this->mkdir($dir);
458 } elseif (!is_writable($dir)) {
459 throw new IOException(sprintf('Unable to write in the %s directory\n', $dir));
460 }
461
462 $tmpFile = tempnam($dir, basename($filename));
463
464 if (false === @file_put_contents($tmpFile, $content)) {
465 throw new IOException(sprintf('Failed to write file "%s".', $filename));
466 }
467
468 $this->rename($tmpFile, $filename, true);
469 $this->chmod($filename, $mode);
470 }
471}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE
new file mode 100644
index 00000000..88a57f8d
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE
@@ -0,0 +1,19 @@
1Copyright (c) 2004-2013 Fabien Potencier
2
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is furnished
8to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all
11copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19THE SOFTWARE.
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md b/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md
new file mode 100644
index 00000000..94ac1469
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md
@@ -0,0 +1,45 @@
1Filesystem Component
2====================
3
4Filesystem provides basic utility to manipulate the file system:
5
6```php
7<?php
8
9use Symfony\Component\Filesystem\Filesystem;
10
11$filesystem = new Filesystem();
12
13$filesystem->copy($originFile, $targetFile, $override = false);
14
15$filesystem->mkdir($dirs, $mode = 0777);
16
17$filesystem->touch($files, $time = null, $atime = null);
18
19$filesystem->remove($files);
20
21$filesystem->chmod($files, $mode, $umask = 0000, $recursive = false);
22
23$filesystem->chown($files, $user, $recursive = false);
24
25$filesystem->chgrp($files, $group, $recursive = false);
26
27$filesystem->rename($origin, $target);
28
29$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false);
30
31$filesystem->makePathRelative($endPath, $startPath);
32
33$filesystem->mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array());
34
35$filesystem->isAbsolutePath($file);
36```
37
38Resources
39---------
40
41You can run the unit tests with the following command:
42
43 $ cd path/to/Symfony/Component/Filesystem/
44 $ composer.phar install --dev
45 $ phpunit
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php
new file mode 100644
index 00000000..02969f30
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php
@@ -0,0 +1,982 @@
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
12namespace Symfony\Component\Filesystem\Tests;
13
14use Symfony\Component\Filesystem\Filesystem;
15
16/**
17 * Test class for Filesystem.
18 */
19class FilesystemTest extends \PHPUnit_Framework_TestCase
20{
21 /**
22 * @var string $workspace
23 */
24 private $workspace = null;
25
26 /**
27 * @var \Symfony\Component\Filesystem\Filesystem $filesystem
28 */
29 private $filesystem = null;
30
31 private static $symlinkOnWindows = null;
32
33 public static function setUpBeforeClass()
34 {
35 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
36 self::$symlinkOnWindows = true;
37 $originDir = tempnam(sys_get_temp_dir(), 'sl');
38 $targetDir = tempnam(sys_get_temp_dir(), 'sl');
39 if (true !== @symlink($originDir, $targetDir)) {
40 $report = error_get_last();
41 if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
42 self::$symlinkOnWindows = false;
43 }
44 }
45 }
46 }
47
48 public function setUp()
49 {
50 $this->filesystem = new Filesystem();
51 $this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000);
52 mkdir($this->workspace, 0777, true);
53 $this->workspace = realpath($this->workspace);
54 }
55
56 public function tearDown()
57 {
58 $this->clean($this->workspace);
59 }
60
61 /**
62 * @param string $file
63 */
64 private function clean($file)
65 {
66 if (is_dir($file) && !is_link($file)) {
67 $dir = new \FilesystemIterator($file);
68 foreach ($dir as $childFile) {
69 $this->clean($childFile);
70 }
71
72 rmdir($file);
73 } else {
74 unlink($file);
75 }
76 }
77
78 public function testCopyCreatesNewFile()
79 {
80 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
81 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
82
83 file_put_contents($sourceFilePath, 'SOURCE FILE');
84
85 $this->filesystem->copy($sourceFilePath, $targetFilePath);
86
87 $this->assertFileExists($targetFilePath);
88 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
89 }
90
91 /**
92 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
93 */
94 public function testCopyFails()
95 {
96 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
97 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
98
99 $this->filesystem->copy($sourceFilePath, $targetFilePath);
100 }
101
102 public function testCopyOverridesExistingFileIfModified()
103 {
104 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
105 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
106
107 file_put_contents($sourceFilePath, 'SOURCE FILE');
108 file_put_contents($targetFilePath, 'TARGET FILE');
109 touch($targetFilePath, time() - 1000);
110
111 $this->filesystem->copy($sourceFilePath, $targetFilePath);
112
113 $this->assertFileExists($targetFilePath);
114 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
115 }
116
117 public function testCopyDoesNotOverrideExistingFileByDefault()
118 {
119 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
120 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
121
122 file_put_contents($sourceFilePath, 'SOURCE FILE');
123 file_put_contents($targetFilePath, 'TARGET FILE');
124
125 // make sure both files have the same modification time
126 $modificationTime = time() - 1000;
127 touch($sourceFilePath, $modificationTime);
128 touch($targetFilePath, $modificationTime);
129
130 $this->filesystem->copy($sourceFilePath, $targetFilePath);
131
132 $this->assertFileExists($targetFilePath);
133 $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath));
134 }
135
136 public function testCopyOverridesExistingFileIfForced()
137 {
138 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
139 $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file';
140
141 file_put_contents($sourceFilePath, 'SOURCE FILE');
142 file_put_contents($targetFilePath, 'TARGET FILE');
143
144 // make sure both files have the same modification time
145 $modificationTime = time() - 1000;
146 touch($sourceFilePath, $modificationTime);
147 touch($targetFilePath, $modificationTime);
148
149 $this->filesystem->copy($sourceFilePath, $targetFilePath, true);
150
151 $this->assertFileExists($targetFilePath);
152 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
153 }
154
155 public function testCopyCreatesTargetDirectoryIfItDoesNotExist()
156 {
157 $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file';
158 $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
159 $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file';
160
161 file_put_contents($sourceFilePath, 'SOURCE FILE');
162
163 $this->filesystem->copy($sourceFilePath, $targetFilePath);
164
165 $this->assertTrue(is_dir($targetFileDirectory));
166 $this->assertFileExists($targetFilePath);
167 $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath));
168 }
169
170 public function testMkdirCreatesDirectoriesRecursively()
171 {
172 $directory = $this->workspace
173 .DIRECTORY_SEPARATOR.'directory'
174 .DIRECTORY_SEPARATOR.'sub_directory';
175
176 $this->filesystem->mkdir($directory);
177
178 $this->assertTrue(is_dir($directory));
179 }
180
181 public function testMkdirCreatesDirectoriesFromArray()
182 {
183 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
184 $directories = array(
185 $basePath.'1', $basePath.'2', $basePath.'3'
186 );
187
188 $this->filesystem->mkdir($directories);
189
190 $this->assertTrue(is_dir($basePath.'1'));
191 $this->assertTrue(is_dir($basePath.'2'));
192 $this->assertTrue(is_dir($basePath.'3'));
193 }
194
195 public function testMkdirCreatesDirectoriesFromTraversableObject()
196 {
197 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
198 $directories = new \ArrayObject(array(
199 $basePath.'1', $basePath.'2', $basePath.'3'
200 ));
201
202 $this->filesystem->mkdir($directories);
203
204 $this->assertTrue(is_dir($basePath.'1'));
205 $this->assertTrue(is_dir($basePath.'2'));
206 $this->assertTrue(is_dir($basePath.'3'));
207 }
208
209 /**
210 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
211 */
212 public function testMkdirCreatesDirectoriesFails()
213 {
214 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
215 $dir = $basePath.'2';
216
217 file_put_contents($dir, '');
218
219 $this->filesystem->mkdir($dir);
220 }
221
222 public function testTouchCreatesEmptyFile()
223 {
224 $file = $this->workspace.DIRECTORY_SEPARATOR.'1';
225
226 $this->filesystem->touch($file);
227
228 $this->assertFileExists($file);
229 }
230
231 /**
232 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
233 */
234 public function testTouchFails()
235 {
236 $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2';
237
238 $this->filesystem->touch($file);
239 }
240
241 public function testTouchCreatesEmptyFilesFromArray()
242 {
243 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
244 $files = array(
245 $basePath.'1', $basePath.'2', $basePath.'3'
246 );
247
248 $this->filesystem->touch($files);
249
250 $this->assertFileExists($basePath.'1');
251 $this->assertFileExists($basePath.'2');
252 $this->assertFileExists($basePath.'3');
253 }
254
255 public function testTouchCreatesEmptyFilesFromTraversableObject()
256 {
257 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
258 $files = new \ArrayObject(array(
259 $basePath.'1', $basePath.'2', $basePath.'3'
260 ));
261
262 $this->filesystem->touch($files);
263
264 $this->assertFileExists($basePath.'1');
265 $this->assertFileExists($basePath.'2');
266 $this->assertFileExists($basePath.'3');
267 }
268
269 public function testRemoveCleansFilesAndDirectoriesIteratively()
270 {
271 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
272
273 mkdir($basePath);
274 mkdir($basePath.'dir');
275 touch($basePath.'file');
276
277 $this->filesystem->remove($basePath);
278
279 $this->assertTrue(!is_dir($basePath));
280 }
281
282 public function testRemoveCleansArrayOfFilesAndDirectories()
283 {
284 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
285
286 mkdir($basePath.'dir');
287 touch($basePath.'file');
288
289 $files = array(
290 $basePath.'dir', $basePath.'file'
291 );
292
293 $this->filesystem->remove($files);
294
295 $this->assertTrue(!is_dir($basePath.'dir'));
296 $this->assertTrue(!is_file($basePath.'file'));
297 }
298
299 public function testRemoveCleansTraversableObjectOfFilesAndDirectories()
300 {
301 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
302
303 mkdir($basePath.'dir');
304 touch($basePath.'file');
305
306 $files = new \ArrayObject(array(
307 $basePath.'dir', $basePath.'file'
308 ));
309
310 $this->filesystem->remove($files);
311
312 $this->assertTrue(!is_dir($basePath.'dir'));
313 $this->assertTrue(!is_file($basePath.'file'));
314 }
315
316 public function testRemoveIgnoresNonExistingFiles()
317 {
318 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
319
320 mkdir($basePath.'dir');
321
322 $files = array(
323 $basePath.'dir', $basePath.'file'
324 );
325
326 $this->filesystem->remove($files);
327
328 $this->assertTrue(!is_dir($basePath.'dir'));
329 }
330
331 public function testRemoveCleansInvalidLinks()
332 {
333 $this->markAsSkippedIfSymlinkIsMissing();
334
335 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
336
337 mkdir($basePath);
338 mkdir($basePath.'dir');
339 // create symlink to unexisting file
340 @symlink($basePath.'file', $basePath.'link');
341
342 $this->filesystem->remove($basePath);
343
344 $this->assertTrue(!is_dir($basePath));
345 }
346
347 public function testFilesExists()
348 {
349 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
350
351 mkdir($basePath);
352 touch($basePath.'file1');
353 mkdir($basePath.'folder');
354
355 $this->assertTrue($this->filesystem->exists($basePath.'file1'));
356 $this->assertTrue($this->filesystem->exists($basePath.'folder'));
357 }
358
359 public function testFilesExistsTraversableObjectOfFilesAndDirectories()
360 {
361 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
362
363 mkdir($basePath.'dir');
364 touch($basePath.'file');
365
366 $files = new \ArrayObject(array(
367 $basePath.'dir', $basePath.'file'
368 ));
369
370 $this->assertTrue($this->filesystem->exists($files));
371 }
372
373 public function testFilesNotExistsTraversableObjectOfFilesAndDirectories()
374 {
375 $basePath = $this->workspace.DIRECTORY_SEPARATOR;
376
377 mkdir($basePath.'dir');
378 touch($basePath.'file');
379 touch($basePath.'file2');
380
381 $files = new \ArrayObject(array(
382 $basePath.'dir', $basePath.'file', $basePath.'file2'
383 ));
384
385 unlink($basePath.'file');
386
387 $this->assertFalse($this->filesystem->exists($files));
388 }
389
390 public function testInvalidFileNotExists()
391 {
392 $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR;
393
394 $this->assertFalse($this->filesystem->exists($basePath.time()));
395 }
396
397 public function testChmodChangesFileMode()
398 {
399 $this->markAsSkippedIfChmodIsMissing();
400
401 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
402 mkdir($dir);
403 $file = $dir.DIRECTORY_SEPARATOR.'file';
404 touch($file);
405
406 $this->filesystem->chmod($file, 0400);
407 $this->filesystem->chmod($dir, 0753);
408
409 $this->assertEquals(753, $this->getFilePermissions($dir));
410 $this->assertEquals(400, $this->getFilePermissions($file));
411 }
412
413 public function testChmodWrongMod()
414 {
415 $this->markAsSkippedIfChmodIsMissing();
416
417 $dir = $this->workspace.DIRECTORY_SEPARATOR.'file';
418 touch($dir);
419
420 $this->filesystem->chmod($dir, 'Wrongmode');
421 }
422
423 public function testChmodRecursive()
424 {
425 $this->markAsSkippedIfChmodIsMissing();
426
427 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
428 mkdir($dir);
429 $file = $dir.DIRECTORY_SEPARATOR.'file';
430 touch($file);
431
432 $this->filesystem->chmod($file, 0400, 0000, true);
433 $this->filesystem->chmod($dir, 0753, 0000, true);
434
435 $this->assertEquals(753, $this->getFilePermissions($dir));
436 $this->assertEquals(753, $this->getFilePermissions($file));
437 }
438
439 public function testChmodAppliesUmask()
440 {
441 $this->markAsSkippedIfChmodIsMissing();
442
443 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
444 touch($file);
445
446 $this->filesystem->chmod($file, 0770, 0022);
447 $this->assertEquals(750, $this->getFilePermissions($file));
448 }
449
450 public function testChmodChangesModeOfArrayOfFiles()
451 {
452 $this->markAsSkippedIfChmodIsMissing();
453
454 $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
455 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
456 $files = array($directory, $file);
457
458 mkdir($directory);
459 touch($file);
460
461 $this->filesystem->chmod($files, 0753);
462
463 $this->assertEquals(753, $this->getFilePermissions($file));
464 $this->assertEquals(753, $this->getFilePermissions($directory));
465 }
466
467 public function testChmodChangesModeOfTraversableFileObject()
468 {
469 $this->markAsSkippedIfChmodIsMissing();
470
471 $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory';
472 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
473 $files = new \ArrayObject(array($directory, $file));
474
475 mkdir($directory);
476 touch($file);
477
478 $this->filesystem->chmod($files, 0753);
479
480 $this->assertEquals(753, $this->getFilePermissions($file));
481 $this->assertEquals(753, $this->getFilePermissions($directory));
482 }
483
484 public function testChown()
485 {
486 $this->markAsSkippedIfPosixIsMissing();
487
488 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
489 mkdir($dir);
490
491 $this->filesystem->chown($dir, $this->getFileOwner($dir));
492 }
493
494 public function testChownRecursive()
495 {
496 $this->markAsSkippedIfPosixIsMissing();
497
498 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
499 mkdir($dir);
500 $file = $dir.DIRECTORY_SEPARATOR.'file';
501 touch($file);
502
503 $this->filesystem->chown($dir, $this->getFileOwner($dir), true);
504 }
505
506 public function testChownSymlink()
507 {
508 $this->markAsSkippedIfSymlinkIsMissing();
509
510 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
511 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
512
513 touch($file);
514
515 $this->filesystem->symlink($file, $link);
516
517 $this->filesystem->chown($link, $this->getFileOwner($link));
518 }
519
520 /**
521 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
522 */
523 public function testChownSymlinkFails()
524 {
525 $this->markAsSkippedIfSymlinkIsMissing();
526
527 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
528 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
529
530 touch($file);
531
532 $this->filesystem->symlink($file, $link);
533
534 $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
535 }
536
537 /**
538 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
539 */
540 public function testChownFail()
541 {
542 $this->markAsSkippedIfPosixIsMissing();
543
544 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
545 mkdir($dir);
546
547 $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999));
548 }
549
550 public function testChgrp()
551 {
552 $this->markAsSkippedIfPosixIsMissing();
553
554 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
555 mkdir($dir);
556
557 $this->filesystem->chgrp($dir, $this->getFileGroup($dir));
558 }
559
560 public function testChgrpRecursive()
561 {
562 $this->markAsSkippedIfPosixIsMissing();
563
564 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
565 mkdir($dir);
566 $file = $dir.DIRECTORY_SEPARATOR.'file';
567 touch($file);
568
569 $this->filesystem->chgrp($dir, $this->getFileGroup($dir), true);
570 }
571
572 public function testChgrpSymlink()
573 {
574 $this->markAsSkippedIfSymlinkIsMissing();
575
576 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
577 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
578
579 touch($file);
580
581 $this->filesystem->symlink($file, $link);
582
583 $this->filesystem->chgrp($link, $this->getFileGroup($link));
584 }
585
586 /**
587 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
588 */
589 public function testChgrpSymlinkFails()
590 {
591 $this->markAsSkippedIfSymlinkIsMissing();
592
593 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
594 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
595
596 touch($file);
597
598 $this->filesystem->symlink($file, $link);
599
600 $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
601 }
602
603 /**
604 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
605 */
606 public function testChgrpFail()
607 {
608 $this->markAsSkippedIfPosixIsMissing();
609
610 $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir';
611 mkdir($dir);
612
613 $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999));
614 }
615
616 public function testRename()
617 {
618 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
619 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
620 touch($file);
621
622 $this->filesystem->rename($file, $newPath);
623
624 $this->assertFileNotExists($file);
625 $this->assertFileExists($newPath);
626 }
627
628 /**
629 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
630 */
631 public function testRenameThrowsExceptionIfTargetAlreadyExists()
632 {
633 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
634 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
635
636 touch($file);
637 touch($newPath);
638
639 $this->filesystem->rename($file, $newPath);
640 }
641
642 public function testRenameOverwritesTheTargetIfItAlreadyExists()
643 {
644 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
645 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
646
647 touch($file);
648 touch($newPath);
649
650 $this->filesystem->rename($file, $newPath, true);
651
652 $this->assertFileNotExists($file);
653 $this->assertFileExists($newPath);
654 }
655
656 /**
657 * @expectedException \Symfony\Component\Filesystem\Exception\IOException
658 */
659 public function testRenameThrowsExceptionOnError()
660 {
661 $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid();
662 $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file';
663
664 $this->filesystem->rename($file, $newPath);
665 }
666
667 public function testSymlink()
668 {
669 $this->markAsSkippedIfSymlinkIsMissing();
670
671 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
672 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
673
674 touch($file);
675
676 $this->filesystem->symlink($file, $link);
677
678 $this->assertTrue(is_link($link));
679 $this->assertEquals($file, readlink($link));
680 }
681
682 /**
683 * @depends testSymlink
684 */
685 public function testRemoveSymlink()
686 {
687 $this->markAsSkippedIfSymlinkIsMissing();
688
689 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
690
691 $this->filesystem->remove($link);
692
693 $this->assertTrue(!is_link($link));
694 }
695
696 public function testSymlinkIsOverwrittenIfPointsToDifferentTarget()
697 {
698 $this->markAsSkippedIfSymlinkIsMissing();
699
700 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
701 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
702
703 touch($file);
704 symlink($this->workspace, $link);
705
706 $this->filesystem->symlink($file, $link);
707
708 $this->assertTrue(is_link($link));
709 $this->assertEquals($file, readlink($link));
710 }
711
712 public function testSymlinkIsNotOverwrittenIfAlreadyCreated()
713 {
714 $this->markAsSkippedIfSymlinkIsMissing();
715
716 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
717 $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
718
719 touch($file);
720 symlink($file, $link);
721
722 $this->filesystem->symlink($file, $link);
723
724 $this->assertTrue(is_link($link));
725 $this->assertEquals($file, readlink($link));
726 }
727
728 public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist()
729 {
730 $this->markAsSkippedIfSymlinkIsMissing();
731
732 $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
733 $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
734 $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';
735
736 touch($file);
737
738 $this->filesystem->symlink($file, $link1);
739 $this->filesystem->symlink($file, $link2);
740
741 $this->assertTrue(is_link($link1));
742 $this->assertEquals($file, readlink($link1));
743 $this->assertTrue(is_link($link2));
744 $this->assertEquals($file, readlink($link2));
745 }
746
747 /**
748 * @dataProvider providePathsForMakePathRelative
749 */
750 public function testMakePathRelative($endPath, $startPath, $expectedPath)
751 {
752 $path = $this->filesystem->makePathRelative($endPath, $startPath);
753
754 $this->assertEquals($expectedPath, $path);
755 }
756
757 /**
758 * @return array
759 */
760 public function providePathsForMakePathRelative()
761 {
762 $paths = array(
763 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'),
764 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
765 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
766 array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
767 array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
768 array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
769 array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
770 array('/aa/bb', '/aa/bb', './'),
771 array('/aa/bb', '/aa/bb/', './'),
772 array('/aa/bb/', '/aa/bb', './'),
773 array('/aa/bb/', '/aa/bb/', './'),
774 array('/aa/bb/cc', '/aa/bb/cc/dd', '../'),
775 array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'),
776 array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'),
777 array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'),
778 array('/aa/bb/cc', '/aa', 'bb/cc/'),
779 array('/aa/bb/cc', '/aa/', 'bb/cc/'),
780 array('/aa/bb/cc/', '/aa', 'bb/cc/'),
781 array('/aa/bb/cc/', '/aa/', 'bb/cc/'),
782 array('/a/aab/bb', '/a/aa', '../aab/bb/'),
783 array('/a/aab/bb', '/a/aa/', '../aab/bb/'),
784 array('/a/aab/bb/', '/a/aa', '../aab/bb/'),
785 array('/a/aab/bb/', '/a/aa/', '../aab/bb/'),
786 );
787
788 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
789 $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
790 }
791
792 return $paths;
793 }
794
795 public function testMirrorCopiesFilesAndDirectoriesRecursively()
796 {
797 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
798 $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR;
799 $file1 = $directory.'file1';
800 $file2 = $sourcePath.'file2';
801
802 mkdir($sourcePath);
803 mkdir($directory);
804 file_put_contents($file1, 'FILE1');
805 file_put_contents($file2, 'FILE2');
806
807 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
808
809 $this->filesystem->mirror($sourcePath, $targetPath);
810
811 $this->assertTrue(is_dir($targetPath));
812 $this->assertTrue(is_dir($targetPath.'directory'));
813 $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1');
814 $this->assertFileEquals($file2, $targetPath.'file2');
815
816 $this->filesystem->remove($file1);
817
818 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false));
819 $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
820
821 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
822 $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
823
824 file_put_contents($file1, 'FILE1');
825
826 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
827 $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
828
829 $this->filesystem->remove($directory);
830 $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true));
831 $this->assertFalse($this->filesystem->exists($targetPath.'directory'));
832 $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'));
833 }
834
835 public function testMirrorCopiesLinks()
836 {
837 $this->markAsSkippedIfSymlinkIsMissing();
838
839 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
840
841 mkdir($sourcePath);
842 file_put_contents($sourcePath.'file1', 'FILE1');
843 symlink($sourcePath.'file1', $sourcePath.'link1');
844
845 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
846
847 $this->filesystem->mirror($sourcePath, $targetPath);
848
849 $this->assertTrue(is_dir($targetPath));
850 $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR.'link1');
851 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
852 }
853
854 public function testMirrorCopiesLinkedDirectoryContents()
855 {
856 $this->markAsSkippedIfSymlinkIsMissing();
857
858 $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR;
859
860 mkdir($sourcePath.'nested/', 0777, true);
861 file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1');
862 // Note: We symlink directory, not file
863 symlink($sourcePath.'nested', $sourcePath.'link1');
864
865 $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
866
867 $this->filesystem->mirror($sourcePath, $targetPath);
868
869 $this->assertTrue(is_dir($targetPath));
870 $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt');
871 $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1'));
872 }
873
874 /**
875 * @dataProvider providePathsForIsAbsolutePath
876 */
877 public function testIsAbsolutePath($path, $expectedResult)
878 {
879 $result = $this->filesystem->isAbsolutePath($path);
880
881 $this->assertEquals($expectedResult, $result);
882 }
883
884 /**
885 * @return array
886 */
887 public function providePathsForIsAbsolutePath()
888 {
889 return array(
890 array('/var/lib', true),
891 array('c:\\\\var\\lib', true),
892 array('\\var\\lib', true),
893 array('var/lib', false),
894 array('../var/lib', false),
895 array('', false),
896 array(null, false)
897 );
898 }
899
900 public function testDumpFile()
901 {
902 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
903
904 $this->filesystem->dumpFile($filename, 'bar', 0753);
905
906 $this->assertFileExists($filename);
907 $this->assertSame('bar', file_get_contents($filename));
908
909 // skip mode check on windows
910 if (!defined('PHP_WINDOWS_VERSION_MAJOR')) {
911 $this->assertEquals(753, $this->getFilePermissions($filename));
912 }
913 }
914
915 public function testDumpFileOverwritesAnExistingFile()
916 {
917 $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
918 file_put_contents($filename, 'FOO BAR');
919
920 $this->filesystem->dumpFile($filename, 'bar');
921
922 $this->assertFileExists($filename);
923 $this->assertSame('bar', file_get_contents($filename));
924 }
925
926 /**
927 * Returns file permissions as three digits (i.e. 755)
928 *
929 * @param string $filePath
930 *
931 * @return integer
932 */
933 private function getFilePermissions($filePath)
934 {
935 return (int) substr(sprintf('%o', fileperms($filePath)), -3);
936 }
937
938 private function getFileOwner($filepath)
939 {
940 $this->markAsSkippedIfPosixIsMissing();
941
942 $infos = stat($filepath);
943 if ($datas = posix_getpwuid($infos['uid'])) {
944 return $datas['name'];
945 }
946 }
947
948 private function getFileGroup($filepath)
949 {
950 $this->markAsSkippedIfPosixIsMissing();
951
952 $infos = stat($filepath);
953 if ($datas = posix_getgrgid($infos['gid'])) {
954 return $datas['name'];
955 }
956 }
957
958 private function markAsSkippedIfSymlinkIsMissing()
959 {
960 if (!function_exists('symlink')) {
961 $this->markTestSkipped('symlink is not supported');
962 }
963
964 if (defined('PHP_WINDOWS_VERSION_MAJOR') && false === self::$symlinkOnWindows) {
965 $this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows');
966 }
967 }
968
969 private function markAsSkippedIfChmodIsMissing()
970 {
971 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
972 $this->markTestSkipped('chmod is not supported on windows');
973 }
974 }
975
976 private function markAsSkippedIfPosixIsMissing()
977 {
978 if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('posix_isatty')) {
979 $this->markTestSkipped('Posix is not supported');
980 }
981 }
982}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json b/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json
new file mode 100644
index 00000000..167dd506
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json
@@ -0,0 +1,31 @@
1{
2 "name": "symfony/filesystem",
3 "type": "library",
4 "description": "Symfony Filesystem Component",
5 "keywords": [],
6 "homepage": "http://symfony.com",
7 "license": "MIT",
8 "authors": [
9 {
10 "name": "Fabien Potencier",
11 "email": "fabien@symfony.com"
12 },
13 {
14 "name": "Symfony Community",
15 "homepage": "http://symfony.com/contributors"
16 }
17 ],
18 "require": {
19 "php": ">=5.3.3"
20 },
21 "autoload": {
22 "psr-0": { "Symfony\\Component\\Filesystem\\": "" }
23 },
24 "target-dir": "Symfony/Component/Filesystem",
25 "minimum-stability": "dev",
26 "extra": {
27 "branch-alias": {
28 "dev-master": "2.3-dev"
29 }
30 }
31}
diff --git a/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist b/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist
new file mode 100644
index 00000000..ef0bf954
--- /dev/null
+++ b/vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist
@@ -0,0 +1,28 @@
1<?xml version="1.0" encoding="UTF-8"?>
2
3<phpunit backupGlobals="false"
4 backupStaticAttributes="false"
5 colors="true"
6 convertErrorsToExceptions="true"
7 convertNoticesToExceptions="true"
8 convertWarningsToExceptions="true"
9 processIsolation="false"
10 stopOnFailure="false"
11 syntaxCheck="false"
12 bootstrap="vendor/autoload.php"
13>
14 <testsuites>
15 <testsuite name="Symfony Filesystem Component Test Suite">
16 <directory>./Tests/</directory>
17 </testsuite>
18 </testsuites>
19
20 <filter>
21 <whitelist>
22 <directory>./</directory>
23 <exclude>
24 <directory>./Tests</directory>
25 </exclude>
26 </whitelist>
27 </filter>
28</phpunit>