1
0
Fork 0

Merge pull request #961 from vicb/autoload

[Autoload] remove closures because of a bug in APC
pull/967/head
Nils Adermann 2012-07-31 15:30:48 -07:00
commit 65e95ed796
4 changed files with 147 additions and 98 deletions

View File

@ -25,7 +25,7 @@ use Composer\Util\Filesystem;
*/ */
class AutoloadGenerator class AutoloadGenerator
{ {
public function dump(Config $config, RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir) public function dump(Config $config, RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $classSuffix = '')
{ {
$filesystem = new Filesystem(); $filesystem = new Filesystem();
$filesystem->ensureDirectoryExists($config->get('vendor-dir')); $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
@ -93,7 +93,9 @@ EOF;
$baseDirFromVendorDirCode = $filesystem->findShortestPathCode($vendorPath, getcwd(), true); $baseDirFromVendorDirCode = $filesystem->findShortestPathCode($vendorPath, getcwd(), true);
$targetDirLoader = <<<EOF $targetDirLoader = <<<EOF
spl_autoload_register(function(\$class) {
public static function autoload(\$class)
{
\$dir = $baseDirFromVendorDirCode . '/'; \$dir = $baseDirFromVendorDirCode . '/';
\$prefixes = array($prefixes); \$prefixes = array($prefixes);
foreach (\$prefixes as \$prefix) { foreach (\$prefixes as \$prefix) {
@ -108,8 +110,7 @@ EOF;
return true; return true;
} }
}); }
EOF; EOF;
} }
@ -135,7 +136,7 @@ EOF;
if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)) { if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)) {
file_put_contents($targetDir.'/include_paths.php', $includePathFile); file_put_contents($targetDir.'/include_paths.php', $includePathFile);
} }
file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, true, true, (bool) $includePathFile, $targetDirLoader, $filesCode)); file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, true, true, (bool) $includePathFile, $targetDirLoader, $filesCode, $classSuffix));
copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php'); copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
} }
@ -277,8 +278,14 @@ EOF;
return $baseDir.var_export($path, true); return $baseDir.var_export($path, true);
} }
protected function getAutoloadFile($vendorPathToTargetDirCode, $usePSR0, $useClassMap, $useIncludePath, $targetDirLoader, $filesCode) protected function getAutoloadFile($vendorPathToTargetDirCode, $usePSR0, $useClassMap, $useIncludePath, $targetDirLoader, $filesCode, $classSuffix)
{ {
// TODO the class ComposerAutoloaderInit should be revert to a closure
// when APC has been fixed:
// - https://github.com/composer/composer/issues/959
// - https://bugs.php.net/bug.php?id=52144
// - https://bugs.php.net/bug.php?id=61576
if ($filesCode) { if ($filesCode) {
$filesCode = "\n".$filesCode; $filesCode = "\n".$filesCode;
} }
@ -291,7 +298,11 @@ if (!class_exists('Composer\\\\Autoload\\\\ClassLoader', false)) {
require $vendorPathToTargetDirCode . '/ClassLoader.php'; require $vendorPathToTargetDirCode . '/ClassLoader.php';
} }
return call_user_func(function() { if (!class_exists('ComposerAutoloaderInit$classSuffix', false)) {
class ComposerAutoloaderInit$classSuffix
{
public static function getLoader()
{
\$loader = new \\Composer\\Autoload\\ClassLoader(); \$loader = new \\Composer\\Autoload\\ClassLoader();
\$composerDir = $vendorPathToTargetDirCode; \$composerDir = $vendorPathToTargetDirCode;
@ -330,14 +341,33 @@ PSR0;
CLASSMAP; CLASSMAP;
} }
$file .= $targetDirLoader; if ($targetDirLoader) {
$file .= <<<REGISTER_AUTOLOAD
spl_autoload_register(array('ComposerAutoloaderInit$classSuffix', 'autoload'));
return $file . <<<FOOTER
REGISTER_AUTOLOAD;
}
$file .= <<<METHOD_FOOTER
\$loader->register(); \$loader->register();
$filesCode $filesCode
return \$loader; return \$loader;
}); }
FOOTER; METHOD_FOOTER;
$file .= $targetDirLoader;
return $file . <<<FOOTER
} }
} }
return ComposerAutoloaderInit$classSuffix::getLoader();
FOOTER;
}
}

View File

@ -95,7 +95,7 @@ class AutoloadGeneratorTest extends TestCase
$this->createClassFile($this->workingDir); $this->createClassFile($this->workingDir);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_1');
$this->assertAutoloadFiles('main', $this->vendorDir.'/composer'); $this->assertAutoloadFiles('main', $this->vendorDir.'/composer');
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap'); $this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
} }
@ -120,7 +120,7 @@ class AutoloadGeneratorTest extends TestCase
$this->createClassFile($this->vendorDir); $this->createClassFile($this->vendorDir);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_2');
$this->assertAutoloadFiles('main3', $this->vendorDir.'/composer'); $this->assertAutoloadFiles('main3', $this->vendorDir.'/composer');
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap'); $this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap');
} }
@ -140,7 +140,7 @@ class AutoloadGeneratorTest extends TestCase
$this->vendorDir .= '/subdir'; $this->vendorDir .= '/subdir';
mkdir($this->vendorDir.'/composer', 0777, true); mkdir($this->vendorDir.'/composer', 0777, true);
$this->createClassFile($this->workingDir); $this->createClassFile($this->workingDir);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_3');
$this->assertAutoloadFiles('main2', $this->vendorDir.'/composer'); $this->assertAutoloadFiles('main2', $this->vendorDir.'/composer');
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap'); $this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap');
} }
@ -157,7 +157,7 @@ class AutoloadGeneratorTest extends TestCase
->method('getPackages') ->method('getPackages')
->will($this->returnValue(array())); ->will($this->returnValue(array()));
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', 'TargetDir');
$this->assertFileEquals(__DIR__.'/Fixtures/autoload_target_dir.php', $this->vendorDir.'/autoload.php'); $this->assertFileEquals(__DIR__.'/Fixtures/autoload_target_dir.php', $this->vendorDir.'/autoload.php');
} }
@ -177,7 +177,7 @@ class AutoloadGeneratorTest extends TestCase
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
mkdir($this->vendorDir.'/composer', 0777, true); mkdir($this->vendorDir.'/composer', 0777, true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_5');
$this->assertAutoloadFiles('vendors', $this->vendorDir.'/composer'); $this->assertAutoloadFiles('vendors', $this->vendorDir.'/composer');
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty."); $this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty.");
} }
@ -204,7 +204,7 @@ class AutoloadGeneratorTest extends TestCase
file_put_contents($this->vendorDir.'/b/b/src/b.php', '<?php class ClassMapBar {}'); file_put_contents($this->vendorDir.'/b/b/src/b.php', '<?php class ClassMapBar {}');
file_put_contents($this->vendorDir.'/b/b/lib/c.php', '<?php class ClassMapBaz {}'); file_put_contents($this->vendorDir.'/b/b/lib/c.php', '<?php class ClassMapBaz {}');
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_6');
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated."); $this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
$this->assertEquals( $this->assertEquals(
array( array(
@ -241,7 +241,7 @@ class AutoloadGeneratorTest extends TestCase
file_put_contents($this->vendorDir.'/b/b/test.php', '<?php class ClassMapBar {}'); file_put_contents($this->vendorDir.'/b/b/test.php', '<?php class ClassMapBar {}');
file_put_contents($this->vendorDir.'/c/c/foo/test.php', '<?php class ClassMapBaz {}'); file_put_contents($this->vendorDir.'/c/c/foo/test.php', '<?php class ClassMapBaz {}');
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_7');
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated."); $this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
$this->assertEquals( $this->assertEquals(
array( array(
@ -273,7 +273,7 @@ class AutoloadGeneratorTest extends TestCase
file_put_contents($this->vendorDir.'/a/a/test.php', '<?php function testFilesAutoloadGeneration1() {}'); file_put_contents($this->vendorDir.'/a/a/test.php', '<?php function testFilesAutoloadGeneration1() {}');
file_put_contents($this->vendorDir.'/b/b/test2.php', '<?php function testFilesAutoloadGeneration2() {}'); file_put_contents($this->vendorDir.'/b/b/test2.php', '<?php function testFilesAutoloadGeneration2() {}');
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', 'FilesAutoload');
$this->assertFileEquals(__DIR__.'/Fixtures/autoload_functions.php', $this->vendorDir.'/autoload.php'); $this->assertFileEquals(__DIR__.'/Fixtures/autoload_functions.php', $this->vendorDir.'/autoload.php');
include $this->vendorDir . '/autoload.php'; include $this->vendorDir . '/autoload.php';
@ -297,7 +297,7 @@ class AutoloadGeneratorTest extends TestCase
->will($this->returnValue($packages)); ->will($this->returnValue($packages));
mkdir($this->vendorDir.'/composer', 0777, true); mkdir($this->vendorDir.'/composer', 0777, true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer'); $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', '_9');
$this->assertAutoloadFiles('override_vendors', $this->vendorDir.'/composer'); $this->assertAutoloadFiles('override_vendors', $this->vendorDir.'/composer');
} }
@ -325,7 +325,7 @@ class AutoloadGeneratorTest extends TestCase
mkdir($this->vendorDir."/composer", 0777, true); mkdir($this->vendorDir."/composer", 0777, true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, "composer"); $this->generator->dump($this->config, $this->repository, $package, $this->im, "composer", '_10');
$this->assertFileEquals(__DIR__.'/Fixtures/include_paths.php', $this->vendorDir.'/composer/include_paths.php'); $this->assertFileEquals(__DIR__.'/Fixtures/include_paths.php', $this->vendorDir.'/composer/include_paths.php');
$this->assertEquals( $this->assertEquals(
@ -354,7 +354,7 @@ class AutoloadGeneratorTest extends TestCase
mkdir($this->vendorDir."/composer", 0777, true); mkdir($this->vendorDir."/composer", 0777, true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, "composer"); $this->generator->dump($this->config, $this->repository, $package, $this->im, "composer", '_11');
$oldIncludePath = get_include_path(); $oldIncludePath = get_include_path();
@ -382,7 +382,7 @@ class AutoloadGeneratorTest extends TestCase
mkdir($this->vendorDir."/composer", 0777, true); mkdir($this->vendorDir."/composer", 0777, true);
$this->generator->dump($this->config, $this->repository, $package, $this->im, "composer"); $this->generator->dump($this->config, $this->repository, $package, $this->im, "composer", '_12');
$this->assertFalse(file_exists($this->vendorDir."/composer/include_paths.php")); $this->assertFalse(file_exists($this->vendorDir."/composer/include_paths.php"));
} }

View File

@ -5,7 +5,11 @@ if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
require __DIR__ . '/composer' . '/ClassLoader.php'; require __DIR__ . '/composer' . '/ClassLoader.php';
} }
return call_user_func(function() { if (!class_exists('ComposerAutoloaderInitFilesAutoload', false)) {
class ComposerAutoloaderInitFilesAutoload
{
public static function getLoader()
{
$loader = new \Composer\Autoload\ClassLoader(); $loader = new \Composer\Autoload\ClassLoader();
$composerDir = __DIR__ . '/composer'; $composerDir = __DIR__ . '/composer';
@ -25,4 +29,8 @@ return call_user_func(function() {
require $vendorDir . '/b/b/test2.php'; require $vendorDir . '/b/b/test2.php';
return $loader; return $loader;
}); }
}
}
return ComposerAutoloaderInitFilesAutoload::getLoader();

View File

@ -5,7 +5,11 @@ if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
require __DIR__ . '/composer' . '/ClassLoader.php'; require __DIR__ . '/composer' . '/ClassLoader.php';
} }
return call_user_func(function() { if (!class_exists('ComposerAutoloaderInitTargetDir', false)) {
class ComposerAutoloaderInitTargetDir
{
public static function getLoader()
{
$loader = new \Composer\Autoload\ClassLoader(); $loader = new \Composer\Autoload\ClassLoader();
$composerDir = __DIR__ . '/composer'; $composerDir = __DIR__ . '/composer';
@ -19,7 +23,15 @@ return call_user_func(function() {
$loader->addClassMap($classMap); $loader->addClassMap($classMap);
} }
spl_autoload_register(function($class) { spl_autoload_register(array('ComposerAutoloaderInitTargetDir', 'autoload'));
$loader->register();
return $loader;
}
public static function autoload($class)
{
$dir = dirname(__DIR__) . '/'; $dir = dirname(__DIR__) . '/';
$prefixes = array('Main\\Foo', 'Main\\Bar'); $prefixes = array('Main\\Foo', 'Main\\Bar');
foreach ($prefixes as $prefix) { foreach ($prefixes as $prefix) {
@ -34,9 +46,8 @@ return call_user_func(function() {
return true; return true;
} }
}); }
}
}
$loader->register(); return ComposerAutoloaderInitTargetDir::getLoader();
return $loader;
});