Fix ClassLoader to be serializable (#11237)
* Fix ClassLoader to be serializable * Fix CI to use the source bin/composer as process for "composer" runs incl within simple-phpunit * Store the closure statically to avoid serialization issues in a cleaner waypull/11244/head
parent
7290f5b437
commit
cbb7c91223
|
@ -103,6 +103,21 @@ jobs:
|
||||||
- name: "Run install again using composer binary from source"
|
- name: "Run install again using composer binary from source"
|
||||||
run: "bin/composer install ${{ env.COMPOSER_FLAGS }}"
|
run: "bin/composer install ${{ env.COMPOSER_FLAGS }}"
|
||||||
|
|
||||||
|
- name: "Make source binary the one used by default (Linux / macOS)"
|
||||||
|
if: "!contains(matrix.os, 'windows')"
|
||||||
|
run: |
|
||||||
|
echo -e "$(pwd)/bin\n$(cat $GITHUB_PATH)" > $GITHUB_PATH
|
||||||
|
echo -e "COMPOSER_BINARY=$(pwd)/bin/composer" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: "Make source binary the one used by default (Windows)"
|
||||||
|
if: "contains(matrix.os, 'windows')"
|
||||||
|
run: |
|
||||||
|
$(
|
||||||
|
(echo "$(Get-Location)\bin")
|
||||||
|
(Get-Content $env:GITHUB_PATH -Raw)
|
||||||
|
) | Set-Content $env:GITHUB_PATH
|
||||||
|
echo "COMPOSER_BINARY=$(Get-Location)\bin\composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
|
||||||
- name: "Prepare git environment"
|
- name: "Prepare git environment"
|
||||||
run: "git config --global user.name composer && git config --global user.email composer@example.com"
|
run: "git config --global user.name composer && git config --global user.email composer@example.com"
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Composer\Autoload;
|
||||||
class ClassLoader
|
class ClassLoader
|
||||||
{
|
{
|
||||||
/** @var \Closure(string):void */
|
/** @var \Closure(string):void */
|
||||||
private $includeFile;
|
private static $includeFile;
|
||||||
|
|
||||||
/** @var ?string */
|
/** @var ?string */
|
||||||
private $vendorDir;
|
private $vendorDir;
|
||||||
|
@ -109,18 +109,7 @@ class ClassLoader
|
||||||
public function __construct($vendorDir = null)
|
public function __construct($vendorDir = null)
|
||||||
{
|
{
|
||||||
$this->vendorDir = $vendorDir;
|
$this->vendorDir = $vendorDir;
|
||||||
|
self::initializeIncludeClosure();
|
||||||
/**
|
|
||||||
* Scope isolated include.
|
|
||||||
*
|
|
||||||
* Prevents access to $this/self from included files.
|
|
||||||
*
|
|
||||||
* @param string $file
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
$this->includeFile = static function($file) {
|
|
||||||
include $file;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,7 +429,7 @@ class ClassLoader
|
||||||
public function loadClass($class)
|
public function loadClass($class)
|
||||||
{
|
{
|
||||||
if ($file = $this->findFile($class)) {
|
if ($file = $this->findFile($class)) {
|
||||||
($this->includeFile)($file);
|
(self::$includeFile)($file);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -570,4 +559,23 @@ class ClassLoader
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function initializeIncludeClosure(): void
|
||||||
|
{
|
||||||
|
if (self::$includeFile !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope isolated include.
|
||||||
|
*
|
||||||
|
* Prevents access to $this/self from included files.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
self::$includeFile = static function($file) {
|
||||||
|
include $file;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,4 +59,27 @@ class ClassLoaderTest extends TestCase
|
||||||
$loader = new ClassLoader();
|
$loader = new ClassLoader();
|
||||||
$this->assertEmpty($loader->getPrefixes());
|
$this->assertEmpty($loader->getPrefixes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSerializability(): void
|
||||||
|
{
|
||||||
|
$loader = new ClassLoader();
|
||||||
|
$loader->add('Pearlike_', __DIR__ . '/Fixtures');
|
||||||
|
$loader->add('', __DIR__ . '/FALLBACK');
|
||||||
|
$loader->addPsr4('ShinyVendor\\ShinyPackage\\', __DIR__ . '/Fixtures');
|
||||||
|
$loader->addPsr4('', __DIR__ . '/FALLBACKPSR4');
|
||||||
|
$loader->addClassMap(['A' => '', 'B' => 'path']);
|
||||||
|
$loader->setApcuPrefix('prefix');
|
||||||
|
$loader->setClassMapAuthoritative(true);
|
||||||
|
$loader->setUseIncludePath(true);
|
||||||
|
|
||||||
|
$loader2 = unserialize(serialize($loader));
|
||||||
|
self::assertInstanceOf(ClassLoader::class, $loader2);
|
||||||
|
self::assertSame($loader->getApcuPrefix(), $loader2->getApcuPrefix());
|
||||||
|
self::assertSame($loader->getClassMap(), $loader2->getClassMap());
|
||||||
|
self::assertSame($loader->getFallbackDirs(), $loader2->getFallbackDirs());
|
||||||
|
self::assertSame($loader->getFallbackDirsPsr4(), $loader2->getFallbackDirsPsr4());
|
||||||
|
self::assertSame($loader->getPrefixes(), $loader2->getPrefixes());
|
||||||
|
self::assertSame($loader->getPrefixesPsr4(), $loader2->getPrefixesPsr4());
|
||||||
|
self::assertSame($loader->getUseIncludePath(), $loader2->getUseIncludePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue