diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 7ae1cc803..9bf57b29d 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/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('\\', '[\\\\/]', preg_quote(str_replace(array('/', '\\'), '', $package->getTargetDir()))); + $path = ltrim(preg_replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/'); + } + $autoloads[$namespace][] = empty($installPath) ? $path : $installPath.'/'.$path; } } diff --git a/src/Composer/Installer/InstallerInstaller.php b/src/Composer/Installer/InstallerInstaller.php index f54b295dc..cde0030cb 100644 --- a/src/Composer/Installer/InstallerInstaller.php +++ b/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(); diff --git a/src/Composer/Script/EventDispatcher.php b/src/Composer/Script/EventDispatcher.php index 00aebf883..702e430ff 100644 --- a/src/Composer/Script/EventDispatcher.php +++ b/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(); diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index b94137db6..4192ee584 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/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/');