From 9d8db4e14858537e440f1a9523b6ea952013c184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Proch=C3=A1zka?= Date: Sat, 1 Sep 2012 13:24:17 +0200 Subject: [PATCH 1/2] AutoloadGenerator: respect dependencies, when requiring files --- src/Composer/Autoload/AutoloadGenerator.php | 26 ++++++++-- .../Test/Autoload/AutoloadGeneratorTest.php | 47 +++++++++++++++++++ .../autoload_functions_by_dependency.php | 7 +++ .../autoload_real_files_by_dependency.php | 34 ++++++++++++++ 4 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_functions_by_dependency.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_real_files_by_dependency.php diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 20a8e43df..797f89d5f 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -170,13 +170,30 @@ EOF; { // build package => install path map $packageMap = array(); + $packages[] = $mainPackage; - // add main package - $packageMap[] = array($mainPackage, ''); + // sort packages by dependencies + usort($packages, function (PackageInterface $a, PackageInterface $b) { + foreach (array_merge($a->getRequires(), $a->getDevRequires()) as $link) { + if (in_array($link->getTarget(), $b->getNames())) { + return 1; + } + } + foreach (array_merge($b->getRequires(), $b->getDevRequires()) as $link) { + if (in_array($link->getTarget(), $a->getNames())) { + return -1; + } + } + + return strcmp($a->getName(), $b->getName()); + }); foreach ($packages as $package) { if ($package instanceof AliasPackage) { continue; + } elseif ($package === $mainPackage) { + $packageMap[] = array($mainPackage, ''); + continue; } $packageMap[] = array( $package, @@ -217,9 +234,8 @@ EOF; } } - foreach ($autoloads as $type => $maps) { - krsort($autoloads[$type]); - } + krsort($autoloads['classmap']); + krsort($autoloads['psr-0']); return $autoloads; } diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index 3c832995b..b6cb99a6b 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -13,6 +13,7 @@ namespace Composer\Test\Autoload; use Composer\Autoload\AutoloadGenerator; +use Composer\Package\Link; use Composer\Util\Filesystem; use Composer\Package\AliasPackage; use Composer\Package\Package; @@ -317,6 +318,52 @@ class AutoloadGeneratorTest extends TestCase $this->assertTrue(function_exists('testFilesAutoloadGenerationRoot')); } + public function testFilesAutoloadOrderByDependencies() + { + $package = new Package('a', '1.0', '1.0'); + $package->setAutoload(array('files' => array('root.php'))); + $package->setRequires(array(new Link('a', 'a/foo'))); + + $packages = array(); + $packages[] = $a = new Package('a/foo', '1.0', '1.0'); + $packages[] = $b = new Package('b/bar', '1.0', '1.0'); + $packages[] = $c = new Package('c/lorem', '1.0', '1.0'); + + $a->setAutoload(array('files' => array('testA.php'))); + $a->setRequires(array(new Link('a/foo', 'c/lorem'))); + + $b->setAutoload(array('files' => array('testB.php'))); + $b->setRequires(array(new Link('b/bar', 'c/lorem'))); + + $c->setAutoload(array('files' => array('testC.php'))); + + $this->repository->expects($this->once()) + ->method('getPackages') + ->will($this->returnValue($packages)); + + $this->fs->ensureDirectoryExists($this->vendorDir . '/a/foo'); + $this->fs->ensureDirectoryExists($this->vendorDir . '/b/bar'); + $this->fs->ensureDirectoryExists($this->vendorDir . '/c/lorem'); + file_put_contents($this->vendorDir . '/a/foo/testA.php', 'vendorDir . '/b/bar/testB.php', 'vendorDir . '/c/lorem/testC.php', 'workingDir . '/root.php', 'generator->dump($this->config, $this->repository, $package, $this->im, 'composer', false, 'FilesAutoloadOrder'); + $this->assertFileEquals(__DIR__ . '/Fixtures/autoload_functions_by_dependency.php', $this->vendorDir . '/autoload.php'); + $this->assertFileEquals(__DIR__ . '/Fixtures/autoload_real_files_by_dependency.php', $this->vendorDir . '/composer/autoload_realFilesAutoloadOrder.php'); + + // suppress the class loader to avoid fatals if the class is redefined + file_put_contents($this->vendorDir . '/composer/ClassLoader.php', ''); + + include $this->vendorDir . '/autoload.php'; + + $this->assertTrue(function_exists('testFilesAutoloadOrderByDependency1')); + $this->assertTrue(function_exists('testFilesAutoloadOrderByDependency2')); + $this->assertTrue(function_exists('testFilesAutoloadOrderByDependency3')); + $this->assertTrue(function_exists('testFilesAutoloadOrderByDependencyRoot')); + } + public function testOverrideVendorsAutoloading() { $package = new Package('a', '1.0', '1.0'); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_functions_by_dependency.php b/tests/Composer/Test/Autoload/Fixtures/autoload_functions_by_dependency.php new file mode 100644 index 000000000..c643a7462 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_functions_by_dependency.php @@ -0,0 +1,7 @@ + $path) { + $loader->add($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + + $loader->register(); + + require $vendorDir . '/c/lorem/testC.php'; + require $vendorDir . '/a/foo/testA.php'; + require $baseDir . '/root.php'; + require $vendorDir . '/b/bar/testB.php'; + + return $loader; + } +} From 80e9999d1c7b897662647f404a0b16955e1b03c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Proch=C3=A1zka?= Date: Thu, 6 Sep 2012 17:26:42 +0200 Subject: [PATCH 2/2] typo --- src/Composer/Autoload/AutoloadGenerator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 797f89d5f..f03f85293 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -191,7 +191,8 @@ EOF; foreach ($packages as $package) { if ($package instanceof AliasPackage) { continue; - } elseif ($package === $mainPackage) { + } + if ($package === $mainPackage) { $packageMap[] = array($mainPackage, ''); continue; }