From 4f5b44bd3bd490309eb2ba7b44df4769816ba729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Sat, 3 Aug 2013 19:26:54 +0200 Subject: twig implementation --- .../Symfony/Component/Filesystem/.gitignore | 4 + .../Symfony/Component/Filesystem/CHANGELOG.md | 18 + .../Filesystem/Exception/ExceptionInterface.php | 24 + .../Component/Filesystem/Exception/IOException.php | 24 + .../Symfony/Component/Filesystem/Filesystem.php | 471 ++++++++++ .../Symfony/Component/Filesystem/LICENSE | 19 + .../Symfony/Component/Filesystem/README.md | 45 + .../Component/Filesystem/Tests/FilesystemTest.php | 982 +++++++++++++++++++++ .../Symfony/Component/Filesystem/composer.json | 31 + .../Symfony/Component/Filesystem/phpunit.xml.dist | 28 + 10 files changed, 1646 insertions(+) create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/.gitignore create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/CHANGELOG.md create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Exception/IOException.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Filesystem.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/LICENSE create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/README.md create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/Tests/FilesystemTest.php create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/composer.json create mode 100644 vendor/symfony/filesystem/Symfony/Component/Filesystem/phpunit.xml.dist (limited to 'vendor/symfony/filesystem') 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 @@ +vendor/ +composer.lock +phpunit.xml + 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 @@ +CHANGELOG +========= + +2.3.0 +----- + + * added the dumpFile() method to atomically write files + +2.2.0 +----- + + * added a delete option for the mirror() method + +2.1.0 +----- + + * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value + * 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Romain Neutron + * + * @api + */ +interface ExceptionInterface +{ + +} 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception class thrown when a filesystem operation failure happens + * + * @author Romain Neutron + * + * @api + */ +class IOException extends \RuntimeException implements ExceptionInterface +{ + +} 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem; + +use Symfony\Component\Filesystem\Exception\IOException; + +/** + * Provides basic utility to manipulate the file system. + * + * @author Fabien Potencier + */ +class Filesystem +{ + /** + * Copies a file. + * + * This method only copies the file if the origin file is newer than the target file. + * + * By default, if the target already exists, it is not overridden. + * + * @param string $originFile The original filename + * @param string $targetFile The target filename + * @param boolean $override Whether to override an existing file or not + * + * @throws IOException When copy fails + */ + public function copy($originFile, $targetFile, $override = false) + { + if (stream_is_local($originFile) && !is_file($originFile)) { + throw new IOException(sprintf('Failed to copy %s because file not exists', $originFile)); + } + + $this->mkdir(dirname($targetFile)); + + if (!$override && is_file($targetFile)) { + $doCopy = filemtime($originFile) > filemtime($targetFile); + } else { + $doCopy = true; + } + + if ($doCopy) { + // https://bugs.php.net/bug.php?id=64634 + $source = fopen($originFile, 'r'); + $target = fopen($targetFile, 'w+'); + stream_copy_to_stream($source, $target); + fclose($source); + fclose($target); + unset($source, $target); + + if (!is_file($targetFile)) { + throw new IOException(sprintf('Failed to copy %s to %s', $originFile, $targetFile)); + } + } + } + + /** + * Creates a directory recursively. + * + * @param string|array|\Traversable $dirs The directory path + * @param integer $mode The directory mode + * + * @throws IOException On any directory creation failure + */ + public function mkdir($dirs, $mode = 0777) + { + foreach ($this->toIterator($dirs) as $dir) { + if (is_dir($dir)) { + continue; + } + + if (true !== @mkdir($dir, $mode, true)) { + throw new IOException(sprintf('Failed to create %s', $dir)); + } + } + } + + /** + * Checks the existence of files or directories. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to check + * + * @return Boolean true if the file exists, false otherwise + */ + public function exists($files) + { + foreach ($this->toIterator($files) as $file) { + if (!file_exists($file)) { + return false; + } + } + + return true; + } + + /** + * Sets access and modification time of file. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to create + * @param integer $time The touch time as a unix timestamp + * @param integer $atime The access time as a unix timestamp + * + * @throws IOException When touch fails + */ + public function touch($files, $time = null, $atime = null) + { + foreach ($this->toIterator($files) as $file) { + $touch = $time ? @touch($file, $time, $atime) : @touch($file); + if (true !== $touch) { + throw new IOException(sprintf('Failed to touch %s', $file)); + } + } + } + + /** + * Removes files or directories. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove + * + * @throws IOException When removal fails + */ + public function remove($files) + { + $files = iterator_to_array($this->toIterator($files)); + $files = array_reverse($files); + foreach ($files as $file) { + if (!file_exists($file) && !is_link($file)) { + continue; + } + + if (is_dir($file) && !is_link($file)) { + $this->remove(new \FilesystemIterator($file)); + + if (true !== @rmdir($file)) { + throw new IOException(sprintf('Failed to remove directory %s', $file)); + } + } else { + // https://bugs.php.net/bug.php?id=52176 + if (defined('PHP_WINDOWS_VERSION_MAJOR') && is_dir($file)) { + if (true !== @rmdir($file)) { + throw new IOException(sprintf('Failed to remove file %s', $file)); + } + } else { + if (true !== @unlink($file)) { + throw new IOException(sprintf('Failed to remove file %s', $file)); + } + } + } + } + } + + /** + * Change mode for an array of files or directories. + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change mode + * @param integer $mode The new mode (octal) + * @param integer $umask The mode mask (octal) + * @param Boolean $recursive Whether change the mod recursively or not + * + * @throws IOException When the change fail + */ + public function chmod($files, $mode, $umask = 0000, $recursive = false) + { + foreach ($this->toIterator($files) as $file) { + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chmod(new \FilesystemIterator($file), $mode, $umask, true); + } + if (true !== @chmod($file, $mode & ~$umask)) { + throw new IOException(sprintf('Failed to chmod file %s', $file)); + } + } + } + + /** + * Change the owner of an array of files or directories + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change owner + * @param string $user The new owner user name + * @param Boolean $recursive Whether change the owner recursively or not + * + * @throws IOException When the change fail + */ + public function chown($files, $user, $recursive = false) + { + foreach ($this->toIterator($files) as $file) { + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chown(new \FilesystemIterator($file), $user, true); + } + if (is_link($file) && function_exists('lchown')) { + if (true !== @lchown($file, $user)) { + throw new IOException(sprintf('Failed to chown file %s', $file)); + } + } else { + if (true !== @chown($file, $user)) { + throw new IOException(sprintf('Failed to chown file %s', $file)); + } + } + } + } + + /** + * Change the group of an array of files or directories + * + * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to change group + * @param string $group The group name + * @param Boolean $recursive Whether change the group recursively or not + * + * @throws IOException When the change fail + */ + public function chgrp($files, $group, $recursive = false) + { + foreach ($this->toIterator($files) as $file) { + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chgrp(new \FilesystemIterator($file), $group, true); + } + if (is_link($file) && function_exists('lchgrp')) { + if (true !== @lchgrp($file, $group)) { + throw new IOException(sprintf('Failed to chgrp file %s', $file)); + } + } else { + if (true !== @chgrp($file, $group)) { + throw new IOException(sprintf('Failed to chgrp file %s', $file)); + } + } + } + } + + /** + * Renames a file or a directory. + * + * @param string $origin The origin filename or directory + * @param string $target The new filename or directory + * @param Boolean $overwrite Whether to overwrite the target if it already exists + * + * @throws IOException When target file or directory already exists + * @throws IOException When origin cannot be renamed + */ + public function rename($origin, $target, $overwrite = false) + { + // we check that target does not exist + if (!$overwrite && is_readable($target)) { + throw new IOException(sprintf('Cannot rename because the target "%s" already exist.', $target)); + } + + if (true !== @rename($origin, $target)) { + throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target)); + } + } + + /** + * Creates a symbolic link or copy a directory. + * + * @param string $originDir The origin directory path + * @param string $targetDir The symbolic link name + * @param Boolean $copyOnWindows Whether to copy files if on Windows + * + * @throws IOException When symlink fails + */ + public function symlink($originDir, $targetDir, $copyOnWindows = false) + { + if (!function_exists('symlink') && $copyOnWindows) { + $this->mirror($originDir, $targetDir); + + return; + } + + $this->mkdir(dirname($targetDir)); + + $ok = false; + if (is_link($targetDir)) { + if (readlink($targetDir) != $originDir) { + $this->remove($targetDir); + } else { + $ok = true; + } + } + + if (!$ok) { + if (true !== @symlink($originDir, $targetDir)) { + $report = error_get_last(); + if (is_array($report)) { + if (defined('PHP_WINDOWS_VERSION_MAJOR') && false !== strpos($report['message'], 'error code(1314)')) { + 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?'); + } + } + throw new IOException(sprintf('Failed to create symbolic link from %s to %s', $originDir, $targetDir)); + } + } + } + + /** + * Given an existing path, convert it to a path relative to a given starting path + * + * @param string $endPath Absolute path of target + * @param string $startPath Absolute path where traversal begins + * + * @return string Path of target relative to starting path + */ + public function makePathRelative($endPath, $startPath) + { + // Normalize separators on windows + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $endPath = strtr($endPath, '\\', '/'); + $startPath = strtr($startPath, '\\', '/'); + } + + // Split the paths into arrays + $startPathArr = explode('/', trim($startPath, '/')); + $endPathArr = explode('/', trim($endPath, '/')); + + // Find for which directory the common path stops + $index = 0; + while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) { + $index++; + } + + // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels) + $depth = count($startPathArr) - $index; + + // Repeated "../" for each level need to reach the common path + $traverser = str_repeat('../', $depth); + + $endPathRemainder = implode('/', array_slice($endPathArr, $index)); + + // Construct $endPath from traversing to the common path, then to the remaining $endPath + $relativePath = $traverser.(strlen($endPathRemainder) > 0 ? $endPathRemainder.'/' : ''); + + return (strlen($relativePath) === 0) ? './' : $relativePath; + } + + /** + * Mirrors a directory to another. + * + * @param string $originDir The origin directory + * @param string $targetDir The target directory + * @param \Traversable $iterator A Traversable instance + * @param array $options An array of boolean options + * Valid options are: + * - $options['override'] Whether to override an existing file on copy or not (see copy()) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink()) + * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) + * + * @throws IOException When file type is unknown + */ + public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array()) + { + $targetDir = rtrim($targetDir, '/\\'); + $originDir = rtrim($originDir, '/\\'); + + // Iterate in destination folder to remove obsolete entries + if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) { + $deleteIterator = $iterator; + if (null === $deleteIterator) { + $flags = \FilesystemIterator::SKIP_DOTS; + $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST); + } + foreach ($deleteIterator as $file) { + $origin = str_replace($targetDir, $originDir, $file->getPathname()); + if (!$this->exists($origin)) { + $this->remove($file); + } + } + } + + $copyOnWindows = false; + if (isset($options['copy_on_windows']) && !function_exists('symlink')) { + $copyOnWindows = $options['copy_on_windows']; + } + + if (null === $iterator) { + $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS; + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST); + } + + foreach ($iterator as $file) { + $target = str_replace($originDir, $targetDir, $file->getPathname()); + + if ($copyOnWindows) { + if (is_link($file) || is_file($file)) { + $this->copy($file, $target, isset($options['override']) ? $options['override'] : false); + } elseif (is_dir($file)) { + $this->mkdir($target); + } else { + throw new IOException(sprintf('Unable to guess "%s" file type.', $file)); + } + } else { + if (is_link($file)) { + $this->symlink($file, $target); + } elseif (is_dir($file)) { + $this->mkdir($target); + } elseif (is_file($file)) { + $this->copy($file, $target, isset($options['override']) ? $options['override'] : false); + } else { + throw new IOException(sprintf('Unable to guess "%s" file type.', $file)); + } + } + } + } + + /** + * Returns whether the file path is an absolute path. + * + * @param string $file A file path + * + * @return Boolean + */ + public function isAbsolutePath($file) + { + if (strspn($file, '/\\', 0, 1) + || (strlen($file) > 3 && ctype_alpha($file[0]) + && substr($file, 1, 1) === ':' + && (strspn($file, '/\\', 2, 1)) + ) + || null !== parse_url($file, PHP_URL_SCHEME) + ) { + return true; + } + + return false; + } + + /** + * @param mixed $files + * + * @return \Traversable + */ + private function toIterator($files) + { + if (!$files instanceof \Traversable) { + $files = new \ArrayObject(is_array($files) ? $files : array($files)); + } + + return $files; + } + + /** + * Atomically dumps content into a file. + * + * @param string $filename The file to be written to. + * @param string $content The data to write into the file. + * @param integer $mode The file mode (octal). + * @throws IOException If the file cannot be written to. + */ + public function dumpFile($filename, $content, $mode = 0666) + { + $dir = dirname($filename); + + if (!is_dir($dir)) { + $this->mkdir($dir); + } elseif (!is_writable($dir)) { + throw new IOException(sprintf('Unable to write in the %s directory\n', $dir)); + } + + $tmpFile = tempnam($dir, basename($filename)); + + if (false === @file_put_contents($tmpFile, $content)) { + throw new IOException(sprintf('Failed to write file "%s".', $filename)); + } + + $this->rename($tmpFile, $filename, true); + $this->chmod($filename, $mode); + } +} 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 @@ +Copyright (c) 2004-2013 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE 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 @@ +Filesystem Component +==================== + +Filesystem provides basic utility to manipulate the file system: + +```php +copy($originFile, $targetFile, $override = false); + +$filesystem->mkdir($dirs, $mode = 0777); + +$filesystem->touch($files, $time = null, $atime = null); + +$filesystem->remove($files); + +$filesystem->chmod($files, $mode, $umask = 0000, $recursive = false); + +$filesystem->chown($files, $user, $recursive = false); + +$filesystem->chgrp($files, $group, $recursive = false); + +$filesystem->rename($origin, $target); + +$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false); + +$filesystem->makePathRelative($endPath, $startPath); + +$filesystem->mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array()); + +$filesystem->isAbsolutePath($file); +``` + +Resources +--------- + +You can run the unit tests with the following command: + + $ cd path/to/Symfony/Component/Filesystem/ + $ composer.phar install --dev + $ 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 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use Symfony\Component\Filesystem\Filesystem; + +/** + * Test class for Filesystem. + */ +class FilesystemTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var string $workspace + */ + private $workspace = null; + + /** + * @var \Symfony\Component\Filesystem\Filesystem $filesystem + */ + private $filesystem = null; + + private static $symlinkOnWindows = null; + + public static function setUpBeforeClass() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + self::$symlinkOnWindows = true; + $originDir = tempnam(sys_get_temp_dir(), 'sl'); + $targetDir = tempnam(sys_get_temp_dir(), 'sl'); + if (true !== @symlink($originDir, $targetDir)) { + $report = error_get_last(); + if (is_array($report) && false !== strpos($report['message'], 'error code(1314)')) { + self::$symlinkOnWindows = false; + } + } + } + } + + public function setUp() + { + $this->filesystem = new Filesystem(); + $this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000); + mkdir($this->workspace, 0777, true); + $this->workspace = realpath($this->workspace); + } + + public function tearDown() + { + $this->clean($this->workspace); + } + + /** + * @param string $file + */ + private function clean($file) + { + if (is_dir($file) && !is_link($file)) { + $dir = new \FilesystemIterator($file); + foreach ($dir as $childFile) { + $this->clean($childFile); + } + + rmdir($file); + } else { + unlink($file); + } + } + + public function testCopyCreatesNewFile() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testCopyFails() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + } + + public function testCopyOverridesExistingFileIfModified() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + touch($targetFilePath, time() - 1000); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + public function testCopyDoesNotOverrideExistingFileByDefault() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('TARGET FILE', file_get_contents($targetFilePath)); + } + + public function testCopyOverridesExistingFileIfForced() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, true); + + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + public function testCopyCreatesTargetDirectoryIfItDoesNotExist() + { + $sourceFilePath = $this->workspace.DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFileDirectory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $targetFilePath = $targetFileDirectory.DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertTrue(is_dir($targetFileDirectory)); + $this->assertFileExists($targetFilePath); + $this->assertEquals('SOURCE FILE', file_get_contents($targetFilePath)); + } + + public function testMkdirCreatesDirectoriesRecursively() + { + $directory = $this->workspace + .DIRECTORY_SEPARATOR.'directory' + .DIRECTORY_SEPARATOR.'sub_directory'; + + $this->filesystem->mkdir($directory); + + $this->assertTrue(is_dir($directory)); + } + + public function testMkdirCreatesDirectoriesFromArray() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $directories = array( + $basePath.'1', $basePath.'2', $basePath.'3' + ); + + $this->filesystem->mkdir($directories); + + $this->assertTrue(is_dir($basePath.'1')); + $this->assertTrue(is_dir($basePath.'2')); + $this->assertTrue(is_dir($basePath.'3')); + } + + public function testMkdirCreatesDirectoriesFromTraversableObject() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $directories = new \ArrayObject(array( + $basePath.'1', $basePath.'2', $basePath.'3' + )); + + $this->filesystem->mkdir($directories); + + $this->assertTrue(is_dir($basePath.'1')); + $this->assertTrue(is_dir($basePath.'2')); + $this->assertTrue(is_dir($basePath.'3')); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testMkdirCreatesDirectoriesFails() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $dir = $basePath.'2'; + + file_put_contents($dir, ''); + + $this->filesystem->mkdir($dir); + } + + public function testTouchCreatesEmptyFile() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'1'; + + $this->filesystem->touch($file); + + $this->assertFileExists($file); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testTouchFails() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'1'.DIRECTORY_SEPARATOR.'2'; + + $this->filesystem->touch($file); + } + + public function testTouchCreatesEmptyFilesFromArray() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $files = array( + $basePath.'1', $basePath.'2', $basePath.'3' + ); + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testTouchCreatesEmptyFilesFromTraversableObject() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + $files = new \ArrayObject(array( + $basePath.'1', $basePath.'2', $basePath.'3' + )); + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testRemoveCleansFilesAndDirectoriesIteratively() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $this->filesystem->remove($basePath); + + $this->assertTrue(!is_dir($basePath)); + } + + public function testRemoveCleansArrayOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = array( + $basePath.'dir', $basePath.'file' + ); + + $this->filesystem->remove($files); + + $this->assertTrue(!is_dir($basePath.'dir')); + $this->assertTrue(!is_file($basePath.'file')); + } + + public function testRemoveCleansTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file' + )); + + $this->filesystem->remove($files); + + $this->assertTrue(!is_dir($basePath.'dir')); + $this->assertTrue(!is_file($basePath.'file')); + } + + public function testRemoveIgnoresNonExistingFiles() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + + $files = array( + $basePath.'dir', $basePath.'file' + ); + + $this->filesystem->remove($files); + + $this->assertTrue(!is_dir($basePath.'dir')); + } + + public function testRemoveCleansInvalidLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + // create symlink to unexisting file + @symlink($basePath.'file', $basePath.'link'); + + $this->filesystem->remove($basePath); + + $this->assertTrue(!is_dir($basePath)); + } + + public function testFilesExists() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + mkdir($basePath); + touch($basePath.'file1'); + mkdir($basePath.'folder'); + + $this->assertTrue($this->filesystem->exists($basePath.'file1')); + $this->assertTrue($this->filesystem->exists($basePath.'folder')); + } + + public function testFilesExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file' + )); + + $this->assertTrue($this->filesystem->exists($files)); + } + + public function testFilesNotExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + touch($basePath.'file2'); + + $files = new \ArrayObject(array( + $basePath.'dir', $basePath.'file', $basePath.'file2' + )); + + unlink($basePath.'file'); + + $this->assertFalse($this->filesystem->exists($files)); + } + + public function testInvalidFileNotExists() + { + $basePath = $this->workspace.DIRECTORY_SEPARATOR.'directory'.DIRECTORY_SEPARATOR; + + $this->assertFalse($this->filesystem->exists($basePath.time())); + } + + public function testChmodChangesFileMode() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400); + $this->filesystem->chmod($dir, 0753); + + $this->assertEquals(753, $this->getFilePermissions($dir)); + $this->assertEquals(400, $this->getFilePermissions($file)); + } + + public function testChmodWrongMod() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'file'; + touch($dir); + + $this->filesystem->chmod($dir, 'Wrongmode'); + } + + public function testChmodRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400, 0000, true); + $this->filesystem->chmod($dir, 0753, 0000, true); + + $this->assertEquals(753, $this->getFilePermissions($dir)); + $this->assertEquals(753, $this->getFilePermissions($file)); + } + + public function testChmodAppliesUmask() + { + $this->markAsSkippedIfChmodIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0770, 0022); + $this->assertEquals(750, $this->getFilePermissions($file)); + } + + public function testChmodChangesModeOfArrayOfFiles() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $files = array($directory, $file); + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertEquals(753, $this->getFilePermissions($file)); + $this->assertEquals(753, $this->getFilePermissions($directory)); + } + + public function testChmodChangesModeOfTraversableFileObject() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $files = new \ArrayObject(array($directory, $file)); + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertEquals(753, $this->getFilePermissions($file)); + $this->assertEquals(753, $this->getFilePermissions($directory)); + } + + public function testChown() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chown($dir, $this->getFileOwner($dir)); + } + + public function testChownRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chown($dir, $this->getFileOwner($dir), true); + } + + public function testChownSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chown($link, $this->getFileOwner($link)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChownSymlinkFails() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChownFail() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChgrp() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chgrp($dir, $this->getFileGroup($dir)); + } + + public function testChgrpRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chgrp($dir, $this->getFileGroup($dir), true); + } + + public function testChgrpSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chgrp($link, $this->getFileGroup($link)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChgrpSymlinkFails() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999)); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testChgrpFail() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testRename() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + touch($file); + + $this->filesystem->rename($file, $newPath); + + $this->assertFileNotExists($file); + $this->assertFileExists($newPath); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testRenameThrowsExceptionIfTargetAlreadyExists() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath); + } + + public function testRenameOverwritesTheTargetIfItAlreadyExists() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath, true); + + $this->assertFileNotExists($file); + $this->assertFileExists($newPath); + } + + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ + public function testRenameThrowsExceptionOnError() + { + $file = $this->workspace.DIRECTORY_SEPARATOR.uniqid(); + $newPath = $this->workspace.DIRECTORY_SEPARATOR.'new_file'; + + $this->filesystem->rename($file, $newPath); + } + + public function testSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + /** + * @depends testSymlink + */ + public function testRemoveSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + $this->filesystem->remove($link); + + $this->assertTrue(!is_link($link)); + } + + public function testSymlinkIsOverwrittenIfPointsToDifferentTarget() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($this->workspace, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkIsNotOverwrittenIfAlreadyCreated() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($file, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.DIRECTORY_SEPARATOR.'file'; + $link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link'; + $link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link1); + $this->filesystem->symlink($file, $link2); + + $this->assertTrue(is_link($link1)); + $this->assertEquals($file, readlink($link1)); + $this->assertTrue(is_link($link2)); + $this->assertEquals($file, readlink($link2)); + } + + /** + * @dataProvider providePathsForMakePathRelative + */ + public function testMakePathRelative($endPath, $startPath, $expectedPath) + { + $path = $this->filesystem->makePathRelative($endPath, $startPath); + + $this->assertEquals($expectedPath, $path); + } + + /** + * @return array + */ + public function providePathsForMakePathRelative() + { + $paths = array( + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'), + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'), + array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'), + array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'), + array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'), + array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'), + array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'), + array('/aa/bb', '/aa/bb', './'), + array('/aa/bb', '/aa/bb/', './'), + array('/aa/bb/', '/aa/bb', './'), + array('/aa/bb/', '/aa/bb/', './'), + array('/aa/bb/cc', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd', '../'), + array('/aa/bb/cc/', '/aa/bb/cc/dd/', '../'), + array('/aa/bb/cc', '/aa', 'bb/cc/'), + array('/aa/bb/cc', '/aa/', 'bb/cc/'), + array('/aa/bb/cc/', '/aa', 'bb/cc/'), + array('/aa/bb/cc/', '/aa/', 'bb/cc/'), + array('/a/aab/bb', '/a/aa', '../aab/bb/'), + array('/a/aab/bb', '/a/aa/', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa', '../aab/bb/'), + array('/a/aab/bb/', '/a/aa/', '../aab/bb/'), + ); + + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/'); + } + + return $paths; + } + + public function testMirrorCopiesFilesAndDirectoriesRecursively() + { + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + $directory = $sourcePath.'directory'.DIRECTORY_SEPARATOR; + $file1 = $directory.'file1'; + $file2 = $sourcePath.'file2'; + + mkdir($sourcePath); + mkdir($directory); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertTrue(is_dir($targetPath.'directory')); + $this->assertFileEquals($file1, $targetPath.'directory'.DIRECTORY_SEPARATOR.'file1'); + $this->assertFileEquals($file2, $targetPath.'file2'); + + $this->filesystem->remove($file1); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => false)); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + file_put_contents($file1, 'FILE1'); + + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->remove($directory); + $this->filesystem->mirror($sourcePath, $targetPath, null, array('delete' => true)); + $this->assertFalse($this->filesystem->exists($targetPath.'directory')); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.DIRECTORY_SEPARATOR.'file1')); + } + + public function testMirrorCopiesLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + file_put_contents($sourcePath.'file1', 'FILE1'); + symlink($sourcePath.'file1', $sourcePath.'link1'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'file1', $targetPath.DIRECTORY_SEPARATOR.'link1'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorCopiesLinkedDirectoryContents() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $sourcePath = $this->workspace.DIRECTORY_SEPARATOR.'source'.DIRECTORY_SEPARATOR; + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: We symlink directory, not file + symlink($sourcePath.'nested', $sourcePath.'link1'); + + $targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertTrue(is_dir($targetPath)); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.DIRECTORY_SEPARATOR.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.DIRECTORY_SEPARATOR.'link1')); + } + + /** + * @dataProvider providePathsForIsAbsolutePath + */ + public function testIsAbsolutePath($path, $expectedResult) + { + $result = $this->filesystem->isAbsolutePath($path); + + $this->assertEquals($expectedResult, $result); + } + + /** + * @return array + */ + public function providePathsForIsAbsolutePath() + { + return array( + array('/var/lib', true), + array('c:\\\\var\\lib', true), + array('\\var\\lib', true), + array('var/lib', false), + array('../var/lib', false), + array('', false), + array(null, false) + ); + } + + public function testDumpFile() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar', 0753); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + + // skip mode check on windows + if (!defined('PHP_WINDOWS_VERSION_MAJOR')) { + $this->assertEquals(753, $this->getFilePermissions($filename)); + } + } + + public function testDumpFileOverwritesAnExistingFile() + { + $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt'; + file_put_contents($filename, 'FOO BAR'); + + $this->filesystem->dumpFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertSame('bar', file_get_contents($filename)); + } + + /** + * Returns file permissions as three digits (i.e. 755) + * + * @param string $filePath + * + * @return integer + */ + private function getFilePermissions($filePath) + { + return (int) substr(sprintf('%o', fileperms($filePath)), -3); + } + + private function getFileOwner($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + if ($datas = posix_getpwuid($infos['uid'])) { + return $datas['name']; + } + } + + private function getFileGroup($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + if ($datas = posix_getgrgid($infos['gid'])) { + return $datas['name']; + } + } + + private function markAsSkippedIfSymlinkIsMissing() + { + if (!function_exists('symlink')) { + $this->markTestSkipped('symlink is not supported'); + } + + if (defined('PHP_WINDOWS_VERSION_MAJOR') && false === self::$symlinkOnWindows) { + $this->markTestSkipped('symlink requires "Create symbolic links" privilege on windows'); + } + } + + private function markAsSkippedIfChmodIsMissing() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $this->markTestSkipped('chmod is not supported on windows'); + } + } + + private function markAsSkippedIfPosixIsMissing() + { + if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('posix_isatty')) { + $this->markTestSkipped('Posix is not supported'); + } + } +} 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 @@ +{ + "name": "symfony/filesystem", + "type": "library", + "description": "Symfony Filesystem Component", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Filesystem\\": "" } + }, + "target-dir": "Symfony/Component/Filesystem", + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + } +} 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 @@ + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + + + + -- cgit v1.2.3