Browse Source

Remove target dir for classmap autoloads of the root package, fixes #1308

Jordi Boggiano 12 years ago
parent
commit
de3188ca7d

+ 17 - 10
src/Composer/Autoload/AutoloadGenerator.php

@@ -53,7 +53,7 @@ return array(
 EOF;
 
         $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getPackages());
-        $autoloads = $this->parseAutoloads($packageMap);
+        $autoloads = $this->parseAutoloads($packageMap, $mainPackage);
 
         foreach ($autoloads['psr-0'] as $namespace => $paths) {
             $exportedPaths = array();
@@ -199,16 +199,17 @@ EOF;
     /**
      * Compiles an ordered list of namespace => path mappings
      *
-     * @param  array $packageMap array of array(package, installDir-relative-to-composer.json)
-     * @return array array('psr-0' => array('Ns\\Foo' => array('installDir')))
+     * @param  array            $packageMap  array of array(package, installDir-relative-to-composer.json)
+     * @param  PackageInterface $mainPackage root package instance
+     * @return array            array('psr-0' => array('Ns\\Foo' => array('installDir')))
      */
-    public function parseAutoloads(array $packageMap)
+    public function parseAutoloads(array $packageMap, PackageInterface $mainPackage)
     {
         $sortedPackageMap = $this->sortPackageMap($packageMap);
 
-        $psr0 = $this->parseAutoloadsType($packageMap, 'psr-0');
-        $classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap');
-        $files = $this->parseAutoloadsType($sortedPackageMap, 'files');
+        $psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
+        $classmap = $this->parseAutoloadsType($sortedPackageMap, 'classmap', $mainPackage);
+        $files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage);
 
         krsort($psr0);
 
@@ -427,24 +428,30 @@ FOOTER;
 
     }
 
-    protected function parseAutoloadsType(array $packageMap, $type)
+    protected function parseAutoloadsType(array $packageMap, $type, PackageInterface $mainPackage)
     {
         $autoloads = array();
         foreach ($packageMap as $item) {
             list($package, $installPath) = $item;
 
             $autoload = $package->getAutoload();
+
             // skip misconfigured packages
             if (!isset($autoload[$type]) || !is_array($autoload[$type])) {
                 continue;
             }
-
-            if (null !== $package->getTargetDir()) {
+            if (null !== $package->getTargetDir() && $package !== $mainPackage) {
                 $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
             }
 
             foreach ($autoload[$type] as $namespace => $paths) {
                 foreach ((array) $paths as $path) {
+                    // remove target-dir from classmap entries of the root package
+                    if ($type === 'classmap' && $package === $mainPackage && $package->getTargetDir()) {
+                        $targetDir = str_replace('\\<dirsep\\>', '[\\\\/]', preg_quote(str_replace(array('/', '\\'), '<dirsep>', $package->getTargetDir())));
+                        $path = ltrim(preg_replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/');
+                    }
+
                     $autoloads[$namespace][] = empty($installPath) ? $path : $installPath.'/'.$path;
                 }
             }

+ 2 - 1
src/Composer/Installer/InstallerInstaller.php

@@ -13,6 +13,7 @@
 namespace Composer\Installer;
 
 use Composer\Composer;
+use Composer\Package\Package;
 use Composer\IO\IOInterface;
 use Composer\Autoload\AutoloadGenerator;
 use Composer\Repository\InstalledRepositoryInterface;
@@ -85,7 +86,7 @@ class InstallerInstaller extends LibraryInstaller
         $classes = is_array($extra['class']) ? $extra['class'] : array($extra['class']);
 
         $generator = new AutoloadGenerator;
-        $map = $generator->parseAutoloads(array(array($package, $downloadPath)));
+        $map = $generator->parseAutoloads(array(array($package, $downloadPath)), new Package('dummy', '1.0.0.0', '1.0.0'));
         $classLoader = $generator->createLoader($map);
         $classLoader->register();
 

+ 1 - 1
src/Composer/Script/EventDispatcher.php

@@ -140,7 +140,7 @@ class EventDispatcher
         $generator = new AutoloadGenerator;
         $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getPackages();
         $packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
-        $map = $generator->parseAutoloads($packageMap);
+        $map = $generator->parseAutoloads($packageMap, $package);
         $this->loader = $generator->createLoader($map);
         $this->loader->register();
 

+ 2 - 2
tests/Composer/Test/Autoload/AutoloadGeneratorTest.php

@@ -165,11 +165,11 @@ class AutoloadGeneratorTest extends TestCase
         $this->assertFileEquals(__DIR__.'/Fixtures/autoload_real_target_dir.php', $this->vendorDir.'/composer/autoload_real.php');
     }
 
-    public function testMainPackageAutoloadingWithTargetDirAndNoPsr()
+    public function testMainPackageAutoloadingWithTargetDirAndClassmap()
     {
         $package = new Package('a', '1.0', '1.0');
         $package->setAutoload(array(
-            'classmap' => array('composersrc/'),
+            'classmap' => array('Main/Foo/composersrc/'),
         ));
         $package->setTargetDir('Main/Foo/');