From 9386a0af946f175d7a1ebfb68851bc2bb8ad7858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= <5175937+theofidry@users.noreply.github.com> Date: Sat, 4 Nov 2023 19:01:12 +0100 Subject: [PATCH] chore: Update to Box 4.5.1 (#893) --- composer.json | 2 +- composer.lock | 16 +- vendor-hotfix/AutoloadDumper.php | 119 --- vendor-hotfix/Box.php | 454 ------------ vendor-hotfix/Compile.php | 961 ------------------------- vendor-hotfix/ComposerOrchestrator.php | 186 ----- vendor-hotfix/NullScoper.php | 53 -- vendor-hotfix/Scoper.php | 38 - vendor-hotfix/SerializableScoper.php | 122 ---- 9 files changed, 9 insertions(+), 1942 deletions(-) delete mode 100644 vendor-hotfix/AutoloadDumper.php delete mode 100644 vendor-hotfix/Box.php delete mode 100644 vendor-hotfix/Compile.php delete mode 100644 vendor-hotfix/ComposerOrchestrator.php delete mode 100644 vendor-hotfix/NullScoper.php delete mode 100644 vendor-hotfix/Scoper.php delete mode 100644 vendor-hotfix/SerializableScoper.php diff --git a/composer.json b/composer.json index 2b332a59a..b335abd4c 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "bamarni/composer-bin-plugin": "^1.1", "ergebnis/composer-normalize": "^2.28", "fidry/makefile": "^1.0", - "humbug/box": "^4.0", + "humbug/box": "^4.5.1", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.0", "symfony/yaml": "^6.1" diff --git a/composer.lock b/composer.lock index f384b609d..f8a78631c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "35dc665bd46fe47bbeb62261834626b9", + "content-hash": "23f592be2a5824006d8de3026549f1f6", "packages": [ { "name": "fidry/console", @@ -2845,16 +2845,16 @@ }, { "name": "humbug/box", - "version": "4.5.0", + "version": "4.5.1", "source": { "type": "git", "url": "https://github.com/box-project/box.git", - "reference": "54142dda6840781f3f2d850f109f330b6221a6cb" + "reference": "1e10a1e974a831b64dab801d09dffa6acd43bd7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/box-project/box/zipball/54142dda6840781f3f2d850f109f330b6221a6cb", - "reference": "54142dda6840781f3f2d850f109f330b6221a6cb", + "url": "https://api.github.com/repos/box-project/box/zipball/1e10a1e974a831b64dab801d09dffa6acd43bd7f", + "reference": "1e10a1e974a831b64dab801d09dffa6acd43bd7f", "shasum": "" }, "require": { @@ -2868,7 +2868,7 @@ "ext-sodium": "*", "fidry/console": "^0.5.3 || ^0.6.0", "fidry/filesystem": "^1.1", - "humbug/php-scoper": "^0.18.3", + "humbug/php-scoper": "^0.18.6", "justinrainbow/json-schema": "^5.2.12", "laravel/serializable-closure": "^1.2.2", "nikic/iter": "^2.2", @@ -2956,9 +2956,9 @@ ], "support": { "issues": "https://github.com/box-project/box/issues", - "source": "https://github.com/box-project/box/tree/4.5.0" + "source": "https://github.com/box-project/box/tree/4.5.1" }, - "time": "2023-10-22T17:09:51+00:00" + "time": "2023-11-04T17:51:11+00:00" }, { "name": "justinrainbow/json-schema", diff --git a/vendor-hotfix/AutoloadDumper.php b/vendor-hotfix/AutoloadDumper.php deleted file mode 100644 index ba0d039c7..000000000 --- a/vendor-hotfix/AutoloadDumper.php +++ /dev/null @@ -1,119 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\Composer; - -use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use KevinGH\Box\NotInstantiable; -use UnexpectedValueException; -use function array_map; -use function explode; -use function implode; -use function preg_replace; -use function preg_match; -use function str_replace; -use const PHP_EOL; - -final class AutoloadDumper -{ - use NotInstantiable; - - public static function generateAutoloadStatements( - SymbolsRegistry $symbolsRegistry, - array $excludedComposerAutoloadFileHashes, - string $autoloadContents, - ): string { - if (0 === $symbolsRegistry->count()) { - return $autoloadContents; - } - - $autoloadContents = self::extractInlinedAutoloadContents($autoloadContents); - $scoperStatements = self::getOriginalScoperAutoloaderContents( - $symbolsRegistry, - $excludedComposerAutoloadFileHashes, - ); - - $indentedAutoloadContents = self::fixInlinedAutoloadIndent( - $autoloadContents, - self::getLoaderStatementIndent($scoperStatements), - ); - - $mergedAutoloadContents = preg_replace( - '/(\s*\\$loader \= .*autoload\.php.*)/', - $indentedAutoloadContents, - $scoperStatements, - ); - - return self::cleanupDuplicateLineReturns($mergedAutoloadContents); - } - - private static function extractInlinedAutoloadContents(string $autoloadContents): string - { - $autoloadContents = str_replace('dump(); - - return preg_replace( - '/scoper\-autoload\.php \@generated by PhpScoper/', - '@generated by Humbug Box', - $scoperStatements, - ); - } - - private static function getLoaderStatementIndent(string $scoperStatements): string - { - if (1 !== preg_match('/(? *)\\$loader \= .*autoload\.php.*/', $scoperStatements, $matches)) { - throw new UnexpectedValueException('Could not process the scoper autoloader statements'); - } - - return $matches['indent']; - } - - private static function fixInlinedAutoloadIndent(string $autoloadContents, string $indent): string - { - $lines = explode(PHP_EOL, $autoloadContents); - - $indentedLines = array_map( - static fn (string $line) => '' === $line ? $line : $indent.$line, - $lines, - ); - - return implode(PHP_EOL, $indentedLines); - } - - private static function cleanupDuplicateLineReturns(string $value): string - { - return preg_replace( - '/\n{2,}/m', - PHP_EOL.PHP_EOL, - $value, - ); - } -} diff --git a/vendor-hotfix/Box.php b/vendor-hotfix/Box.php deleted file mode 100644 index 710466bf1..000000000 --- a/vendor-hotfix/Box.php +++ /dev/null @@ -1,454 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box; - -use Amp\MultiReasonException; -use BadMethodCallException; -use Countable; -use Fidry\FileSystem\FS; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use KevinGH\Box\Compactor\Compactors; -use KevinGH\Box\Compactor\PhpScoper; -use KevinGH\Box\Compactor\Placeholder; -use KevinGH\Box\Phar\CompressionAlgorithm; -use KevinGH\Box\PhpScoper\NullScoper; -use KevinGH\Box\PhpScoper\Scoper; -use Phar; -use RecursiveDirectoryIterator; -use RuntimeException; -use SplFileInfo; -use Webmozart\Assert\Assert; -use function Amp\ParallelFunctions\parallelMap; -use function Amp\Promise\wait; -use function array_filter; -use function array_map; -use function array_unshift; -use function chdir; -use function dirname; -use function extension_loaded; -use function file_exists; -use function getcwd; -use function is_object; -use function openssl_pkey_export; -use function openssl_pkey_get_details; -use function openssl_pkey_get_private; -use function sprintf; - -/** - * Box is a utility class to generate a PHAR. - * - * @private - */ -final class Box implements Countable -{ - private Compactors $compactors; - private Placeholder $placeholderCompactor; - private MapFile $mapFile; - private Scoper $scoper; - private bool $buffering = false; - - /** - * @var array Relative file path as key and file contents as value - */ - private array $bufferedFiles = []; - - private function __construct( - private readonly Phar $phar, - private readonly string $pharFilePath, - ) { - $this->compactors = new Compactors(); - $this->placeholderCompactor = new Placeholder([]); - $this->mapFile = new MapFile(getcwd(), []); - $this->scoper = new NullScoper(); - } - - /** - * Creates a new PHAR and Box instance. - * - * @param string $pharFilePath The PHAR file name - * @param int $pharFlags Flags to pass to the Phar parent class RecursiveDirectoryIterator - * @param string $pharAlias Alias with which the Phar archive should be referred to in calls to stream functionality - * - * @see RecursiveDirectoryIterator - */ - public static function create(string $pharFilePath, int $pharFlags = 0, ?string $pharAlias = null): self - { - // Ensure the parent directory of the PHAR file exists as `new \Phar()` does not create it and would fail - // otherwise. - FS::mkdir(dirname($pharFilePath)); - - return new self( - new Phar($pharFilePath, $pharFlags, $pharAlias), - $pharFilePath, - ); - } - - public function startBuffering(): void - { - Assert::false($this->buffering, 'The buffering must be ended before starting it again'); - - $this->buffering = true; - - $this->phar->startBuffering(); - } - - /** - * @param callable(SymbolsRegistry, string): void $dumpAutoload - */ - public function endBuffering(?callable $dumpAutoload): void - { - Assert::true($this->buffering, 'The buffering must be started before ending it'); - - $dumpAutoload ??= static fn () => null; - $cwd = getcwd(); - - $tmp = FS::makeTmpDir('box', self::class); - chdir($tmp); - - if ([] === $this->bufferedFiles) { - $this->bufferedFiles = [ - '.box_empty' => 'A PHAR cannot be empty so Box adds this file to ensure the PHAR is created still.', - ]; - } - - try { - foreach ($this->bufferedFiles as $file => $contents) { - FS::dumpFile($file, $contents); - } - - if (null !== $dumpAutoload) { - $dumpAutoload( - $this->scoper->getSymbolsRegistry(), - $this->scoper->getPrefix(), - $this->scoper->getExcludedFilePaths(), - ); - } - - chdir($cwd); - - $this->phar->buildFromDirectory($tmp); - } finally { - FS::remove($tmp); - } - - $this->buffering = false; - - $this->phar->stopBuffering(); - } - - /** - * @param non-empty-string $normalizedVendorDir Normalized path ("/" path separator and no trailing "/") to the Composer vendor directory - */ - public function removeComposerArtefacts(string $normalizedVendorDir): void - { - Assert::false($this->buffering, 'The buffering must have ended before removing the Composer artefacts'); - - $composerFiles = [ - 'composer.json', - 'composer.lock', - $normalizedVendorDir.'/composer/installed.json', - ]; - - $this->phar->startBuffering(); - - foreach ($composerFiles as $composerFile) { - $localComposerFile = ($this->mapFile)($composerFile); - - $pharFilePath = sprintf( - 'phar://%s/%s', - $this->phar->getPath(), - $localComposerFile, - ); - - if (file_exists($pharFilePath)) { - $this->phar->delete($localComposerFile); - } - } - - $this->phar->stopBuffering(); - } - - public function compress(CompressionAlgorithm $compressionAlgorithm): ?string - { - Assert::false($this->buffering, 'Cannot compress files while buffering.'); - - $extensionRequired = $compressionAlgorithm->getRequiredExtension(); - - if (null !== $extensionRequired && false === extension_loaded($extensionRequired)) { - throw new RuntimeException( - sprintf( - 'Cannot compress the PHAR with the compression algorithm "%s": the extension "%s" is required but appear to not be loaded', - $compressionAlgorithm->name, - $extensionRequired, - ), - ); - } - - try { - if (CompressionAlgorithm::NONE === $compressionAlgorithm) { - $this->getPhar()->decompressFiles(); - } else { - $this->phar->compressFiles($compressionAlgorithm->value); - } - } catch (BadMethodCallException $exception) { - $exceptionMessage = 'unable to create temporary file' !== $exception->getMessage() - ? 'Could not compress the PHAR: '.$exception->getMessage() - : sprintf( - 'Could not compress the PHAR: the compression requires too many file descriptors to be opened (%s). Check your system limits or install the posix extension to allow Box to automatically configure it during the compression', - $this->phar->count(), - ); - - throw new RuntimeException($exceptionMessage, $exception->getCode(), $exception); - } - - return $extensionRequired; - } - - public function registerCompactors(Compactors $compactors): void - { - $compactorsArray = $compactors->toArray(); - - foreach ($compactorsArray as $index => $compactor) { - if ($compactor instanceof PhpScoper) { - $this->scoper = $compactor->getScoper(); - - continue; - } - - if ($compactor instanceof Placeholder) { - // Removes the known Placeholder compactors in favour of the Box one - unset($compactorsArray[$index]); - } - } - - array_unshift($compactorsArray, $this->placeholderCompactor); - - $this->compactors = new Compactors(...$compactorsArray); - } - - /** - * @param scalar[] $placeholders - */ - public function registerPlaceholders(array $placeholders): void - { - $message = 'Expected value "%s" to be a scalar or stringable object.'; - - foreach ($placeholders as $index => $placeholder) { - if (is_object($placeholder)) { - Assert::methodExists($placeholder, '__toString', $message); - - $placeholders[$index] = (string) $placeholder; - - break; - } - - Assert::scalar($placeholder, $message); - } - - $this->placeholderCompactor = new Placeholder($placeholders); - - $this->registerCompactors($this->compactors); - } - - public function registerFileMapping(MapFile $fileMapper): void - { - $this->mapFile = $fileMapper; - } - - public function registerStub(string $file): void - { - $contents = $this->placeholderCompactor->compact( - $file, - FS::getFileContents($file), - ); - - $this->phar->setStub($contents); - } - - /** - * @param array $files - * - * @throws MultiReasonException - */ - public function addFiles(array $files, bool $binary): void - { - Assert::true($this->buffering, 'Cannot add files if the buffering has not started.'); - - $files = array_map('strval', $files); - - if ($binary) { - foreach ($files as $file) { - $this->addFile($file, null, true); - } - - return; - } - - foreach ($this->processContents($files) as [$file, $contents]) { - $this->bufferedFiles[$file] = $contents; - } - } - - /** - * Adds the a file to the PHAR. The contents will first be compacted and have its placeholders - * replaced. - * - * @param null|string $contents If null the content of the file will be used - * @param bool $binary When true means the file content shouldn't be processed - * - * @return string File local path - */ - public function addFile(string $file, ?string $contents = null, bool $binary = false): string - { - Assert::true($this->buffering, 'Cannot add files if the buffering has not started.'); - - if (null === $contents) { - $contents = FS::getFileContents($file); - } - - $local = ($this->mapFile)($file); - - $this->bufferedFiles[$local] = $binary ? $contents : $this->compactors->compact($local, $contents); - - return $local; - } - - public function getPhar(): Phar - { - return $this->phar; - } - - /** - * Signs the PHAR using a private key file. - * - * @param string $file the private key file name - * @param null|string $password the private key password - */ - public function signUsingFile(string $file, ?string $password = null): void - { - $this->sign(FS::getFileContents($file), $password); - } - - /** - * Signs the PHAR using a private key. - * - * @param string $key The private key - * @param null|string $password The private key password - */ - public function sign(string $key, ?string $password): void - { - $pubKey = $this->pharFilePath.'.pubkey'; - - Assert::writable(dirname($pubKey)); - Assert::true(extension_loaded('openssl')); - - if (file_exists($pubKey)) { - Assert::file( - $pubKey, - 'Cannot create public key: %s already exists and is not a file.', - ); - } - - $resource = openssl_pkey_get_private($key, (string) $password); - - Assert::notSame(false, $resource, 'Could not retrieve the private key, check that the password is correct.'); - - openssl_pkey_export($resource, $private); - - $details = openssl_pkey_get_details($resource); - - $this->phar->setSignatureAlgorithm(Phar::OPENSSL, $private); - - FS::dumpFile($pubKey, $details['key']); - } - - /** - * @param string[] $files - * - * @throws MultiReasonException - * - * @return array array of tuples where the first element is the local file path (path inside the PHAR) and the - * second element is the processed contents - */ - private function processContents(array $files): array - { - $mapFile = $this->mapFile; - $compactors = $this->compactors; - $cwd = getcwd(); - - $processFile = static function (string $file) use ($cwd, $mapFile, $compactors): array { - chdir($cwd); - - // Keep the fully qualified call here since this function may be executed without the right autoloading - // mechanism - \KevinGH\Box\register_aliases(); - if (true === \KevinGH\Box\is_parallel_processing_enabled()) { - \KevinGH\Box\register_error_handler(); - } - - $contents = \Fidry\FileSystem\FS::getFileContents($file); - - $local = $mapFile($file); - - $processedContents = $compactors->compact($local, $contents); - - return [$local, $processedContents, $compactors->getScoperSymbolsRegistry()]; - }; - - if ($this->scoper instanceof NullScoper || false === is_parallel_processing_enabled()) { - return array_map($processFile, $files); - } - - // In the case of parallel processing, an issue is caused due to the statefulness nature of the PhpScoper - // symbols registry. - // - // Indeed, the PhpScoper symbols registry stores the records of exposed/excluded classes and functions. If nothing is done, - // then the symbols registry retrieved in the end will here will be "blank" since the updated symbols registries are the ones - // from the workers used for the parallel processing. - // - // In order to avoid that, the symbols registries will be returned as a result as well in order to be able to merge - // all the symbols registries into one. - // - // This process is allowed thanks to the nature of the state of the symbols registries: having redundant classes or - // functions registered can easily be deal with so merging all those different states is actually - // straightforward. - $tuples = wait(parallelMap($files, $processFile)); - - if ([] === $tuples) { - return []; - } - - $filesWithContents = []; - $symbolRegistries = []; - - foreach ($tuples as [$local, $processedContents, $symbolRegistry]) { - $filesWithContents[] = [$local, $processedContents]; - $symbolRegistries[] = $symbolRegistry; - } - - $this->compactors->registerSymbolsRegistry( - SymbolsRegistry::createFromRegistries(array_filter($symbolRegistries)), - ); - - return $filesWithContents; - } - - public function count(): int - { - Assert::false($this->buffering, 'Cannot count the number of files in the PHAR when buffering'); - - return $this->phar->count(); - } -} diff --git a/vendor-hotfix/Compile.php b/vendor-hotfix/Compile.php deleted file mode 100644 index 7a0f9e9e8..000000000 --- a/vendor-hotfix/Compile.php +++ /dev/null @@ -1,961 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\Console\Command; - -use Amp\MultiReasonException; -use Fidry\Console\Command\Command; -use Fidry\Console\Command\CommandAware; -use Fidry\Console\Command\CommandAwareness; -use Fidry\Console\Command\Configuration as CommandConfiguration; -use Fidry\Console\ExitCode; -use Fidry\Console\Input\IO; -use Fidry\FileSystem\FileSystem; -use Fidry\FileSystem\FS; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use KevinGH\Box\Amp\FailureCollector; -use KevinGH\Box\Box; -use KevinGH\Box\Compactor\Compactor; -use KevinGH\Box\Composer\CompilerPsrLogger; -use KevinGH\Box\Composer\ComposerConfiguration; -use KevinGH\Box\Composer\ComposerOrchestrator; -use KevinGH\Box\Composer\ComposerProcessFactory; -use KevinGH\Box\Composer\IncompatibleComposerVersion; -use KevinGH\Box\Configuration\Configuration; -use KevinGH\Box\Console\Logger\CompilerLogger; -use KevinGH\Box\Console\MessageRenderer; -use KevinGH\Box\MapFile; -use KevinGH\Box\Phar\CompressionAlgorithm; -use KevinGH\Box\RequirementChecker\DecodedComposerJson; -use KevinGH\Box\RequirementChecker\DecodedComposerLock; -use KevinGH\Box\RequirementChecker\RequirementsDumper; -use KevinGH\Box\StubGenerator; -use RuntimeException; -use stdClass; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Input\StringInput; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Question\Question; -use Symfony\Component\Filesystem\Path; -use Webmozart\Assert\Assert; -use function array_map; -use function array_shift; -use function count; -use function decoct; -use function explode; -use function file_exists; -use function filesize; -use function implode; -use function is_callable; -use function is_string; -use function KevinGH\Box\bump_open_file_descriptor_limit; -use function KevinGH\Box\check_php_settings; -use function KevinGH\Box\disable_parallel_processing; -use function KevinGH\Box\format_size; -use function KevinGH\Box\format_time; -use function memory_get_peak_usage; -use function memory_get_usage; -use function microtime; -use function putenv; -use function Safe\getcwd; -use function sprintf; -use function var_export; -use const KevinGH\Box\BOX_ALLOW_XDEBUG; -use const PHP_EOL; - -/** - * @private - */ -final class Compile implements CommandAware -{ - use CommandAwareness; - - public const NAME = 'compile'; - - private const HELP = <<<'HELP' - The %command.name% command will compile code in a new PHAR based on a variety of settings. - - This command relies on a configuration file for loading - PHAR packaging settings. If a configuration file is not - specified through the --config|-c option, one of - the following files will be used (in order): box.json, - box.json.dist - - The configuration file is actually a JSON object saved to a file. For more - information check the documentation online: - - https://github.com/humbug/box - - HELP; - - private const DEBUG_OPTION = 'debug'; - private const NO_PARALLEL_PROCESSING_OPTION = 'no-parallel'; - private const NO_RESTART_OPTION = 'no-restart'; - private const DEV_OPTION = 'dev'; - private const NO_CONFIG_OPTION = 'no-config'; - private const WITH_DOCKER_OPTION = 'with-docker'; - private const COMPOSER_BIN_OPTION = 'composer-bin'; - private const ALLOW_COMPOSER_COMPOSER_CHECK_FAILURE_OPTION = 'allow-composer-check-failure'; - - private const DEBUG_DIR = '.box_dump'; - - public function __construct(private string $header) - { - } - - public function getConfiguration(): CommandConfiguration - { - return new CommandConfiguration( - self::NAME, - '🔨 Compiles an application into a PHAR', - self::HELP, - [], - [ - new InputOption( - self::DEBUG_OPTION, - null, - InputOption::VALUE_NONE, - 'Dump the files added to the PHAR in a `'.self::DEBUG_DIR.'` directory', - ), - new InputOption( - self::NO_PARALLEL_PROCESSING_OPTION, - null, - InputOption::VALUE_NONE, - 'Disable the parallel processing', - ), - new InputOption( - self::NO_RESTART_OPTION, - null, - InputOption::VALUE_NONE, - 'Do not restart the PHP process. Box restarts the process by default to disable xdebug and set `phar.readonly=0`', - ), - new InputOption( - self::DEV_OPTION, - null, - InputOption::VALUE_NONE, - 'Skips the compression step', - ), - new InputOption( - self::NO_CONFIG_OPTION, - null, - InputOption::VALUE_NONE, - 'Ignore the config file even when one is specified with the --config option', - ), - new InputOption( - self::WITH_DOCKER_OPTION, - null, - InputOption::VALUE_NONE, - 'Generates a Dockerfile', - ), - new InputOption( - self::COMPOSER_BIN_OPTION, - null, - InputOption::VALUE_REQUIRED, - 'Composer binary to use', - ), - new InputOption( - self::ALLOW_COMPOSER_COMPOSER_CHECK_FAILURE_OPTION, - null, - InputOption::VALUE_NONE, - 'To continue even if an unsupported Composer version is detected', - ), - ConfigOption::getOptionInput(), - ChangeWorkingDirOption::getOptionInput(), - ], - ); - } - - public function execute(IO $io): int - { - if ($io->getOption(self::NO_RESTART_OPTION)->asBoolean()) { - putenv(BOX_ALLOW_XDEBUG.'=1'); - } - - $debug = $io->getOption(self::DEBUG_OPTION)->asBoolean(); - - if ($debug) { - $io->setVerbosity(OutputInterface::VERBOSITY_DEBUG); - } - - check_php_settings($io); - - if ($io->getOption(self::NO_PARALLEL_PROCESSING_OPTION)->asBoolean()) { - disable_parallel_processing(); - $io->writeln( - '[debug] Disabled parallel processing', - OutputInterface::VERBOSITY_DEBUG, - ); - } - - ChangeWorkingDirOption::changeWorkingDirectory($io); - - $io->writeln($this->header); - - $config = $io->getOption(self::NO_CONFIG_OPTION)->asBoolean() - ? Configuration::create(null, new stdClass()) - : ConfigOption::getConfig($io, true); - $config->setComposerBin(self::getComposerBin($io)); - $path = $config->getOutputPath(); - - $logger = new CompilerLogger($io); - - $startTime = microtime(true); - - $logger->logStartBuilding($path); - - $this->removeExistingArtifacts($config, $logger, $debug); - - // Adding files might result in opening a lot of files. Either because not parallelized or when creating the - // workers for parallelization. - // As a result, we bump the file descriptor to an arbitrary number to ensure this process can run correctly - $restoreLimit = bump_open_file_descriptor_limit(2048, $io); - - try { - $box = $this->createPhar($config, $logger, $io, $debug); - } finally { - $restoreLimit(); - } - - self::correctPermissions($path, $config, $logger); - - self::logEndBuilding($config, $logger, $io, $box, $path, $startTime); - - if ($io->getOption(self::WITH_DOCKER_OPTION)->asBoolean()) { - return $this->generateDockerFile($io); - } - - return ExitCode::SUCCESS; - } - - private function createPhar( - Configuration $config, - CompilerLogger $logger, - IO $io, - bool $debug, - ): Box { - $box = Box::create($config->getTmpOutputPath()); - $composerOrchestrator = new ComposerOrchestrator( - ComposerProcessFactory::create( - $config->getComposerBin(), - $io, - ), - new CompilerPsrLogger($logger), - new FileSystem(), - ); - - self::checkComposerVersion($composerOrchestrator, $config, $logger, $io); - - $box->startBuffering(); - - self::registerReplacementValues($config, $box, $logger); - self::registerCompactors($config, $box, $logger); - self::registerFileMapping($config, $box, $logger); - - // Registering the main script _before_ adding the rest if of the files is _very_ important. The temporary - // file used for debugging purposes and the Composer dump autoloading will not work correctly otherwise. - $main = self::registerMainScript($config, $box, $logger); - - $check = self::registerRequirementsChecker($config, $box, $logger); - - self::addFiles($config, $box, $logger, $io); - - self::registerStub($config, $box, $main, $check, $logger); - self::configureMetadata($config, $box, $logger); - - self::commit($box, $composerOrchestrator, $config, $logger); - - self::checkComposerFiles($box, $config, $logger); - - if ($debug) { - $box->getPhar()->extractTo(self::DEBUG_DIR, null, true); - } - - self::configureCompressionAlgorithm( - $config, - $box, - $io->getOption(self::DEV_OPTION)->asBoolean(), - $io, - $logger, - ); - - self::signPhar($config, $box, $config->getTmpOutputPath(), $io, $logger); - - if ($config->getTmpOutputPath() !== $config->getOutputPath()) { - FS::rename($config->getTmpOutputPath(), $config->getOutputPath()); - } - - return $box; - } - - private static function getComposerBin(IO $io): ?string - { - $composerBin = $io->getOption(self::COMPOSER_BIN_OPTION)->asNullableNonEmptyString(); - - return null === $composerBin ? null : Path::makeAbsolute($composerBin, getcwd()); - } - - private function removeExistingArtifacts(Configuration $config, CompilerLogger $logger, bool $debug): void - { - $path = $config->getOutputPath(); - - if ($debug) { - FS::remove(self::DEBUG_DIR); - - FS::dumpFile( - self::DEBUG_DIR.'/.box_configuration', - ConfigurationExporter::export($config), - ); - } - - if (false === file_exists($path)) { - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Removing the existing PHAR "%s"', - $path, - ), - ); - - FS::remove($path); - } - - private static function checkComposerVersion( - ComposerOrchestrator $composerOrchestrator, - Configuration $config, - CompilerLogger $logger, - IO $io, - ): void { - if (!$config->dumpAutoload()) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Skipping the Composer compatibility check: the autoloader is not dumped', - ); - - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Checking Composer compatibility', - ); - - try { - $composerOrchestrator->checkVersion(); - - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - 'Supported version detected', - ); - } catch (IncompatibleComposerVersion $incompatibleComposerVersion) { - if ($io->getOption(self::ALLOW_COMPOSER_COMPOSER_CHECK_FAILURE_OPTION)->asBoolean()) { - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - 'Warning! Incompatible composer version detected: '.$incompatibleComposerVersion->getMessage(), - ); - - return; // Swallow the exception - } - - throw $incompatibleComposerVersion; - } - } - - private static function registerReplacementValues(Configuration $config, Box $box, CompilerLogger $logger): void - { - $values = $config->getReplacements(); - - if (0 === count($values)) { - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Setting replacement values', - ); - - foreach ($values as $key => $value) { - $logger->log( - CompilerLogger::PLUS_PREFIX, - sprintf( - '%s: %s', - $key, - $value, - ), - ); - } - - $box->registerPlaceholders($values); - } - - private static function registerCompactors(Configuration $config, Box $box, CompilerLogger $logger): void - { - $compactors = $config->getCompactors(); - - if (0 === count($compactors)) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'No compactor to register', - ); - - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Registering compactors', - ); - - $logCompactors = static function (Compactor $compactor) use ($logger): void { - $compactorClassParts = explode('\\', $compactor::class); - - if (str_starts_with($compactorClassParts[0], '_HumbugBox')) { - // Keep the non prefixed class name for the user - array_shift($compactorClassParts); - } - - $logger->log( - CompilerLogger::PLUS_PREFIX, - implode('\\', $compactorClassParts), - ); - }; - - array_map($logCompactors, $compactors->toArray()); - - $box->registerCompactors($compactors); - } - - private static function registerFileMapping(Configuration $config, Box $box, CompilerLogger $logger): void - { - $fileMapper = $config->getFileMapper(); - - self::logMap($fileMapper, $logger); - - $box->registerFileMapping($fileMapper); - } - - private static function addFiles(Configuration $config, Box $box, CompilerLogger $logger, IO $io): void - { - $logger->log(CompilerLogger::QUESTION_MARK_PREFIX, 'Adding binary files'); - - $count = count($config->getBinaryFiles()); - - $box->addFiles($config->getBinaryFiles(), true); - - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - 0 === $count - ? 'No file found' - : sprintf('%d file(s)', $count), - ); - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Auto-discover files? %s', - $config->hasAutodiscoveredFiles() ? 'Yes' : 'No', - ), - ); - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Exclude dev files? %s', - $config->excludeDevFiles() ? 'Yes' : 'No', - ), - ); - $logger->log(CompilerLogger::QUESTION_MARK_PREFIX, 'Adding files'); - - $count = count($config->getFiles()); - - self::addFilesWithErrorHandling($config, $box, $io); - - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - 0 === $count - ? 'No file found' - : sprintf('%d file(s)', $count), - ); - } - - private static function addFilesWithErrorHandling(Configuration $config, Box $box, IO $io): void - { - try { - $box->addFiles($config->getFiles(), false); - - return; - } catch (MultiReasonException $ampFailure) { - // Continue - } - - // This exception is handled a different way to give me meaningful feedback to the user - $io->error([ - 'An Amp\Parallel error occurred. To diagnostic if it is an Amp error related, you may try again with "--no-parallel".', - 'Reason(s) of the failure:', - ...FailureCollector::collectReasons($ampFailure), - ]); - - throw $ampFailure; - } - - private static function registerMainScript(Configuration $config, Box $box, CompilerLogger $logger): ?string - { - if (false === $config->hasMainScript()) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'No main script path configured', - ); - - return null; - } - - $main = $config->getMainScriptPath(); - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Adding main file: %s', - $main, - ), - ); - - $localMain = $box->addFile( - $main, - $config->getMainScriptContents(), - ); - - $relativeMain = Path::makeRelative($main, $config->getBasePath()); - - if ($localMain !== $relativeMain) { - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - $localMain, - ); - } - - return $localMain; - } - - private static function registerRequirementsChecker(Configuration $config, Box $box, CompilerLogger $logger): bool - { - if (false === $config->checkRequirements()) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Skip requirements checker', - ); - - return false; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Adding requirements checker', - ); - - $checkFiles = RequirementsDumper::dump( - new DecodedComposerJson($config->getDecodedComposerJsonContents() ?? []), - new DecodedComposerLock($config->getDecodedComposerLockContents() ?? []), - $config->getCompressionAlgorithm(), - ); - - foreach ($checkFiles as $fileWithContents) { - [$file, $contents] = $fileWithContents; - - $box->addFile('.box/'.$file, $contents, true); - } - - return true; - } - - private static function registerStub( - Configuration $config, - Box $box, - ?string $main, - bool $checkRequirements, - CompilerLogger $logger, - ): void { - if ($config->isStubGenerated()) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Generating new stub', - ); - - $stub = self::createStub($config, $main, $checkRequirements, $logger); - - $box->getPhar()->setStub($stub); - - return; - } - - if (null !== ($stub = $config->getStubPath())) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Using stub file: %s', - $stub, - ), - ); - - $box->registerStub($stub); - - return; - } - - $aliasWasAdded = $box->getPhar()->setAlias($config->getAlias()); - - Assert::true( - $aliasWasAdded, - sprintf( - 'The alias "%s" is invalid. See Phar::setAlias() documentation for more information.', - $config->getAlias(), - ), - ); - - $box->getPhar()->setDefaultStub($main); - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Using default stub', - ); - } - - private static function configureMetadata(Configuration $config, Box $box, CompilerLogger $logger): void - { - if (null !== ($metadata = $config->getMetadata())) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Setting metadata', - ); - - if (is_callable($metadata)) { - $metadata = $metadata(); - } - - $logger->log( - CompilerLogger::MINUS_PREFIX, - is_string($metadata) ? $metadata : var_export($metadata, true), - ); - - $box->getPhar()->setMetadata($metadata); - } - } - - private static function commit( - Box $box, - ComposerOrchestrator $composerOrchestrator, - Configuration $config, - CompilerLogger $logger, - ): void { - $message = $config->dumpAutoload() - ? 'Dumping the Composer autoloader' - : 'Skipping dumping the Composer autoloader'; - - $logger->log(CompilerLogger::QUESTION_MARK_PREFIX, $message); - - $excludeDevFiles = $config->excludeDevFiles(); - - $box->endBuffering( - $config->dumpAutoload() - ? static fn (SymbolsRegistry $symbolsRegistry, string $prefix, array $excludeScoperFiles) => $composerOrchestrator->dumpAutoload( - $symbolsRegistry, - $prefix, - $excludeDevFiles, - $excludeScoperFiles, - ) - : null, - ); - } - - private static function checkComposerFiles(Box $box, Configuration $config, CompilerLogger $logger): void - { - $message = $config->excludeComposerFiles() - ? 'Removing the Composer dump artefacts' - : 'Keep the Composer dump artefacts'; - - $logger->log(CompilerLogger::QUESTION_MARK_PREFIX, $message); - - if ($config->excludeComposerFiles()) { - $box->removeComposerArtefacts( - ComposerConfiguration::retrieveVendorDir( - $config->getDecodedComposerJsonContents() ?? [], - ), - ); - } - } - - private static function configureCompressionAlgorithm( - Configuration $config, - Box $box, - bool $dev, - IO $io, - CompilerLogger $logger, - ): void { - $algorithm = $config->getCompressionAlgorithm(); - - if (CompressionAlgorithm::NONE === $algorithm) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'No compression', - ); - - return; - } - - if ($dev) { - $logger->log(CompilerLogger::QUESTION_MARK_PREFIX, 'Dev mode detected: skipping the compression'); - - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Compressing with the algorithm "%s"', - $algorithm->name, - ), - ); - - $restoreLimit = bump_open_file_descriptor_limit(count($box), $io); - - try { - $extension = $box->compress($algorithm); - - if (null !== $extension) { - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - sprintf( - 'Warning: the extension "%s" will now be required to execute the PHAR', - $extension, - ), - ); - } - } catch (RuntimeException $exception) { - $io->error($exception->getMessage()); - - // Continue: the compression failure should not result in completely bailing out the compilation process - } finally { - $restoreLimit(); - } - } - - private static function signPhar( - Configuration $config, - Box $box, - string $path, - IO $io, - CompilerLogger $logger, - ): void { - // Sign using private key when applicable - FS::remove($path.'.pubkey'); - - $key = $config->getPrivateKeyPath(); - - if (null === $key) { - $box->getPhar()->setSignatureAlgorithm( - $config->getSigningAlgorithm()->value, - ); - - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Signing using a private key', - ); - - $passphrase = $config->getPrivateKeyPassphrase(); - - if ($config->promptForPrivateKey()) { - if (false === $io->isInteractive()) { - throw new RuntimeException( - sprintf( - 'Accessing to the private key "%s" requires a passphrase but none provided. Either ' - .'provide one or run this command in interactive mode.', - $key, - ), - ); - } - - $question = new Question('Private key passphrase'); - $question->setHidden(false); - $question->setHiddenFallback(false); - - $passphrase = $io->askQuestion($question); - - $io->writeln(''); - } - - $box->signUsingFile($key, $passphrase); - } - - private static function correctPermissions(string $path, Configuration $config, CompilerLogger $logger): void - { - if (null !== ($chmod = $config->getFileMode())) { - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - sprintf( - 'Setting file permissions to %s', - '0'.decoct($chmod), - ), - ); - - FS::chmod($path, $chmod); - } - } - - private static function createStub( - Configuration $config, - ?string $main, - bool $checkRequirements, - CompilerLogger $logger, - ): string { - $shebang = $config->getShebang(); - $bannerPath = $config->getStubBannerPath(); - $bannerContents = $config->getStubBannerContents(); - - if (null !== $shebang) { - $logger->log( - CompilerLogger::MINUS_PREFIX, - sprintf( - 'Using shebang line: %s', - $shebang, - ), - ); - } else { - $logger->log( - CompilerLogger::MINUS_PREFIX, - 'No shebang line', - ); - } - - if (null !== $bannerPath) { - $logger->log( - CompilerLogger::MINUS_PREFIX, - sprintf( - 'Using custom banner from file: %s', - $bannerPath, - ), - ); - } elseif (null !== $bannerContents) { - $logger->log( - CompilerLogger::MINUS_PREFIX, - 'Using banner:', - ); - - $bannerLines = explode("\n", $bannerContents); - - foreach ($bannerLines as $bannerLine) { - $logger->log( - CompilerLogger::CHEVRON_PREFIX, - $bannerLine, - ); - } - } - - return StubGenerator::generateStub( - $config->getAlias(), - $bannerContents, - $main, - $config->isInterceptFileFuncs(), - $shebang, - $checkRequirements, - ); - } - - private static function logMap(MapFile $fileMapper, CompilerLogger $logger): void - { - $map = $fileMapper->getMap(); - - if (0 === count($map)) { - return; - } - - $logger->log( - CompilerLogger::QUESTION_MARK_PREFIX, - 'Mapping paths', - ); - - foreach ($map as $item) { - foreach ($item as $match => $replace) { - if ('' === $match) { - $match = '(all)'; - $replace .= '/'; - } - - $logger->log( - CompilerLogger::MINUS_PREFIX, - sprintf( - '%s > %s', - $match, - $replace, - ), - ); - } - } - } - - private static function logEndBuilding( - Configuration $config, - CompilerLogger $logger, - IO $io, - Box $box, - string $path, - float $startTime, - ): void { - $logger->log( - CompilerLogger::STAR_PREFIX, - 'Done.', - ); - $io->newLine(); - - MessageRenderer::render($io, $config->getRecommendations(), $config->getWarnings()); - - $io->comment( - sprintf( - 'PHAR: %s (%s)', - $box->count() > 1 ? $box->count().' files' : $box->count().' file', - format_size( - filesize($path), - ), - ) - .PHP_EOL - .'You can inspect the generated PHAR with the "info" command.', - ); - - $io->comment( - sprintf( - 'Memory usage: %s (peak: %s), time: %s', - format_size(memory_get_usage()), - format_size(memory_get_peak_usage()), - format_time(microtime(true) - $startTime), - ), - ); - } - - private function generateDockerFile(IO $io): int - { - $input = new StringInput(''); - $input->setInteractive(false); - - return $this->getDockerCommand()->execute( - new IO($input, $io->getOutput()), - ); - } - - private function getDockerCommand(): Command - { - return $this->getCommandRegistry()->findCommand(GenerateDockerFile::NAME); - } -} diff --git a/vendor-hotfix/ComposerOrchestrator.php b/vendor-hotfix/ComposerOrchestrator.php deleted file mode 100644 index db259dd7c..000000000 --- a/vendor-hotfix/ComposerOrchestrator.php +++ /dev/null @@ -1,186 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\Composer; - -use Composer\Semver\Semver; -use Fidry\Console\Input\IO; -use Fidry\FileSystem\FileSystem; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use KevinGH\Box\NotInstantiable; -use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; -use RuntimeException; -use Symfony\Component\Process\Exception\ProcessFailedException; -use function sprintf; -use function trim; -use const PHP_EOL; - -/** - * @private - */ -final class ComposerOrchestrator -{ - use NotInstantiable; - - public const SUPPORTED_VERSION_CONSTRAINTS = '^2.2.0'; - - private string $detectedVersion; - - public static function create(): self - { - return new self( - ComposerProcessFactory::create(io: IO::createNull()), - new NullLogger(), - new FileSystem(), - ); - } - - public function __construct( - private ComposerProcessFactory $processFactory, - private LoggerInterface $logger, - private FileSystem $fileSystem, - ) { - } - - /** - * @throws UndetectableComposerVersion - */ - public function getVersion(): string - { - if (isset($this->detectedVersion)) { - return $this->detectedVersion; - } - - $getVersionProcess = $this->processFactory->getVersionProcess(); - - $this->logger->info($getVersionProcess->getCommandLine()); - - $getVersionProcess->run(); - - if (false === $getVersionProcess->isSuccessful()) { - throw UndetectableComposerVersion::forFailedProcess($getVersionProcess); - } - - $output = $getVersionProcess->getOutput(); - - if (1 !== preg_match('/Composer version (\S+?) /', $output, $match)) { - throw UndetectableComposerVersion::forOutput( - $getVersionProcess, - $output, - ); - } - - $this->detectedVersion = $match[1]; - - return $this->detectedVersion; - } - - /** - * @throws UndetectableComposerVersion - * @throws IncompatibleComposerVersion - */ - public function checkVersion(): void - { - $version = $this->getVersion(); - - $this->logger->info( - sprintf( - 'Version detected: %s (Box requires %s)', - $version, - self::SUPPORTED_VERSION_CONSTRAINTS, - ), - ); - - if (!Semver::satisfies($version, self::SUPPORTED_VERSION_CONSTRAINTS)) { - throw IncompatibleComposerVersion::create($version, self::SUPPORTED_VERSION_CONSTRAINTS); - } - } - - public function dumpAutoload( - SymbolsRegistry $symbolsRegistry, - string $prefix, - bool $excludeDevFiles, - array $excludedComposerAutoloadFileHashes, - ): void { - $this->dumpAutoloader(true === $excludeDevFiles); - - if ('' === $prefix) { - return; - } - - $autoloadFile = $this->getVendorDir().'/autoload.php'; - - $autoloadContents = AutoloadDumper::generateAutoloadStatements( - $symbolsRegistry, - $excludedComposerAutoloadFileHashes, - $this->fileSystem->getFileContents($autoloadFile), - ); - - $this->fileSystem->dumpFile($autoloadFile, $autoloadContents); - } - - public function getVendorDir(): string - { - $vendorDirProcess = $this->processFactory->getVendorDirProcess(); - - $this->logger->info($vendorDirProcess->getCommandLine()); - - $vendorDirProcess->run(); - - if (false === $vendorDirProcess->isSuccessful()) { - throw new RuntimeException( - 'Could not retrieve the vendor dir.', - 0, - new ProcessFailedException($vendorDirProcess), - ); - } - - return trim($vendorDirProcess->getOutput()); - } - - private function dumpAutoloader(bool $noDev): void - { - $dumpAutoloadProcess = $this->processFactory->getDumpAutoloaderProcess($noDev); - - $this->logger->info($dumpAutoloadProcess->getCommandLine()); - - $dumpAutoloadProcess->run(); - - if (false === $dumpAutoloadProcess->isSuccessful()) { - throw new RuntimeException( - 'Could not dump the autoloader.', - 0, - new ProcessFailedException($dumpAutoloadProcess), - ); - } - - $output = $dumpAutoloadProcess->getOutput(); - $errorOutput = $dumpAutoloadProcess->getErrorOutput(); - - if ('' !== $output) { - $this->logger->info( - 'STDOUT output:'.PHP_EOL.$output, - ['stdout' => $output], - ); - } - - if ('' !== $errorOutput) { - $this->logger->info( - 'STDERR output:'.PHP_EOL.$errorOutput, - ['stderr' => $errorOutput], - ); - } - } -} diff --git a/vendor-hotfix/NullScoper.php b/vendor-hotfix/NullScoper.php deleted file mode 100644 index affe05f6f..000000000 --- a/vendor-hotfix/NullScoper.php +++ /dev/null @@ -1,53 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\PhpScoper; - -use Humbug\PhpScoper\Symbol\SymbolsRegistry; - -/** - * @private - */ -final class NullScoper implements Scoper -{ - public function __construct( - private SymbolsRegistry $symbolsRegistry = new SymbolsRegistry(), - ) { - } - - public function scope(string $filePath, string $contents): string - { - return $contents; - } - - public function changeSymbolsRegistry(SymbolsRegistry $symbolsRegistry): void - { - $this->symbolsRegistry = $symbolsRegistry; - } - - public function getSymbolsRegistry(): SymbolsRegistry - { - return $this->symbolsRegistry; - } - - public function getPrefix(): string - { - return ''; - } - - public function getExcludedFilePaths(): array - { - return []; - } -} diff --git a/vendor-hotfix/Scoper.php b/vendor-hotfix/Scoper.php deleted file mode 100644 index 2c0662ec2..000000000 --- a/vendor-hotfix/Scoper.php +++ /dev/null @@ -1,38 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\PhpScoper; - -use Humbug\PhpScoper\Symbol\SymbolsRegistry; - -interface Scoper -{ - /** - * Scope AKA. apply the given prefix to the file in the appropriate way. - * - * @param string $filePath File to scope - * @param string $contents Contents of the file to scope - * - * @return string Contents of the file with the prefix applied - */ - public function scope(string $filePath, string $contents): string; - - public function changeSymbolsRegistry(SymbolsRegistry $symbolsRegistry): void; - - public function getSymbolsRegistry(): SymbolsRegistry; - - public function getPrefix(): string; - - public function getExcludedFilePaths(): array; -} diff --git a/vendor-hotfix/SerializableScoper.php b/vendor-hotfix/SerializableScoper.php deleted file mode 100644 index 152c00e87..000000000 --- a/vendor-hotfix/SerializableScoper.php +++ /dev/null @@ -1,122 +0,0 @@ - - * Théo Fidry - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace KevinGH\Box\PhpScoper; - -use Humbug\PhpScoper\Configuration\Configuration as PhpScoperConfiguration; -use Humbug\PhpScoper\Container as PhpScoperContainer; -use Humbug\PhpScoper\Scoper\Scoper as PhpScoperScoper; -use Humbug\PhpScoper\Symbol\SymbolsRegistry; -use function count; - -/** - * @private - */ -final class SerializableScoper implements Scoper -{ - private PhpScoperConfiguration $scoperConfig; - private PhpScoperContainer $scoperContainer; - private PhpScoperScoper $scoper; - private SymbolsRegistry $symbolsRegistry; - - /** - * @var list - */ - public array $excludedFilePaths; - - public function __construct( - PhpScoperConfiguration $scoperConfig, - string ...$excludedFilePaths, - ) { - $this->scoperConfig = $scoperConfig->withPatcher( - PatcherFactory::createSerializablePatchers($scoperConfig->getPatcher()) - ); - $this->excludedFilePaths = $excludedFilePaths; - $this->symbolsRegistry = new SymbolsRegistry(); - } - - public function scope(string $filePath, string $contents): string - { - return $this->getScoper()->scope( - $filePath, - $contents, - ); - } - - public function changeSymbolsRegistry(SymbolsRegistry $symbolsRegistry): void - { - $this->symbolsRegistry = $symbolsRegistry; - - unset($this->scoper); - } - - public function getSymbolsRegistry(): SymbolsRegistry - { - return $this->symbolsRegistry; - } - - public function getPrefix(): string - { - return $this->scoperConfig->getPrefix(); - } - - private function getScoper(): PhpScoperScoper - { - if (isset($this->scoper)) { - return $this->scoper; - } - - if (!isset($this->scoperContainer)) { - $this->scoperContainer = new PhpScoperContainer(); - } - - $this->scoper = $this->createScoper(); - - return $this->scoper; - } - - public function __wakeup(): void - { - // We need to make sure that a fresh Scoper & PHP-Parser Parser/Lexer - // is used within a sub-process. - // Otherwise, there is a risk of data corruption or that a compatibility - // layer of some sorts (such as the tokens for PHP-Paser) is not - // triggered in the sub-process resulting in obscure errors - unset($this->scoper, $this->scoperContainer); - } - - private function createScoper(): PhpScoperScoper - { - $scoper = $this->scoperContainer - ->getScoperFactory() - ->createScoper( - $this->scoperConfig, - $this->symbolsRegistry, - ); - - if (0 === count($this->excludedFilePaths)) { - return $scoper; - } - - return new ExcludedFilesScoper( - $scoper, - ...$this->excludedFilePaths, - ); - } - - public function getExcludedFilePaths(): array - { - return $this->excludedFilePaths; - } -}