diff --git a/src/Box.php b/src/Box.php index 96e5e9143..232c8f105 100644 --- a/src/Box.php +++ b/src/Box.php @@ -113,7 +113,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..651a16f00 100644 --- a/src/Composer/AutoloadDumper.php +++ b/src/Composer/AutoloadDumper.php @@ -14,15 +14,18 @@ namespace KevinGH\Box\Composer; +use Humbug\PhpScoper\Autoload\ComposerFileHasher; use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use KevinGH\Box\NotInstantiable; use UnexpectedValueException; +use function array_column; use function array_map; use function explode; use function implode; use function preg_match; use function preg_replace; +use function sprintf; use function str_replace; use const PHP_EOL; @@ -30,15 +33,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 +73,26 @@ 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 +131,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();