From d83ec37df2962e6eca3d0346a674f0175f3c7bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= <5175937+theofidry@users.noreply.github.com> Date: Sun, 7 Apr 2024 21:42:41 +0200 Subject: [PATCH] fix: Fix the autoloading of the excluded files (#1323) This fixes the integration of https://github.com/humbug/php-scoper/pull/864 within Box which was done in #1142. The issue was that the relative file paths was passed instead of hashes. Note that we create the file hasher in a different way than in PHP-Scoper, since PHP-Scoper has to deal with the vendor directory from the source and the scoped one, and deals with absolute paths. In Box however, this is not the case, we directly get relative file paths (relative to the working directory) --- src/Box.php | 2 +- src/Composer/AutoloadDumper.php | 34 +++++++++++++++++- src/Composer/ComposerOrchestrator.php | 16 +++++++-- tests/Composer/AutoloadDumperTest.php | 50 +++++++++++++++++---------- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/src/Box.php b/src/Box.php index f9e980e26..90bf57b6f 100644 --- a/src/Box.php +++ b/src/Box.php @@ -115,7 +115,7 @@ public function startBuffering(): void } /** - * @param callable(SymbolsRegistry, string): void $dumpAutoload + * @param callable(SymbolsRegistry, string, string[]): void $dumpAutoload */ public function endBuffering(?callable $dumpAutoload): void { diff --git a/src/Composer/AutoloadDumper.php b/src/Composer/AutoloadDumper.php index 6a4133c88..f96b951fc 100644 --- a/src/Composer/AutoloadDumper.php +++ b/src/Composer/AutoloadDumper.php @@ -14,6 +14,7 @@ namespace KevinGH\Box\Composer; +use Humbug\PhpScoper\Autoload\ComposerFileHasher; use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use KevinGH\Box\NotInstantiable; @@ -23,6 +24,7 @@ use function implode; use function preg_match; use function preg_replace; +use function sprintf; use function str_replace; use const PHP_EOL; @@ -30,15 +32,26 @@ final class AutoloadDumper { use NotInstantiable; + private const PACKAGE_PATH_REGEX = '~^%s/(?[^/]+?/[^/]+?)/(?.+?)$~'; + + /** + * @param string[] $excludedComposerAutoloadFiles + */ public static function generateAutoloadStatements( SymbolsRegistry $symbolsRegistry, - array $excludedComposerAutoloadFileHashes, + string $vendorDir, + array $excludedComposerAutoloadFiles, string $autoloadContents, ): string { if (0 === $symbolsRegistry->count()) { return $autoloadContents; } + $excludedComposerAutoloadFileHashes = self::getExcludedComposerAutoloadFileHashes( + $vendorDir, + $excludedComposerAutoloadFiles, + ); + $autoloadContents = self::extractInlinedAutoloadContents($autoloadContents); $scoperStatements = self::getOriginalScoperAutoloaderContents( $symbolsRegistry, @@ -59,6 +72,25 @@ public static function generateAutoloadStatements( return self::cleanupDuplicateLineReturns($mergedAutoloadContents); } + /** + * @param string[] $excludedComposerAutoloadFiles + */ + private static function getExcludedComposerAutoloadFileHashes( + string $vendorDir, + array $excludedComposerAutoloadFiles, + ): array { + $fileHashGenerator = new ComposerFileHasher( + '', + $excludedComposerAutoloadFiles, + sprintf( + self::PACKAGE_PATH_REGEX, + $vendorDir, + ), + ); + + return $fileHashGenerator->generateHashes(); + } + private static function extractInlinedAutoloadContents(string $autoloadContents): string { $autoloadContents = str_replace('dumpAutoloader(true === $excludeDevFiles); @@ -122,17 +127,22 @@ public function dumpAutoload( return; } - $autoloadFile = $this->getVendorDir().'/autoload.php'; + $vendorDir = $this->getVendorDir(); + $autoloadFile = $vendorDir.'/autoload.php'; $autoloadContents = AutoloadDumper::generateAutoloadStatements( $symbolsRegistry, - $excludedComposerAutoloadFileHashes, + $vendorDir, + $excludedComposerAutoloadFiles, $this->fileSystem->getFileContents($autoloadFile), ); $this->fileSystem->dumpFile($autoloadFile, $autoloadContents); } + /** + * @return string The vendor-dir directory path relative to its composer.json. + */ public function getVendorDir(): string { $vendorDirProcess = $this->processFactory->getVendorDirProcess(); diff --git a/tests/Composer/AutoloadDumperTest.php b/tests/Composer/AutoloadDumperTest.php index 11e100b7a..802ba8b58 100644 --- a/tests/Composer/AutoloadDumperTest.php +++ b/tests/Composer/AutoloadDumperTest.php @@ -19,6 +19,7 @@ use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; +use function md5; /** * @internal @@ -29,12 +30,14 @@ final class AutoloadDumperTest extends TestCase #[DataProvider('autoloadProvider')] public function test_it_can_generate_the_autoload( SymbolsRegistry $symbolsRegistry, + string $vendorDir, array $excludedComposerAutoloadFileHashes, string $autoloadContents, string $expected, ): void { $actual = AutoloadDumper::generateAutoloadStatements( $symbolsRegistry, + $vendorDir, $excludedComposerAutoloadFileHashes, $autoloadContents, ); @@ -44,8 +47,16 @@ public function test_it_can_generate_the_autoload( public static function autoloadProvider(): iterable { + $defaultVendorDir = 'vendor'; + + $excludedFile1 = 'vendor/phpstorm/stubs/stub1.php'; + $excludedFile1Hash = md5('phpstorm/stubs:stub1.php'); + $excludedFile2 = 'vendor/phpstorm/stubs/stub2.php'; + $excludedFile2Hash = md5('phpstorm/stubs:stub2.php'); + yield 'no symbols' => [ new SymbolsRegistry(), + $defaultVendorDir, [], <<<'PHP'