From 48444a028cc5857d834b4b008dd3b67689432263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Mon, 1 Apr 2013 09:27:50 +0200 Subject: [PATCH] Added support for vendor dir excluded from working dir --- src/Composer/Autoload/AutoloadGenerator.php | 49 +++++----- .../Test/Autoload/AutoloadGeneratorTest.php | 91 +++++++++++++++++++ 2 files changed, 115 insertions(+), 25 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index f7abfe1c2..4a4b0fc72 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -41,18 +41,18 @@ class AutoloadGenerator { $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($config->get('vendor-dir')); - $vendorPath = strtr(realpath($config->get('vendor-dir')), '\\', '/'); + $basePath = $filesystem->normalizePath(getcwd()); + $vendorPath = $filesystem->normalizePath(realpath($config->get('vendor-dir'))); $useGlobalIncludePath = (bool) $config->get('use-include-path'); $targetDir = $vendorPath.'/'.$targetDir; $filesystem->ensureDirectoryExists($targetDir); - $cwd = getcwd(); - $relVendorPath = $filesystem->findShortestPath($cwd, $vendorPath, true); + $relVendorPath = $filesystem->findShortestPath($basePath, $vendorPath, true); $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true); $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode); $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true); - $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $cwd, true); + $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true); $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode); $namespacesFile = << $paths) { $exportedPaths = array(); foreach ($paths as $path) { - $exportedPaths[] = $this->getPathCode($filesystem, $relVendorPath, $vendorPath, $path); + $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $relVendorPath, $vendorPath, $path); } $exportedPrefix = var_export($namespace, true); $namespacesFile .= " $exportedPrefix => "; @@ -101,11 +101,11 @@ EOF; $targetDirLoader = null; $mainAutoload = $mainPackage->getAutoload(); if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) { - $levels = count(explode('/', trim(strtr($mainPackage->getTargetDir(), '\\', '/'), '/'))); + $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir()))); $prefixes = implode(', ', array_map(function ($prefix) { return var_export($prefix, true); }, array_keys($mainAutoload['psr-0']))); - $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $cwd, true); + $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true); $targetDirLoader = << $paths) { foreach ($paths as $dir) { - $dir = $this->getPath($filesystem, $relVendorPath, $vendorPath, $dir); + $dir = $this->getPath($filesystem, $basePath, $relVendorPath, $vendorPath, $dir); $whitelist = sprintf( '{%s/%s.+(? $path) { if ('' === $namespace || 0 === strpos($class, $namespace)) { - $path = '/'.$filesystem->findShortestPath($cwd, $path, true); if (!isset($classMap[$class])) { - $classMap[$class] = '$baseDir . '.var_export($path, true).",\n"; + $path = $this->getPathCode($filesystem, $basePath, $relVendorPath, $vendorPath, $path); + $classMap[$class] = $path.",\n"; } } } @@ -159,12 +159,8 @@ EOF; $autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap'])); foreach ($autoloads['classmap'] as $dir) { foreach (ClassMapGenerator::createMap($dir) as $class => $path) { - $path = $filesystem->findShortestPath($cwd, $path, true); - if ($filesystem->isAbsolutePath($path)) { - $classMap[$class] = var_export($path, true).",\n"; - } else { - $classMap[$class] = '$baseDir . '.var_export('/'.$path, true).",\n"; - } + $path = $this->getPathCode($filesystem, $basePath, $relVendorPath, $vendorPath, $path); + $classMap[$class] = $path.",\n"; } } @@ -177,7 +173,7 @@ EOF; $filesCode = ""; $autoloads['files'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['files'])); foreach ($autoloads['files'] as $functionFile) { - $filesCode .= ' require '.$this->getPathCode($filesystem, $relVendorPath, $vendorPath, $functionFile).";\n"; + $filesCode .= ' require '.$this->getPathCode($filesystem, $basePath, $relVendorPath, $vendorPath, $functionFile).";\n"; } if (!$suffix) { @@ -186,7 +182,7 @@ EOF; file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile); file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile); - if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { + if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $relVendorPath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) { file_put_contents($targetDir.'/include_paths.php', $includePathFile); } file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix)); @@ -257,7 +253,7 @@ EOF; return $loader; } - protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode) + protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode) { $includePaths = array(); @@ -291,15 +287,15 @@ return array( EOF; foreach ($includePaths as $path) { - $includePathsFile .= " " . $this->getPathCode($filesystem, $relVendorPath, $vendorPath, $path) . ",\n"; + $includePathsFile .= " " . $this->getPathCode($filesystem, $basePath, $relVendorPath, $vendorPath, $path) . ",\n"; } return $includePathsFile . ");\n"; } - protected function getPathCode(Filesystem $filesystem, $relVendorPath, $vendorPath, $path) + protected function getPathCode(Filesystem $filesystem, $basePath, $relVendorPath, $vendorPath, $path) { - $path = strtr($path, '\\', '/'); + $path = $filesystem->normalizePath($path); $baseDir = ''; if (!$filesystem->isAbsolutePath($path)) { if (strpos($path, $relVendorPath) === 0) { @@ -313,6 +309,9 @@ EOF; } elseif (strpos($path, $vendorPath) === 0) { $path = substr($path, strlen($vendorPath)); $baseDir = '$vendorDir . '; + } elseif (strpos($path, $basePath) === 0) { + $path = substr($path, strlen($basePath)); + $baseDir = '$baseDir . '; } if (preg_match('/\.phar$/', $path)){ @@ -322,16 +321,16 @@ EOF; return $baseDir.var_export($path, true); } - protected function getPath(Filesystem $filesystem, $relVendorPath, $vendorPath, $path) + protected function getPath(Filesystem $filesystem, $basePath, $relVendorPath, $vendorPath, $path) { - $path = strtr($path, '\\', '/'); + $path = $filesystem->normalizePath($path); if (!$filesystem->isAbsolutePath($path)) { if (strpos($path, $relVendorPath) === 0) { // path starts with vendor dir return $vendorPath . substr($path, strlen($relVendorPath)); } - return strtr(getcwd(), '\\', '/').'/'.$path; + return $basePath.'/'.$path; } return $path; diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 5fff7b6e5..40b0a67cc 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -660,6 +660,97 @@ EOF; $this->assertFileEquals(__DIR__.'/Fixtures/autoload_real_include_path.php', $this->vendorDir.'/composer/autoload_real.php'); } + public function testVendorDirExcludedFromWorkingDir() + { + $workingDir = $this->vendorDir.'/working-dir'; + $vendorDir = $workingDir.'/../vendor'; + + $this->fs->ensureDirectoryExists($workingDir); + chdir($workingDir); + + $package = new Package('a', '1.0', '1.0'); + $package->setAutoload(array( + 'psr-0' => array('Foo' => 'src'), + 'classmap' => array('classmap'), + 'files' => array('test.php'), + )); + + $vendorPackage = new Package('b/b', '1.0', '1.0'); + $vendorPackage->setAutoload(array( + 'psr-0' => array('Bar' => 'lib'), + 'classmap' => array('classmaps'), + 'files' => array('bootstrap.php'), + )); + + $this->repository->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue(array($vendorPackage))); + + $im = $this->getMockBuilder('Composer\Installer\InstallationManager') + ->disableOriginalConstructor() + ->getMock(); + $im->expects($this->any()) + ->method('getInstallPath') + ->will($this->returnCallback(function ($package) use ($vendorDir) { + $targetDir = $package->getTargetDir(); + return $vendorDir.'/'.$package->getName() . ($targetDir ? '/'.$targetDir : ''); + })); + + $this->fs->ensureDirectoryExists($workingDir.'/src/Foo'); + $this->fs->ensureDirectoryExists($workingDir.'/classmap'); + $this->fs->ensureDirectoryExists($vendorDir.'/composer'); + $this->fs->ensureDirectoryExists($vendorDir.'/b/b/lib/Bar'); + $this->fs->ensureDirectoryExists($vendorDir.'/b/b/classmaps'); + file_put_contents($workingDir.'/src/Foo/Bar.php', 'vendorDir; + $this->vendorDir = $vendorDir; + $this->generator->dump($this->config, $this->repository, $package, $im, 'composer', true, '_13'); + $this->vendorDir = $oldVendorDir; + + $expectedNamespace = <<<'EOF' + $baseDir . '/src', + 'Bar' => $vendorDir . '/b/b/lib', +); + +EOF; + + $expectedClassmap = <<<'EOF' + $vendorDir . '/b/b/classmaps/classes.php', + 'Bar\\Foo' => $vendorDir . '/b/b/lib/Bar/Foo.php', + 'Foo\\Bar' => $baseDir . '/src/Foo/Bar.php', + 'Foo\\Foo' => $baseDir . '/classmap/classes.php', +); + +EOF; + + $this->assertEquals($expectedNamespace, file_get_contents($vendorDir.'/composer/autoload_namespaces.php')); + $this->assertEquals($expectedClassmap, file_get_contents($vendorDir.'/composer/autoload_classmap.php')); + $this->assertContains("require \$vendorDir . '/b/b/bootstrap.php';", file_get_contents($vendorDir.'/composer/autoload_real.php')); + $this->assertContains("require \$baseDir . '/test.php';", file_get_contents($vendorDir.'/composer/autoload_real.php')); + } + private function assertAutoloadFiles($name, $dir, $type = 'namespaces') { $a = __DIR__.'/Fixtures/autoload_'.$name.'.php';