Skip to content

Commit

Permalink
Draft: fix: Fix the autoloading of the excluded files
Browse files Browse the repository at this point in the history
This fixes the integration of
humbug/php-scoper#864 within Box which was done
in box-project#1142.
  • Loading branch information
theofidry committed Mar 8, 2024
1 parent e7daf0f commit 13abce2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Box.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
36 changes: 35 additions & 1 deletion src/Composer/AutoloadDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,45 @@

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;

final class AutoloadDumper
{
use NotInstantiable;

private const PACKAGE_PATH_REGEX = '~^%s/(?<vendor>[^/]+?/[^/]+?)/(?<path>.+?)$~';

/**
* @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,
Expand All @@ -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('<?php', '', $autoloadContents);
Expand Down
20 changes: 17 additions & 3 deletions src/Composer/ComposerOrchestrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,43 @@ public function checkVersion(): void
}
}

/**
* @param SymbolsRegistry $symbolsRegistry
* @param string $prefix
* @param bool $excludeDevFiles
* @param string[] $excludedComposerAutoloadFiles Relative paths of the files that were not scoped hence which need
* to be configured as loaded to Composer as otherwise they would be
* autoloaded twice.
* @return void
*/
public function dumpAutoload(
SymbolsRegistry $symbolsRegistry,
string $prefix,
bool $excludeDevFiles,
array $excludedComposerAutoloadFileHashes,
array $excludedComposerAutoloadFiles,
): void {
$this->dumpAutoloader(true === $excludeDevFiles);

if ('' === $prefix) {
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();
Expand Down

0 comments on commit 13abce2

Please sign in to comment.