From abb926a60c55573205ed33d0c0b2a5dc37d7b06d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 3 Dec 2011 23:20:06 +0100 Subject: [PATCH 1/7] Add tests for autoloader --- .../Test/Autoload/AutoloadGeneratorTest.php | 120 ++++++++++++++++++ .../Test/Autoload/Fixtures/autoload_main.php | 10 ++ .../Test/Autoload/Fixtures/autoload_main2.php | 10 ++ .../Autoload/Fixtures/autoload_vendors.php | 11 ++ 4 files changed, 151 insertions(+) create mode 100644 tests/Composer/Test/Autoload/AutoloadGeneratorTest.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_main.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_main2.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_vendors.php diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php new file mode 100644 index 000000000..f7b327092 --- /dev/null +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -0,0 +1,120 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Installer; + +use Composer\Autoload\AutoloadGenerator; +use Composer\Downloader\Util\Filesystem; +use Composer\Package\MemoryPackage; + +class AutoloadGeneratorTest extends \PHPUnit_Framework_TestCase +{ + public $vendorDir; + private $workingDir; + private $im; + private $repository; + private $generator; + + protected function setUp() + { + $fs = new Filesystem; + $that = $this; + + $this->workingDir = sys_get_temp_dir(); + $this->vendorDir = $this->workingDir.DIRECTORY_SEPARATOR.'composer-test-autoload'; + if (is_dir($this->vendorDir)) { + $fs->removeDirectory($this->vendorDir); + } + mkdir($this->vendorDir); + + $this->dir = getcwd(); + chdir($this->workingDir); + + $this->im = $this->getMockBuilder('Composer\Installer\InstallationManager') + ->disableOriginalConstructor() + ->getMock(); + $this->im->expects($this->any()) + ->method('getInstallPath') + ->will($this->returnCallback(function ($package) use ($that) { + return $that->vendorDir.'/'.$package->getName(); + })); + $this->im->expects($this->any()) + ->method('getVendorPath') + ->will($this->returnCallback(function () use ($that) { + return $that->vendorDir; + })); + + $this->repo = $this->getMockBuilder('Composer\Repository\RepositoryInterface') + ->disableOriginalConstructor() + ->getMock(); + + $this->generator = new AutoloadGenerator(); + } + + protected function tearDown() + { + chdir($this->dir); + } + + public function testMainPackageAutoloading() + { + $package = new MemoryPackage('a', '1.0', '1.0'); + $package->setAutoload(array('psr-0' => array('Main' => 'src/', 'Lala' => 'src/'))); + + $this->repo->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue(array())); + + mkdir($this->vendorDir.'/.composer'); + $this->generator->dump($this->repo, $package, $this->im, $this->vendorDir.'/.composer'); + $this->assertAutoloadFiles('main', $this->vendorDir.'/.composer'); + } + + public function testMainPackageAutoloadingAlternativeVendorDir() + { + $package = new MemoryPackage('a', '1.0', '1.0'); + $package->setAutoload(array('psr-0' => array('Main' => 'src/', 'Lala' => 'src/'))); + + $this->repo->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue(array())); + + $this->vendorDir .= '/subdir'; + mkdir($this->vendorDir.'/.composer', 0777, true); + $this->generator->dump($this->repo, $package, $this->im, $this->vendorDir.'/.composer'); + $this->assertAutoloadFiles('main2', $this->vendorDir.'/.composer'); + } + + public function testVendorsAutoloading() + { + $package = new MemoryPackage('a', '1.0', '1.0'); + + $packages = array(); + $packages[] = $a = new MemoryPackage('a/a', '1.0', '1.0'); + $packages[] = $b = new MemoryPackage('b/b', '1.0', '1.0'); + $a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/'))); + $b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/'))); + + $this->repo->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue($packages)); + + mkdir($this->vendorDir.'/.composer', 0777, true); + $this->generator->dump($this->repo, $package, $this->im, $this->vendorDir.'/.composer'); + $this->assertAutoloadFiles('vendors', $this->vendorDir.'/.composer'); + } + + private function assertAutoloadFiles($name, $dir) + { + $this->assertEquals(file_get_contents(__DIR__.'/Fixtures/autoload_'.$name.'.php'), file_get_contents($dir.'/autoload_namespaces.php')); + } +} diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_main.php b/tests/Composer/Test/Autoload/Fixtures/autoload_main.php new file mode 100644 index 000000000..157d888f3 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_main.php @@ -0,0 +1,10 @@ + dirname($vendorDir) . '/src/', + 'Lala' => dirname($vendorDir) . '/src/', +); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_main2.php b/tests/Composer/Test/Autoload/Fixtures/autoload_main2.php new file mode 100644 index 000000000..a0fa2c7db --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_main2.php @@ -0,0 +1,10 @@ + dirname(dirname($vendorDir)) . '/src/', + 'Lala' => dirname(dirname($vendorDir)) . '/src/', +); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_vendors.php b/tests/Composer/Test/Autoload/Fixtures/autoload_vendors.php new file mode 100644 index 000000000..b149046df --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_vendors.php @@ -0,0 +1,11 @@ + $vendorDir . '/b/b/src/', + 'A\\B' => $vendorDir . '/a/a/lib/', + 'A' => $vendorDir . '/a/a/src/', +); From bc88d86983665850303aa2b5d4c7568bb63befa1 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 3 Dec 2011 23:20:36 +0100 Subject: [PATCH 2/7] Make use of Filesystem class in AutoloadGenerator --- src/Composer/Autoload/AutoloadGenerator.php | 38 ++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 8627552bb..9c6665ab6 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -17,6 +17,7 @@ use Composer\Json\JsonFile; use Composer\Package\Loader\JsonLoader; use Composer\Package\PackageInterface; use Composer\Repository\RepositoryInterface; +use Composer\Downloader\Util\Filesystem; /** * @author Igor Wiedler @@ -27,7 +28,6 @@ class AutoloadGenerator public function dump(RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir) { $autoloadFile = file_get_contents(__DIR__.'/ClassLoader.php'); - $autoloadFile .= <<<'EOF' // autoload.php generated by Composer @@ -49,12 +49,17 @@ function init() { return init(); EOF; - $namespacesFile = <<<'EOF' + $filesystem = new Filesystem(); + $vendorPath = strtr(realpath($installationManager->getVendorPath()), '\\', '/'); + $relVendorPath = ltrim(substr($vendorPath, strlen(getcwd())), '/'); + $vendorDirCode = $filesystem->findShortestPathCode($targetDir, $vendorPath, true); + + $namespacesFile = <<parseAutoloads($packageMap); - $vendorPath = $installationManager->getVendorPath(); - $realVendorPath = realpath($vendorPath); - $vendorPathDepth = substr_count(strtr(substr($realVendorPath, strlen(getcwd())), '\\', '/'), '/'); - $appBaseDir = str_repeat('dirname(', $vendorPathDepth).'$baseDir'.str_repeat(')', $vendorPathDepth); + $appBaseDir = $filesystem->findShortestPathCode($vendorPath, getcwd(), true); + $appBaseDir = str_replace('__DIR__', '$vendorDir', $appBaseDir); if (isset($autoloads['psr-0'])) { foreach ($autoloads['psr-0'] as $def) { - if (!$this->isAbsolutePath($def['path'])) { - if (strpos($def['path'], $vendorPath) === 0) { - $def['path'] = substr($def['path'], strlen($vendorPath)); - $baseDir = '$baseDir . '; + $def['path'] = strtr($def['path'], '\\', '/'); + $baseDir = ''; + if (!$filesystem->isAbsolutePath($def['path'])) { + if (strpos($def['path'], $relVendorPath) === 0) { + $def['path'] = substr($def['path'], strlen($relVendorPath)); + $baseDir = '$vendorDir . '; } else { $def['path'] = '/'.$def['path']; $baseDir = $appBaseDir . ' . '; } - } else { - $baseDir = ''; + } elseif (strpos($def['path'], $vendorPath) === 0) { + $def['path'] = substr($def['path'], strlen($vendorPath)); + $baseDir = '$vendorDir . '; } $exportedPrefix = var_export($def['namespace'], true); $exportedPath = var_export($def['path'], true); @@ -158,9 +163,4 @@ EOF; return $loader; } - - protected function isAbsolutePath($path) - { - return substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':'; - } } From 4517a2e51eb2b8c59fe33f626adf592894e4f5cf Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 3 Dec 2011 23:21:10 +0100 Subject: [PATCH 3/7] Added tests and fixed some incorrect behaviors in Filesystem --- src/Composer/Downloader/Util/Filesystem.php | 22 +++++++++--- .../Test/Downloader/Util/FilesystemTest.php | 35 +++++++++++++------ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/Composer/Downloader/Util/Filesystem.php b/src/Composer/Downloader/Util/Filesystem.php index 66e423e1d..bd8a346af 100644 --- a/src/Composer/Downloader/Util/Filesystem.php +++ b/src/Composer/Downloader/Util/Filesystem.php @@ -58,8 +58,8 @@ class Filesystem if (dirname($from) === dirname($to)) { return './'.basename($to); } - $from = strtr($from, '\\', '/'); - $to = strtr($to, '\\', '/'); + $from = rtrim(strtr($from, '\\', '/'), '/'); + $to = rtrim(strtr($to, '\\', '/'), '/'); $commonPath = dirname($to); while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/$}i', $commonPath)) { @@ -70,6 +70,10 @@ class Filesystem return $to; } + if (strpos($from, $to) === 0) { + $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/'); + return str_repeat('../', $sourcePathDepth); + } $commonPath = rtrim($commonPath, '/') . '/'; $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/'); $commonPathCode = str_repeat('../', $sourcePathDepth); @@ -81,16 +85,17 @@ class Filesystem * * @param string $from * @param string $to + * @param Boolean $directories if true, the source/target are considered to be directories * @return string */ - public function findShortestPathCode($from, $to) + public function findShortestPathCode($from, $to, $directories = false) { if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) { throw new \InvalidArgumentException('from and to must be absolute paths'); } if ($from === $to) { - return '__FILE__'; + return $directories ? '__DIR__' : '__FILE__'; } $from = strtr($from, '\\', '/'); $to = strtr($to, '\\', '/'); @@ -105,7 +110,14 @@ class Filesystem } $commonPath = rtrim($commonPath, '/') . '/'; - $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/'); + if (strpos($to, $from) === 0) { + return '__DIR__ . '.var_export(substr($to, strlen($from)), true); + } + if (strpos($from, $to) === 0) { + $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/') - 1 + $directories; + return str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth); + } + $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/') + $directories; $commonPathCode = str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth); return $commonPathCode . '.' . var_export('/' . substr($to, strlen($commonPath)), true); } diff --git a/tests/Composer/Test/Downloader/Util/FilesystemTest.php b/tests/Composer/Test/Downloader/Util/FilesystemTest.php index f4d9af04f..592875dc2 100644 --- a/tests/Composer/Test/Downloader/Util/FilesystemTest.php +++ b/tests/Composer/Test/Downloader/Util/FilesystemTest.php @@ -20,24 +20,35 @@ class FilesystemTest extends TestCase /** * @dataProvider providePathCouplesAsCode */ - public function testFindShortestPathCode($a, $b, $expected) + public function testFindShortestPathCode($a, $b, $directory, $expected) { $fs = new Filesystem; - $this->assertEquals($expected, $fs->findShortestPathCode($a, $b)); + $this->assertEquals($expected, $fs->findShortestPathCode($a, $b, $directory)); } public function providePathCouplesAsCode() { return array( - array('/foo/bar', '/foo/bar', "__FILE__"), - array('/foo/bar', '/foo/baz', "__DIR__.'/baz'"), - array('/foo/bin/run', '/foo/vendor/acme/bin/run', "dirname(__DIR__).'/vendor/acme/bin/run'"), - array('/foo/bin/run', '/foo/vendor/acme/bin/run', "dirname(__DIR__).'/vendor/acme/bin/run'"), - array('/foo/bin/run', '/bar/bin/run', "'/bar/bin/run'"), - array('c:/bin/run', 'c:/vendor/acme/bin/run', "dirname(__DIR__).'/vendor/acme/bin/run'"), - array('c:\\bin\\run', 'c:/vendor/acme/bin/run', "dirname(__DIR__).'/vendor/acme/bin/run'"), - array('c:/bin/run', 'd:/vendor/acme/bin/run', "'d:/vendor/acme/bin/run'"), - array('c:\\bin\\run', 'd:/vendor/acme/bin/run', "'d:/vendor/acme/bin/run'"), + array('/foo/bar', '/foo/bar', false, "__FILE__"), + array('/foo/bar', '/foo/baz', false, "__DIR__.'/baz'"), + array('/foo/bin/run', '/foo/vendor/acme/bin/run', false, "dirname(__DIR__).'/vendor/acme/bin/run'"), + array('/foo/bin/run', '/foo/vendor/acme/bin/run', false, "dirname(__DIR__).'/vendor/acme/bin/run'"), + array('/foo/bin/run', '/bar/bin/run', false, "'/bar/bin/run'"), + array('c:/bin/run', 'c:/vendor/acme/bin/run', false, "dirname(__DIR__).'/vendor/acme/bin/run'"), + array('c:\\bin\\run', 'c:/vendor/acme/bin/run', false, "dirname(__DIR__).'/vendor/acme/bin/run'"), + array('c:/bin/run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"), + array('c:\\bin\\run', 'd:/vendor/acme/bin/run', false, "'d:/vendor/acme/bin/run'"), + array('/foo/bar', '/foo/bar', true, "__DIR__"), + array('/foo/bar', '/foo/baz', true, "dirname(__DIR__).'/baz'"), + array('/foo/bin/run', '/foo/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"), + array('/foo/bin/run', '/foo/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"), + array('/foo/bin/run', '/bar/bin/run', true, "'/bar/bin/run'"), + array('c:/bin/run', 'c:/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"), + array('c:\\bin\\run', 'c:/vendor/acme/bin/run', true, "dirname(dirname(__DIR__)).'/vendor/acme/bin/run'"), + array('c:/bin/run', 'd:/vendor/acme/bin/run', true, "'d:/vendor/acme/bin/run'"), + array('c:\\bin\\run', 'd:/vendor/acme/bin/run', true, "'d:/vendor/acme/bin/run'"), + array('C:/Temp/test', 'C:\Temp', true, "dirname(__DIR__)"), + array('C:/Temp', 'C:\Temp\test', true, "__DIR__ . '/test'"), ); } @@ -62,6 +73,8 @@ class FilesystemTest extends TestCase array('c:\\bin\\run', 'c:/vendor/acme/bin/run', "../vendor/acme/bin/run"), array('c:/bin/run', 'd:/vendor/acme/bin/run', "d:/vendor/acme/bin/run"), array('c:\\bin\\run', 'd:/vendor/acme/bin/run', "d:/vendor/acme/bin/run"), + array('C:/Temp/test', 'C:\Temp', "../"), + array('C:/Temp', 'C:\Temp\test', "test"), ); } } From a19695cdcbcc20b96db86749fe26272a3d6706c8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 4 Dec 2011 18:44:40 +0100 Subject: [PATCH 4/7] Tentative fix for *nix --- src/Composer/Downloader/Util/Filesystem.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Composer/Downloader/Util/Filesystem.php b/src/Composer/Downloader/Util/Filesystem.php index bd8a346af..e20296b51 100644 --- a/src/Composer/Downloader/Util/Filesystem.php +++ b/src/Composer/Downloader/Util/Filesystem.php @@ -61,12 +61,12 @@ class Filesystem $from = rtrim(strtr($from, '\\', '/'), '/'); $to = rtrim(strtr($to, '\\', '/'), '/'); - $commonPath = dirname($to); - while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/$}i', $commonPath)) { + $commonPath = strtr(dirname($to), '\\', '/'); + while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/?$}i', $commonPath) && '.' !== $commonPath) { $commonPath = strtr(dirname($commonPath), '\\', '/'); } - if (0 !== strpos($from, $commonPath) || '/' === $commonPath) { + if (0 !== strpos($from, $commonPath) || '/' === $commonPath || '.' === $commonPath) { return $to; } From 21d74328e307b77f5bcb3748e6d0e31055cf5ac7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 4 Dec 2011 22:00:55 +0100 Subject: [PATCH 5/7] Cosmetic fixes --- tests/Composer/Test/Autoload/AutoloadGeneratorTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index f7b327092..d1236d6f0 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -53,9 +53,7 @@ class AutoloadGeneratorTest extends \PHPUnit_Framework_TestCase return $that->vendorDir; })); - $this->repo = $this->getMockBuilder('Composer\Repository\RepositoryInterface') - ->disableOriginalConstructor() - ->getMock(); + $this->repo = $this->getMock('Composer\Repository\RepositoryInterface'); $this->generator = new AutoloadGenerator(); } @@ -115,6 +113,6 @@ class AutoloadGeneratorTest extends \PHPUnit_Framework_TestCase private function assertAutoloadFiles($name, $dir) { - $this->assertEquals(file_get_contents(__DIR__.'/Fixtures/autoload_'.$name.'.php'), file_get_contents($dir.'/autoload_namespaces.php')); + $this->assertFileEquals(__DIR__.'/Fixtures/autoload_'.$name.'.php', $dir.'/autoload_namespaces.php'); } } From 304ce3b3750ca772120c41e91b181d09b81c14ae Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 4 Dec 2011 22:13:11 +0100 Subject: [PATCH 6/7] Fix relative target dirs --- src/Composer/Autoload/AutoloadGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 9c6665ab6..e3e5c49a9 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -52,7 +52,7 @@ EOF; $filesystem = new Filesystem(); $vendorPath = strtr(realpath($installationManager->getVendorPath()), '\\', '/'); $relVendorPath = ltrim(substr($vendorPath, strlen(getcwd())), '/'); - $vendorDirCode = $filesystem->findShortestPathCode($targetDir, $vendorPath, true); + $vendorDirCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true); $namespacesFile = << Date: Sun, 4 Dec 2011 22:40:30 +0100 Subject: [PATCH 7/7] Added more tests for Filesystem util and some fixes --- src/Composer/Downloader/Util/Filesystem.php | 23 +++++++------------ .../Test/Downloader/Util/FilesystemTest.php | 8 ++++++- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Composer/Downloader/Util/Filesystem.php b/src/Composer/Downloader/Util/Filesystem.php index e20296b51..e486d8631 100644 --- a/src/Composer/Downloader/Util/Filesystem.php +++ b/src/Composer/Downloader/Util/Filesystem.php @@ -61,7 +61,7 @@ class Filesystem $from = rtrim(strtr($from, '\\', '/'), '/'); $to = rtrim(strtr($to, '\\', '/'), '/'); - $commonPath = strtr(dirname($to), '\\', '/'); + $commonPath = $to; while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/?$}i', $commonPath) && '.' !== $commonPath) { $commonPath = strtr(dirname($commonPath), '\\', '/'); } @@ -70,14 +70,10 @@ class Filesystem return $to; } - if (strpos($from, $to) === 0) { - $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/'); - return str_repeat('../', $sourcePathDepth); - } $commonPath = rtrim($commonPath, '/') . '/'; $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/'); $commonPathCode = str_repeat('../', $sourcePathDepth); - return $commonPathCode . substr($to, strlen($commonPath)); + return ($commonPathCode . substr($to, strlen($commonPath))) ?: './'; } /** @@ -100,26 +96,23 @@ class Filesystem $from = strtr($from, '\\', '/'); $to = strtr($to, '\\', '/'); - $commonPath = dirname($to); - while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/$}i', $commonPath)) { + $commonPath = $to; + while (strpos($from, $commonPath) !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/?$}i', $commonPath) && '.' !== $commonPath) { $commonPath = strtr(dirname($commonPath), '\\', '/'); } - if (0 !== strpos($from, $commonPath) || '/' === $commonPath) { + if (0 !== strpos($from, $commonPath) || '/' === $commonPath || '.' === $commonPath) { return var_export($to, true); } $commonPath = rtrim($commonPath, '/') . '/'; - if (strpos($to, $from) === 0) { + if (strpos($to, $from.'/') === 0) { return '__DIR__ . '.var_export(substr($to, strlen($from)), true); } - if (strpos($from, $to) === 0) { - $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/') - 1 + $directories; - return str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth); - } $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/') + $directories; $commonPathCode = str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth); - return $commonPathCode . '.' . var_export('/' . substr($to, strlen($commonPath)), true); + $relTarget = substr($to, strlen($commonPath)); + return $commonPathCode . (strlen($relTarget) ? '.' . var_export('/' . $relTarget, true) : ''); } /** diff --git a/tests/Composer/Test/Downloader/Util/FilesystemTest.php b/tests/Composer/Test/Downloader/Util/FilesystemTest.php index 592875dc2..01a3189b8 100644 --- a/tests/Composer/Test/Downloader/Util/FilesystemTest.php +++ b/tests/Composer/Test/Downloader/Util/FilesystemTest.php @@ -49,6 +49,8 @@ class FilesystemTest extends TestCase array('c:\\bin\\run', 'd:/vendor/acme/bin/run', true, "'d:/vendor/acme/bin/run'"), array('C:/Temp/test', 'C:\Temp', true, "dirname(__DIR__)"), array('C:/Temp', 'C:\Temp\test', true, "__DIR__ . '/test'"), + array('/tmp/test', '/tmp', true, "dirname(__DIR__)"), + array('/tmp', '/tmp/test', true, "__DIR__ . '/test'"), ); } @@ -73,7 +75,11 @@ class FilesystemTest extends TestCase array('c:\\bin\\run', 'c:/vendor/acme/bin/run', "../vendor/acme/bin/run"), array('c:/bin/run', 'd:/vendor/acme/bin/run', "d:/vendor/acme/bin/run"), array('c:\\bin\\run', 'd:/vendor/acme/bin/run', "d:/vendor/acme/bin/run"), - array('C:/Temp/test', 'C:\Temp', "../"), + array('C:/Temp/test', 'C:\Temp', "./"), + array('/tmp/test', '/tmp', "./"), + array('C:/Temp/test/sub', 'C:\Temp', "../"), + array('/tmp/test/sub', '/tmp', "../"), + array('/tmp', '/tmp/test', "test"), array('C:/Temp', 'C:\Temp\test', "test"), ); }