From 31f40bbf898e7448717a424af98eae6180b926b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Sat, 15 Jun 2024 12:12:29 +0200 Subject: [PATCH 1/3] feat: Allow to configure the parser PHP version --- src/Configuration/Configuration.php | 10 +++++++++ src/Configuration/ConfigurationFactory.php | 24 ++++++++++++++++++++ src/Configuration/ConfigurationKeys.php | 2 ++ src/Console/Command/AddPrefixCommand.php | 26 ++++++++++++++++++++-- src/Console/ConsoleScoper.php | 23 ++++++++++++++----- src/Scoper/ScoperFactory.php | 1 + src/scoper.inc.php.tpl | 5 +++++ 7 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php index 4ad285aa..57dfe3b7 100644 --- a/src/Configuration/Configuration.php +++ b/src/Configuration/Configuration.php @@ -16,6 +16,7 @@ use Humbug\PhpScoper\Patcher\Patcher; use InvalidArgumentException; +use PhpParser\PhpVersion; use function Safe\preg_match; use function sprintf; @@ -43,6 +44,7 @@ public function __construct( private ?string $path, private ?string $outputDir, string $prefix, + private ?PhpVersion $phpVersion, private array $filesWithContents, private array $excludedFilesWithContents, private Patcher $patcher, @@ -78,6 +80,7 @@ public function withPrefix(string $prefix): self $this->path, $this->outputDir, $prefix, + $this->phpVersion, $this->filesWithContents, $this->excludedFilesWithContents, $this->patcher, @@ -102,6 +105,7 @@ public function withFilesWithContents(array $filesWithContents): self $this->path, $this->outputDir, $this->prefix, + $this->phpVersion, $filesWithContents, $this->excludedFilesWithContents, $this->patcher, @@ -131,6 +135,7 @@ public function withPatcher(Patcher $patcher): self $this->path, $this->outputDir, $this->prefix, + $this->phpVersion, $this->filesWithContents, $this->excludedFilesWithContents, $patcher, @@ -148,6 +153,11 @@ public function getSymbolsConfiguration(): SymbolsConfiguration return $this->symbolsConfiguration; } + public function getPhpVersion(): ?PhpVersion + { + return $this->phpVersion; + } + private static function validatePrefix(string $prefix): void { if (1 !== preg_match(self::PREFIX_PATTERN, $prefix)) { diff --git a/src/Configuration/ConfigurationFactory.php b/src/Configuration/ConfigurationFactory.php index 503a8299..fa4216d4 100644 --- a/src/Configuration/ConfigurationFactory.php +++ b/src/Configuration/ConfigurationFactory.php @@ -20,6 +20,7 @@ use Humbug\PhpScoper\Patcher\SymfonyParentTraitPatcher; use Humbug\PhpScoper\Patcher\SymfonyPatcher; use InvalidArgumentException; +use PhpParser\PhpVersion; use RuntimeException; use SplFileInfo; use Symfony\Component\Filesystem\Filesystem; @@ -189,6 +190,7 @@ private static function validateConfigKeys(array $config): void ); } + // TODO: move to ConfigKeys private static function validateConfigKey(string $key): void { if (in_array($key, ConfigurationKeys::KEYWORDS, true)) { @@ -213,6 +215,28 @@ private static function retrievePrefix(array $config): string return '' === $prefix ? self::generateRandomPrefix() : $prefix; } + /** + * @return non-empty-string|null + */ + private static function retrievePhpVersion(array $config): ?PhpVersion + { + $phpVersion = $config[ConfigurationKeys::PHP_VERSION_KEYWORD] ?? null; + + if (null === $phpVersion) { + return null; + } + + // TODO: throw a dedicated exception + throw new InvalidArgumentException( + sprintf( + 'Expected patchers to be an array of callables, found "%s" instead.', + gettype($patchers), + ), + ); + + return '' === $phpVersion ? null : $phpVersion; + } + /** * @return non-empty-string|null */ diff --git a/src/Configuration/ConfigurationKeys.php b/src/Configuration/ConfigurationKeys.php index 9712e58d..8a8c3316 100644 --- a/src/Configuration/ConfigurationKeys.php +++ b/src/Configuration/ConfigurationKeys.php @@ -21,6 +21,7 @@ final class ConfigurationKeys use NotInstantiable; public const PREFIX_KEYWORD = 'prefix'; + public const PHP_VERSION_KEYWORD = 'php-version'; public const OUTPUT_DIR_KEYWORD = 'output-dir'; public const EXCLUDED_FILES_KEYWORD = 'exclude-files'; public const FINDER_KEYWORD = 'finders'; @@ -42,6 +43,7 @@ final class ConfigurationKeys public const KEYWORDS = [ self::PREFIX_KEYWORD, + self::PHP_VERSION_KEYWORD, self::OUTPUT_DIR_KEYWORD, self::EXCLUDED_FILES_KEYWORD, self::FINDER_KEYWORD, diff --git a/src/Console/Command/AddPrefixCommand.php b/src/Console/Command/AddPrefixCommand.php index 0896eae0..f041fa54 100644 --- a/src/Console/Command/AddPrefixCommand.php +++ b/src/Console/Command/AddPrefixCommand.php @@ -25,8 +25,10 @@ use Humbug\PhpScoper\Configuration\ConfigurationFactory; use Humbug\PhpScoper\Console\ConfigLoader; use Humbug\PhpScoper\Console\ConsoleScoper; +use Humbug\PhpScoper\Container; use Humbug\PhpScoper\Scoper\ScoperFactory; use InvalidArgumentException; +use PhpParser\PhpVersion; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -54,6 +56,7 @@ final class AddPrefixCommand implements Command, CommandAware private const CONTINUE_ON_FAILURE_OPT = 'continue-on-failure'; private const CONFIG_FILE_OPT = 'config'; private const NO_CONFIG_OPT = 'no-config'; + private const PHP_VERSION_OPT = 'no-config'; private const DEFAULT_OUTPUT_DIR = 'build'; @@ -61,9 +64,9 @@ final class AddPrefixCommand implements Command, CommandAware public function __construct( private readonly Filesystem $fileSystem, - private readonly ScoperFactory $scoperFactory, private readonly Application $application, private readonly ConfigurationFactory $configFactory, + private readonly Container $container, ) { } @@ -94,7 +97,7 @@ public function getConfiguration(): CommandConfiguration 'o', InputOption::VALUE_REQUIRED, 'The output directory in which the prefixed code will be dumped.', - '' + '', ), new InputOption( self::FORCE_OPT, @@ -129,6 +132,12 @@ public function getConfiguration(): CommandConfiguration InputOption::VALUE_NONE, 'Do not look for a configuration file.', ), + new InputOption( + self::PHP_VERSION_OPT, + null, + InputOption::VALUE_REQUIRED, + 'PHP version in which the PHP parser and printer will be configured.', + ), ], ); } @@ -145,6 +154,7 @@ public function execute(IO $io): int $paths = $this->getPathArguments($io, $cwd); $config = $this->retrieveConfig($io, $paths, $cwd); + $phpVersion = self::getPhpVersion($io); $outputDir = $this->canonicalizePath( $this->getOutputDir($io, $config), @@ -155,6 +165,7 @@ public function execute(IO $io): int $this->getScoper()->scope( $io, $config, + $phpVersion, $paths, $outputDir, self::getStopOnFailure($io), @@ -163,6 +174,17 @@ public function execute(IO $io): int return ExitCode::SUCCESS; } + private static function getPhpVersion(IO $io): ?PhpVersion + { + $version = $io + ->getTypedOption(self::PHP_VERSION_OPT) + ->asNullableString(); + + return null === $version + ? $version + : PhpVersion::fromString($version); + } + private static function getStopOnFailure(IO $io): bool { $stopOnFailure = $io->getTypedOption(self::STOP_ON_FAILURE_OPT)->asBoolean(); diff --git a/src/Console/ConsoleScoper.php b/src/Console/ConsoleScoper.php index f354e4fb..78115b3f 100644 --- a/src/Console/ConsoleScoper.php +++ b/src/Console/ConsoleScoper.php @@ -19,10 +19,12 @@ use Humbug\PhpScoper\Autoload\ComposerFileHasher; use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\Container; use Humbug\PhpScoper\Scoper\Scoper; use Humbug\PhpScoper\Scoper\ScoperFactory; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use Humbug\PhpScoper\Throwable\Exception\ParsingException; +use PhpParser\PhpVersion; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Path; use Throwable; @@ -50,7 +52,7 @@ public function __construct( private Filesystem $fileSystem, private Application $application, - private ScoperFactory $scoperFactory, + private Container $container, ) { } @@ -61,6 +63,7 @@ public function __construct( public function scope( IO $io, Configuration $config, + ?PhpVersion $phpVersion, array $paths, string $outputDir, bool $stopOnFailure @@ -78,6 +81,7 @@ public function scope( try { $this->doScope( $config, + $phpVersion, $outputDir, $stopOnFailure, $logger, @@ -95,6 +99,7 @@ public function scope( private function doScope( Configuration $config, + ?PhpVersion $phpVersion, string $outputDir, bool $stopOnFailure, ScoperLogger $logger @@ -108,6 +113,7 @@ private function doScope( $this->scopeFiles( $config, + $phpVersion, $files, $stopOnFailure, $logger, @@ -118,7 +124,7 @@ private function doScope( $this->dumpFileWithPermissions($excludedFileWithContent); } - self::dumpScoperAutoloader( + $this->dumpScoperAutoloader( $files, $excludedFilesWithContents, $symbolsRegistry, @@ -175,6 +181,7 @@ private function dumpScoperAutoloader( */ private function scopeFiles( Configuration $config, + ?PhpVersion $phpVersion, array $files, bool $stopOnFailure, ScoperLogger $logger, @@ -182,10 +189,14 @@ private function scopeFiles( ): void { $logger->outputFileCount(count($files)); - $scoper = $this->scoperFactory->createScoper( - $config, - $symbolsRegistry, - ); + $resolvedPhpVersion = $phpVersion ?? $config->getPhpVersion(); + + $scoper = $this->container + ->getScoperFactory($resolvedPhpVersion) + ->createScoper( + $config, + $symbolsRegistry, + ); foreach ($files as $file) { $this->scopeFile( diff --git a/src/Scoper/ScoperFactory.php b/src/Scoper/ScoperFactory.php index 978cc83a..c88426b5 100644 --- a/src/Scoper/ScoperFactory.php +++ b/src/Scoper/ScoperFactory.php @@ -23,6 +23,7 @@ use Humbug\PhpScoper\Symbol\EnrichedReflectorFactory; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use PhpParser\Parser; +use PhpParser\PhpVersion; /** * @final diff --git a/src/scoper.inc.php.tpl b/src/scoper.inc.php.tpl index 5c01cddb..823b6e7f 100644 --- a/src/scoper.inc.php.tpl +++ b/src/scoper.inc.php.tpl @@ -71,6 +71,11 @@ return [ ...$excludedFiles, ], + // PHP version (e.g. `'7.2'`) in which the PHP parser and printer will be configured into. This will affect what + // level of code it will understand and how the code will be printed. + // If none (or `null`) is configured, then the host version will be used. + 'php-version' => null, + // When scoping PHP files, there will be scenarios where some of the code being scoped indirectly references the // original namespace. These will include, for example, strings or string manipulations. PHP-Scoper has limited // support for prefixing such strings. To circumvent that, you can define patchers to manipulate the file to your From b2a5685cd9741dcdd941c8b9f7898f237574723d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Sun, 16 Jun 2024 16:52:26 +0200 Subject: [PATCH 2/3] fix --- src/Configuration/Configuration.php | 1 - src/Configuration/ConfigurationFactory.php | 25 ++++++++-------- .../Throwable/InvalidConfigurationValue.php | 23 ++++++++++++++ src/Console/Command/AddPrefixCommand.php | 8 ++--- src/Console/Command/InspectCommand.php | 30 ++++++++++++++++++- src/Console/ConsoleScoper.php | 7 +++-- .../ConfigurationFactoryTest.php | 27 ++++++++--------- tests/Configuration/ConfigurationTest.php | 10 +++++-- .../Factory/StandardScoperFactoryTest.php | 1 + 9 files changed, 94 insertions(+), 38 deletions(-) diff --git a/src/Configuration/Configuration.php b/src/Configuration/Configuration.php index 2330d9b7..ab07340a 100644 --- a/src/Configuration/Configuration.php +++ b/src/Configuration/Configuration.php @@ -17,7 +17,6 @@ use Humbug\PhpScoper\Configuration\Throwable\InvalidConfigurationValue; use Humbug\PhpScoper\Patcher\Patcher; use PhpParser\PhpVersion; -use function Safe\preg_match; final class Configuration { diff --git a/src/Configuration/ConfigurationFactory.php b/src/Configuration/ConfigurationFactory.php index 3db58fcf..902b0ec7 100644 --- a/src/Configuration/ConfigurationFactory.php +++ b/src/Configuration/ConfigurationFactory.php @@ -14,6 +14,7 @@ namespace Humbug\PhpScoper\Configuration; +use Exception; use Humbug\PhpScoper\Configuration\Throwable\InvalidConfiguration; use Humbug\PhpScoper\Configuration\Throwable\InvalidConfigurationFile; use Humbug\PhpScoper\Configuration\Throwable\InvalidConfigurationValue; @@ -22,7 +23,6 @@ use Humbug\PhpScoper\Patcher\PatcherChain; use Humbug\PhpScoper\Patcher\SymfonyParentTraitPatcher; use Humbug\PhpScoper\Patcher\SymfonyPatcher; -use InvalidArgumentException; use PhpParser\PhpVersion; use SplFileInfo; use Symfony\Component\Filesystem\Filesystem; @@ -99,6 +99,7 @@ public function create(?string $path = null, array $paths = []): Configuration $path, $outputDir, $prefix, + self::retrievePhpVersion($config), $filesWithContents, self::retrieveFilesWithContents($excludedFiles), new PatcherChain($patchers), @@ -181,25 +182,25 @@ private static function retrievePrefix(array $config): string } /** - * @return non-empty-string|null + * @throws InvalidConfigurationValue */ private static function retrievePhpVersion(array $config): ?PhpVersion { - $phpVersion = $config[ConfigurationKeys::PHP_VERSION_KEYWORD] ?? null; + $stringVersion = $config[ConfigurationKeys::PHP_VERSION_KEYWORD] ?? null; - if (null === $phpVersion) { + if (null === $stringVersion || '' === $stringVersion) { return null; } - // TODO: throw a dedicated exception - throw new InvalidArgumentException( - sprintf( - 'Expected patchers to be an array of callables, found "%s" instead.', - gettype($patchers), - ), - ); + if (!is_string($stringVersion)) { + throw InvalidConfigurationValue::forInvalidPhpVersionType($stringVersion); + } - return '' === $phpVersion ? null : $phpVersion; + try { + return PhpVersion::fromString($stringVersion); + } catch (Exception $exception) { + throw InvalidConfigurationValue::forInvalidPhpVersion($stringVersion, $exception); + } } /** diff --git a/src/Configuration/Throwable/InvalidConfigurationValue.php b/src/Configuration/Throwable/InvalidConfigurationValue.php index be21aba2..0538b1bf 100644 --- a/src/Configuration/Throwable/InvalidConfigurationValue.php +++ b/src/Configuration/Throwable/InvalidConfigurationValue.php @@ -14,9 +14,11 @@ namespace Humbug\PhpScoper\Configuration\Throwable; +use Exception; use Symfony\Component\Finder\Finder; use UnexpectedValueException; use function gettype; +use function sprintf; final class InvalidConfigurationValue extends UnexpectedValueException implements InvalidConfiguration { @@ -115,6 +117,27 @@ public static function forInvalidPrefixPattern(string $prefix): self ); } + public static function forInvalidPhpVersionType(mixed $phpVersion): self + { + return new self( + sprintf( + 'Expected the PHP version to be a string, got "%s" instead.', + gettype($phpVersion), + ), + ); + } + + public static function forInvalidPhpVersion(string $stringVersion, Exception $previous): self + { + return new self( + sprintf( + 'Expected the PHP version to of the format ".", e.g. "7.2", got "%s".', + $stringVersion, + ), + previous: $previous, + ); + } + public static function forInvalidNamespaceSeparator(string $prefix): self { return new self( diff --git a/src/Console/Command/AddPrefixCommand.php b/src/Console/Command/AddPrefixCommand.php index 285f91e3..e644d78f 100644 --- a/src/Console/Command/AddPrefixCommand.php +++ b/src/Console/Command/AddPrefixCommand.php @@ -27,7 +27,7 @@ use Humbug\PhpScoper\Configuration\Throwable\UnknownConfigurationKey; use Humbug\PhpScoper\Console\ConfigLoader; use Humbug\PhpScoper\Console\ConsoleScoper; -use Humbug\PhpScoper\Container; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use InvalidArgumentException; use PhpParser\PhpVersion; use Symfony\Component\Console\Exception\RuntimeException; @@ -57,7 +57,7 @@ final class AddPrefixCommand implements Command, CommandAware private const CONTINUE_ON_FAILURE_OPT = 'continue-on-failure'; private const CONFIG_FILE_OPT = 'config'; private const NO_CONFIG_OPT = 'no-config'; - private const PHP_VERSION_OPT = 'no-config'; + private const PHP_VERSION_OPT = 'php-version'; private const DEFAULT_OUTPUT_DIR = 'build'; @@ -65,9 +65,9 @@ final class AddPrefixCommand implements Command, CommandAware public function __construct( private readonly Filesystem $fileSystem, + private readonly ScoperFactory $scoperFactory, private readonly Application $application, private readonly ConfigurationFactory $configFactory, - private readonly Container $container, ) { } @@ -137,7 +137,7 @@ public function getConfiguration(): CommandConfiguration self::PHP_VERSION_OPT, null, InputOption::VALUE_REQUIRED, - 'PHP version in which the PHP parser and printer will be configured.', + 'PHP version in which the PHP parser and printer will be configured, e.g. "7.2".', ), ], ); diff --git a/src/Console/Command/InspectCommand.php b/src/Console/Command/InspectCommand.php index 0735e786..0e401b50 100644 --- a/src/Console/Command/InspectCommand.php +++ b/src/Console/Command/InspectCommand.php @@ -26,6 +26,7 @@ use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use InvalidArgumentException; +use PhpParser\PhpVersion; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -49,6 +50,7 @@ final class InspectCommand implements Command, CommandAware private const PREFIX_OPT = 'prefix'; private const CONFIG_FILE_OPT = 'config'; private const NO_CONFIG_OPT = 'no-config'; + private const PHP_VERSION_OPT = 'php-version'; public function __construct( private readonly Filesystem $fileSystem, @@ -94,6 +96,12 @@ public function getConfiguration(): CommandConfiguration InputOption::VALUE_NONE, 'Do not look for a configuration file.', ), + new InputOption( + self::PHP_VERSION_OPT, + null, + InputOption::VALUE_REQUIRED, + 'PHP version in which the PHP parser and printer will be configured, e.g. "7.2".', + ), ], ); } @@ -108,6 +116,7 @@ public function execute(IO $io): int // working directory $cwd = getcwd(); + $phpversion = self::getPhpVersion($io); $filePath = $this->getFilePath($io, $cwd); $config = $this->retrieveConfig($io, [$filePath], $cwd); @@ -120,7 +129,13 @@ public function execute(IO $io): int $symbolsRegistry = new SymbolsRegistry(); $fileContents = $config->getFilesWithContents()[$filePath][1]; - $scopedContents = $this->scopeFile($config, $symbolsRegistry, $filePath, $fileContents); + $scopedContents = $this->scopeFile( + $config, + $symbolsRegistry, + $phpversion, + $filePath, + $fileContents, + ); $this->printScopedContents($io, $scopedContents, $symbolsRegistry); @@ -192,12 +207,14 @@ private function canonicalizePath(string $path, string $cwd): string private function scopeFile( Configuration $config, SymbolsRegistry $symbolsRegistry, + ?PhpVersion $phpversion, string $filePath, string $fileContents, ): string { $scoper = $this->scoperFactory->createScoper( $config, $symbolsRegistry, + $phpversion, ); return $scoper->scope( @@ -249,4 +266,15 @@ private static function exportSymbolsRegistry(SymbolsRegistry $symbolsRegistry, true, ); } + + private static function getPhpVersion(IO $io): ?PhpVersion + { + $version = $io + ->getTypedOption(self::PHP_VERSION_OPT) + ->asNullableString(); + + return null === $version + ? $version + : PhpVersion::fromString($version); + } } diff --git a/src/Console/ConsoleScoper.php b/src/Console/ConsoleScoper.php index 30bb489c..ed237d5b 100644 --- a/src/Console/ConsoleScoper.php +++ b/src/Console/ConsoleScoper.php @@ -19,6 +19,7 @@ use Humbug\PhpScoper\Autoload\ComposerFileHasher; use Humbug\PhpScoper\Autoload\ScoperAutoloadGenerator; use Humbug\PhpScoper\Configuration\Configuration; +use Humbug\PhpScoper\Scoper\Factory\ScoperFactory; use Humbug\PhpScoper\Scoper\Scoper; use Humbug\PhpScoper\Symbol\SymbolsRegistry; use Humbug\PhpScoper\Throwable\Exception\ParsingException; @@ -50,7 +51,7 @@ public function __construct( private Filesystem $fileSystem, private Application $application, - private Container $container, + private ScoperFactory $scoperFactory, ) { } @@ -189,11 +190,11 @@ private function scopeFiles( $resolvedPhpVersion = $phpVersion ?? $config->getPhpVersion(); - $scoper = $this->container - ->getScoperFactory($resolvedPhpVersion) + $scoper = $this->scoperFactory ->createScoper( $config, $symbolsRegistry, + $resolvedPhpVersion, ); foreach ($files as $file) { diff --git a/tests/Configuration/ConfigurationFactoryTest.php b/tests/Configuration/ConfigurationFactoryTest.php index aa8f3f1d..2a5dc3ce 100644 --- a/tests/Configuration/ConfigurationFactoryTest.php +++ b/tests/Configuration/ConfigurationFactoryTest.php @@ -24,6 +24,7 @@ use Humbug\PhpScoper\Patcher\SymfonyPatcher; use Humbug\PhpScoper\Symbol\NamespaceRegistry; use Humbug\PhpScoper\Symbol\SymbolRegistry; +use PhpParser\PhpVersion; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; use function array_keys; @@ -94,6 +95,7 @@ public function test_it_can_create_a_complete_configuration(): void return [ 'prefix' => 'MyPrefix', + 'php-version' => '7.2', 'output-dir' => 'dist', 'exclude-files' => ['file1', 'file2'], 'patchers' => [], @@ -126,29 +128,25 @@ public function test_it_can_create_a_complete_configuration(): void $configuration = $this->createConfigFromStandardFile(); - self::assertSame($this->tmp.DIRECTORY_SEPARATOR.'scoper.inc.php', $configuration->getPath()); - self::assertEquals(new Prefix('MyPrefix'), $configuration->getPrefix()); - self::assertSame('dist', $configuration->getOutputDir()); - self::assertSame([], $configuration->getFilesWithContents()); - self::assertSame( - [ + ConfigurationTest::assertStateIs( + configuration: $configuration, + expectedPath: $this->tmp.DIRECTORY_SEPARATOR.'scoper.inc.php', + expectedOutputDir: 'dist', + expectedPrefix: 'MyPrefix', + expectedPhpVersion: PhpVersion::fromComponents(7, 2), + expectedFilesWithContents: [], + expectedExcludedFilesWithContents: [ $this->tmp.DIRECTORY_SEPARATOR.'file1' => [ $this->tmp.DIRECTORY_SEPARATOR.'file1', '', ], ], - $configuration->getExcludedFilesWithContents(), - ); - self::assertEquals( - new PatcherChain([ + expectedPatcher: new PatcherChain([ new ComposerPatcher(), new SymfonyParentTraitPatcher(), new SymfonyPatcher(), ]), - $configuration->getPatcher(), - ); - self::assertEquals( - SymbolsConfiguration::create( + expectedSymbolsConfiguration: SymbolsConfiguration::create( false, false, false, @@ -162,7 +160,6 @@ public function test_it_can_create_a_complete_configuration(): void SymbolRegistry::create(), SymbolRegistry::createForConstants(), ), - $configuration->getSymbolsConfiguration(), ); } diff --git a/tests/Configuration/ConfigurationTest.php b/tests/Configuration/ConfigurationTest.php index 2c19ac6d..75d50b04 100644 --- a/tests/Configuration/ConfigurationTest.php +++ b/tests/Configuration/ConfigurationTest.php @@ -18,6 +18,7 @@ use Humbug\PhpScoper\Patcher\FakePatcher; use Humbug\PhpScoper\Patcher\Patcher; use Humbug\PhpScoper\Patcher\PatcherChain; +use PhpParser\PhpVersion; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; @@ -43,6 +44,7 @@ public function test_it_validates_the_prefix( null, null, $prefix, + null, [], [], new PatcherChain([]), @@ -56,6 +58,7 @@ public function test_it_can_create_a_new_instance_with_a_different_prefix(): voi '/path/to/config', '/path/to/outputDir', 'initialPrefix', + null, ['/path/to/fileA' => ['/path/to/fileA', 'fileAContent']], ['/path/to/fileB' => ['/path/to/fileB', 'fileBContent']], new FakePatcher(), @@ -82,6 +85,7 @@ public function test_it_can_create_a_new_instance_with_a_different_patcher(): vo '/path/to/config', '/path/to/outputDir', 'initialPrefix', + null, ['/path/to/fileA' => ['/path/to/fileA', 'fileAContent']], ['/path/to/fileB' => ['/path/to/fileB', 'fileBContent']], new FakePatcher(), @@ -97,7 +101,7 @@ public function test_it_can_create_a_new_instance_with_a_different_patcher(): vo $newConfig = $config->withPatcher($newPatcher); $expectedNewConfigValues = $values; - $expectedNewConfigValues[5] = $newPatcher; + $expectedNewConfigValues[6] = $newPatcher; self::assertStateIs($config, ...$values); self::assertStateIs($newConfig, ...$expectedNewConfigValues); @@ -116,11 +120,12 @@ public static function prefixProvider(): iterable ]; } - private static function assertStateIs( + public static function assertStateIs( Configuration $configuration, ?string $expectedPath, ?string $expectedOutputDir, string $expectedPrefix, + ?PhpVersion $expectedPhpVersion, array $expectedFilesWithContents, array $expectedExcludedFilesWithContents, Patcher $expectedPatcher, @@ -129,6 +134,7 @@ private static function assertStateIs( self::assertSame($expectedPath, $configuration->getPath()); self::assertSame($expectedOutputDir, $configuration->getOutputDir()); self::assertSame($expectedPrefix, $configuration->getPrefix()); + self::assertEquals($expectedPhpVersion, $configuration->getPhpVersion()); self::assertEqualsCanonicalizing( $expectedFilesWithContents, $configuration->getFilesWithContents(), diff --git a/tests/Scoper/Factory/StandardScoperFactoryTest.php b/tests/Scoper/Factory/StandardScoperFactoryTest.php index eb1fdf67..cb940408 100644 --- a/tests/Scoper/Factory/StandardScoperFactoryTest.php +++ b/tests/Scoper/Factory/StandardScoperFactoryTest.php @@ -48,6 +48,7 @@ public function test_it_can_create_a_scoper(): void null, null, '_Humbug', + null, [], [], new FakePatcher(), From 7a3aa4dc4a32f47bccf3add70b8671e18f2a9766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Sun, 16 Jun 2024 16:59:15 +0200 Subject: [PATCH 3/3] add docs --- README.md | 1 + docs/configuration.md | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/README.md b/README.md index 199c592f..b65643db 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ potentially very difficult to debug due to dissimilar or unsupported package ver - [Usage](#usage) - [Configuration](docs/configuration.md#configuration) - [Prefix](docs/configuration.md#prefix) + - [PHP Version](docs/configuration.md#php-version) - [Output directory](docs/configuration.md#output-directory) - [Finders and paths](docs/configuration.md#finders-and-paths) - [Patchers](docs/configuration.md#patchers) diff --git a/docs/configuration.md b/docs/configuration.md index 8a47c623..eb91f2d1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,6 +1,7 @@ ## Configuration - [Prefix](#prefix) +- [PHP-Version](#php-version) - [Output directory](#output-directory) - [Finders and paths](#finders-and-paths) - [Patchers](#patchers) @@ -28,6 +29,7 @@ use Isolated\Symfony\Component\Finder\Finder; return [ 'prefix' => null, // string|null + 'php-version' => null, // string|null 'output-dir' => null, // string|null 'finders' => [], // list 'patchers' => [], // list @@ -56,6 +58,15 @@ The prefix to be used to isolate the code. If `null` or `''` (empty string) is g then a random prefix will be automatically generated. +### PHP Version + +The PHP version provided is used to configure the underlying [PHP-Parser] Parser and Printer. This will not affect +the PHP internal symbols used by PHP-Scoper but may affect what code can be parsed and how the code will be printed. + +If `null` or `''` (empty string) is given, then the host version will be used, i.e. executing it with PHP 8.4 will +result in PHP 8.4 being used as the PHP version. + + ### Output directory The base output directory where the prefixed files will be generated. If `null` @@ -476,5 +487,6 @@ namespace Humbug\Acme; [box]: https://github.com/box-project/box [php-scoper-integration]: https://github.com/humbug/box#isolating-the-phar +[PHP-Parser]: https://github.com/nikic/PHP-Parser [phpstorm-stubs]: https://github.com/JetBrains/phpstorm-stubs [symfony_finder]: https://symfony.com/doc/current/components/finder.html