From eedbd218f52c526ec41c6c623137c3781eb4d928 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 31 May 2018 17:02:04 +0200 Subject: [PATCH] Make sure circular dependencies do not break the autoload dumper, refs #7316, refs #7348 --- src/Composer/Autoload/AutoloadGenerator.php | 15 +++++---- .../Test/Autoload/AutoloadGeneratorTest.php | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index b881a2163..5a0da1f40 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -902,12 +902,13 @@ INITIALIZER; /** * Filters out dev-dependencies when not in dev-mode - * + * * @param array $packageMap * @param PackageInterface $mainPackage * @return array */ - protected function filterPackageMap(array $packageMap, PackageInterface $mainPackage) { + protected function filterPackageMap(array $packageMap, PackageInterface $mainPackage) + { if ($this->devMode === true) { return $packageMap; } @@ -924,14 +925,16 @@ INITIALIZER; $add = function (PackageInterface $package) use (&$add, $mainPackage, $packages, &$include) { foreach ($package->getRequires() as $link) { $target = $link->getTarget(); - $include[$target] = true; - if (isset($packages[$target])) { - $add($packages[$target]); + if (!isset($include[$target])) { + $include[$target] = true; + if (isset($packages[$target])) { + $add($packages[$target]); + } } } }; $add($mainPackage); - + return array_filter( $packageMap, function ($item) use ($include) { diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index f491a62b5..dd99bfd59 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -386,6 +386,39 @@ class AutoloadGeneratorTest extends TestCase $this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated, even if empty."); } + public function testNonDevAutoloadExclusionWithRecursion() + { + $package = new Package('a', '1.0', '1.0'); + $package->setRequires(array( + new Link('a', 'a/a'), + )); + + $packages = array(); + $packages[] = $a = new Package('a/a', '1.0', '1.0'); + $packages[] = $b = new Package('b/b', '1.0', '1.0'); + $a->setAutoload(array('psr-0' => array('A' => 'src/', 'A\\B' => 'lib/'))); + $a->setRequires(array( + new Link('a/a', 'b/b'), + )); + $b->setAutoload(array('psr-0' => array('B\\Sub\\Name' => 'src/'))); + $b->setRequires(array( + new Link('b/b', 'a/a'), + )); + + $this->repository->expects($this->once()) + ->method('getCanonicalPackages') + ->will($this->returnValue($packages)); + + $this->fs->ensureDirectoryExists($this->vendorDir.'/composer'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/src'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/a/a/lib'); + $this->fs->ensureDirectoryExists($this->vendorDir.'/b/b/src'); + + $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, '_5'); + $this->assertAutoloadFiles('vendors', $this->vendorDir.'/composer'); + $this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated, even if empty."); + } + public function testPSRToClassMapIgnoresNonExistingDir() { $package = new Package('a', '1.0', '1.0');