From a2b647a99eb92e123b7e36ab135baeb7b219207a Mon Sep 17 00:00:00 2001 From: ShiraNai7 Date: Thu, 11 Apr 2019 20:23:31 +0200 Subject: [PATCH] Handle absolute phar:// paths in autoload_static.php --- src/Composer/Autoload/AutoloadGenerator.php | 18 +++- .../Test/Autoload/AutoloadGeneratorTest.php | 41 +++++++++ .../Test/Autoload/Fixtures/autoload_phar.php | 13 +++ .../Autoload/Fixtures/autoload_phar_psr4.php | 13 +++ .../Fixtures/autoload_phar_static.php | 87 +++++++++++++++++++ 5 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_phar.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_phar_psr4.php create mode 100644 tests/Composer/Test/Autoload/Fixtures/autoload_phar_static.php diff --git a/src/Composer/Autoload/AutoloadGenerator.php b/src/Composer/Autoload/AutoloadGenerator.php index 7ea1a3444..4d04f7a2f 100644 --- a/src/Composer/Autoload/AutoloadGenerator.php +++ b/src/Composer/Autoload/AutoloadGenerator.php @@ -545,7 +545,7 @@ EOF; } } - if (preg_match('/\.phar.+$/', $path)) { + if (strpos($path, '.phar') !== false) { $baseDir = "'phar://' . " . $baseDir; } @@ -769,10 +769,14 @@ HEADER; $filesystem = new Filesystem(); $vendorPathCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true, true) . " . '/"; + $vendorPharPathCode = ' => \'phar://\' . ' . $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true, true) . " . '/"; $appBaseDirCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $basePath, true, true) . " . '/"; + $appBaseDirPharCode = ' => \'phar://\' . ' . $filesystem->findShortestPathCode(realpath($targetDir), $basePath, true, true) . " . '/"; $absoluteVendorPathCode = ' => ' . substr(var_export(rtrim($vendorDir, '\\/') . '/', true), 0, -1); + $absoluteVendorPharPathCode = ' => ' . substr(var_export(rtrim('phar://' . $vendorDir, '\\/') . '/', true), 0, -1); $absoluteAppBaseDirCode = ' => ' . substr(var_export(rtrim($baseDir, '\\/') . '/', true), 0, -1); + $absoluteAppBaseDirPharCode = ' => ' . substr(var_export(rtrim('phar://' . $baseDir, '\\/') . '/', true), 0, -1); $initializer = ''; $prefix = "\0Composer\Autoload\ClassLoader\0"; @@ -795,9 +799,15 @@ HEADER; // See https://bugs.php.net/68057 $staticPhpVersion = 70000; } - $value = var_export($value, true); - $value = str_replace($absoluteVendorPathCode, $vendorPathCode, $value); - $value = str_replace($absoluteAppBaseDirCode, $appBaseDirCode, $value); + $value = strtr( + var_export($value, true), + array( + $absoluteVendorPathCode => $vendorPathCode, + $absoluteVendorPharPathCode => $vendorPharPathCode, + $absoluteAppBaseDirCode => $appBaseDirCode, + $absoluteAppBaseDirPharCode => $appBaseDirPharCode, + ) + ); $value = ltrim(preg_replace('/^ */m', ' $0$0', $value)); $file .= sprintf(" public static $%s = %s;\n\n", $prop, $value); diff --git a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php index c1605bf97..84ac16df7 100644 --- a/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php +++ b/tests/Composer/Test/Autoload/AutoloadGeneratorTest.php @@ -486,6 +486,47 @@ class AutoloadGeneratorTest extends TestCase $this->assertFileExists($this->vendorDir.'/composer/autoload_classmap.php', "ClassMap file needs to be generated, even if empty."); } + public function testPharAutoload() + { + $package = new Package('a', '1.0', '1.0'); + $package->setRequires(array( + new Link('a', 'a/a'), + )); + + $package->setAutoload(array( + 'psr-0' => array( + 'Foo' => 'foo.phar', + 'Bar' => 'dir/bar.phar/src', + ), + 'psr-4' => array( + 'Baz\\' => 'baz.phar', + 'Qux\\' => 'dir/qux.phar/src', + ), + )); + + $vendorPackage = new Package('a/a', '1.0', '1.0'); + $vendorPackage->setAutoload(array( + 'psr-0' => array( + 'Lorem' => 'lorem.phar', + 'Ipsum' => 'dir/ipsum.phar/src', + ), + 'psr-4' => array( + 'Dolor\\' => 'dolor.phar', + 'Sit\\' => 'dir/sit.phar/src', + ), + )); + + $this->repository->expects($this->once()) + ->method('getCanonicalPackages') + ->will($this->returnValue(array($vendorPackage))); + + $this->generator->dump($this->config, $this->repository, $package, $this->im, 'composer', true, 'Phar'); + + $this->assertAutoloadFiles('phar', $this->vendorDir . '/composer'); + $this->assertAutoloadFiles('phar_psr4', $this->vendorDir . '/composer', 'psr4'); + $this->assertAutoloadFiles('phar_static', $this->vendorDir . '/composer', 'static'); + } + public function testPSRToClassMapIgnoresNonExistingDir() { $package = new Package('a', '1.0', '1.0'); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_phar.php b/tests/Composer/Test/Autoload/Fixtures/autoload_phar.php new file mode 100644 index 000000000..7654005f3 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_phar.php @@ -0,0 +1,13 @@ + array('phar://' . $vendorDir . '/a/a/lorem.phar'), + 'Ipsum' => array('phar://' . $vendorDir . '/a/a/dir/ipsum.phar/src'), + 'Foo' => array('phar://' . $baseDir . '/foo.phar'), + 'Bar' => array('phar://' . $baseDir . '/dir/bar.phar/src'), +); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_phar_psr4.php b/tests/Composer/Test/Autoload/Fixtures/autoload_phar_psr4.php new file mode 100644 index 000000000..f6142a001 --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_phar_psr4.php @@ -0,0 +1,13 @@ + array('phar://' . $vendorDir . '/a/a/dir/sit.phar/src'), + 'Qux\\' => array('phar://' . $baseDir . '/dir/qux.phar/src'), + 'Dolor\\' => array('phar://' . $vendorDir . '/a/a/dolor.phar'), + 'Baz\\' => array('phar://' . $baseDir . '/baz.phar'), +); diff --git a/tests/Composer/Test/Autoload/Fixtures/autoload_phar_static.php b/tests/Composer/Test/Autoload/Fixtures/autoload_phar_static.php new file mode 100644 index 000000000..486a5c0dc --- /dev/null +++ b/tests/Composer/Test/Autoload/Fixtures/autoload_phar_static.php @@ -0,0 +1,87 @@ + + array ( + 'Sit\\' => 4, + ), + 'Q' => + array ( + 'Qux\\' => 4, + ), + 'D' => + array ( + 'Dolor\\' => 6, + ), + 'B' => + array ( + 'Baz\\' => 4, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Sit\\' => + array ( + 0 => 'phar://' . __DIR__ . '/..' . '/a/a/dir/sit.phar/src', + ), + 'Qux\\' => + array ( + 0 => 'phar://' . __DIR__ . '/../..' . '/dir/qux.phar/src', + ), + 'Dolor\\' => + array ( + 0 => 'phar://' . __DIR__ . '/..' . '/a/a/dolor.phar', + ), + 'Baz\\' => + array ( + 0 => 'phar://' . __DIR__ . '/../..' . '/baz.phar', + ), + ); + + public static $prefixesPsr0 = array ( + 'L' => + array ( + 'Lorem' => + array ( + 0 => 'phar://' . __DIR__ . '/..' . '/a/a/lorem.phar', + ), + ), + 'I' => + array ( + 'Ipsum' => + array ( + 0 => 'phar://' . __DIR__ . '/..' . '/a/a/dir/ipsum.phar/src', + ), + ), + 'F' => + array ( + 'Foo' => + array ( + 0 => 'phar://' . __DIR__ . '/../..' . '/foo.phar', + ), + ), + 'B' => + array ( + 'Bar' => + array ( + 0 => 'phar://' . __DIR__ . '/../..' . '/dir/bar.phar/src', + ), + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitPhar::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitPhar::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitPhar::$prefixesPsr0; + + }, null, ClassLoader::class); + } +}