From 5eb8bbbba2166fc79bc83b220ed2912404bd1c6e Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 13 Mar 2024 15:02:20 +0100 Subject: [PATCH 01/13] Utilize composer min-php version to narrow PHP_VERSION_ID fix Update e2e-tests.yml add more tests fix rename class added config parameters fix test more tests test version parameters Update e2e-tests.yml prevent 'Comparison operation "<" between int<70205, 90000> and 70205 is always false.' strict errors downgrade composer/semver for brianium/paratest:4.0.0 compat should fix the php 7.2 CI build incorporate feedback spaces to tabs support more constants Narrow `PHP_VERSION` in version_compare() another test fix --- .github/workflows/e2e-tests.yml | 24 ++++ .github/workflows/static-analysis.yml | 5 + .github/workflows/tests.yml | 4 + conf/config.neon | 10 +- conf/parametersSchema.neon | 8 +- e2e/composer-max-version/.gitignore | 2 + e2e/composer-max-version/composer.json | 5 + e2e/composer-max-version/phpstan.neon | 2 + e2e/composer-max-version/test.php | 10 ++ e2e/composer-min-max-version/.gitignore | 2 + e2e/composer-min-max-version/composer.json | 5 + e2e/composer-min-max-version/phpstan.neon | 2 + e2e/composer-min-max-version/test.php | 10 ++ e2e/composer-min-open-end-version/.gitignore | 2 + .../composer.json | 5 + .../phpstan.neon | 2 + e2e/composer-min-open-end-version/test.php | 6 + e2e/composer-min-version-bc/.gitignore | 2 + e2e/composer-min-version-bc/composer.json | 5 + e2e/composer-min-version-bc/test.php | 7 + e2e/composer-min-version/.gitignore | 2 + e2e/composer-min-version/composer.json | 5 + e2e/composer-min-version/phpstan.neon | 2 + e2e/composer-min-version/test.php | 6 + e2e/composer-version-config-patch/.gitignore | 2 + .../composer.json | 5 + .../phpstan.neon | 2 + e2e/composer-version-config-patch/test.php | 7 + e2e/composer-version-config/.gitignore | 2 + e2e/composer-version-config/composer.json | 5 + e2e/composer-version-config/phpstan.neon | 6 + e2e/composer-version-config/test.php | 11 ++ src/Analyser/ConstantResolver.php | 69 +++++++++- src/Analyser/ConstantResolverFactory.php | 5 + .../ValidateIgnoredErrorsExtension.php | 2 +- src/Php/ComposerPhpVersionFactory.php | 126 ++++++++++++++++++ src/Php/PhpVersion.php | 21 ++- src/Php/PhpVersionFactoryFactory.php | 23 +++- src/Testing/PHPStanTestCase.php | 2 +- ...pareFunctionDynamicReturnTypeExtension.php | 38 +++++- 40 files changed, 440 insertions(+), 19 deletions(-) create mode 100644 e2e/composer-max-version/.gitignore create mode 100644 e2e/composer-max-version/composer.json create mode 100644 e2e/composer-max-version/phpstan.neon create mode 100644 e2e/composer-max-version/test.php create mode 100644 e2e/composer-min-max-version/.gitignore create mode 100644 e2e/composer-min-max-version/composer.json create mode 100644 e2e/composer-min-max-version/phpstan.neon create mode 100644 e2e/composer-min-max-version/test.php create mode 100644 e2e/composer-min-open-end-version/.gitignore create mode 100644 e2e/composer-min-open-end-version/composer.json create mode 100644 e2e/composer-min-open-end-version/phpstan.neon create mode 100644 e2e/composer-min-open-end-version/test.php create mode 100644 e2e/composer-min-version-bc/.gitignore create mode 100644 e2e/composer-min-version-bc/composer.json create mode 100644 e2e/composer-min-version-bc/test.php create mode 100644 e2e/composer-min-version/.gitignore create mode 100644 e2e/composer-min-version/composer.json create mode 100644 e2e/composer-min-version/phpstan.neon create mode 100644 e2e/composer-min-version/test.php create mode 100644 e2e/composer-version-config-patch/.gitignore create mode 100644 e2e/composer-version-config-patch/composer.json create mode 100644 e2e/composer-version-config-patch/phpstan.neon create mode 100644 e2e/composer-version-config-patch/test.php create mode 100644 e2e/composer-version-config/.gitignore create mode 100644 e2e/composer-version-config/composer.json create mode 100644 e2e/composer-version-config/phpstan.neon create mode 100644 e2e/composer-version-config/test.php create mode 100644 src/Php/ComposerPhpVersionFactory.php diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 4ca9c86329..5b38b2946d 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -270,6 +270,30 @@ jobs: cd e2e/baseline-uninit-prop-trait ../../bin/phpstan analyse --configuration test-no-baseline.neon --generate-baseline test-baseline.neon ../../bin/phpstan analyse --configuration test.neon + - script: | + cd e2e/composer-max-version + composer install + ../../bin/phpstan analyze test.php --level=0 + - script: | + cd e2e/composer-min-max-version + composer install + ../../bin/phpstan analyze test.php --level=0 + - script: | + cd e2e/composer-min-open-end-version + composer install + ../../bin/phpstan analyze test.php --level=0 + - script: | + cd e2e/composer-min-version-bc + composer install + ../../bin/phpstan analyze test.php --level=0 + - script: | + cd e2e/composer-min-version + composer install + ../../bin/phpstan analyze test.php --level=0 + - script: | + cd e2e/composer-version-config + composer install + ../../bin/phpstan analyze test.php --level=0 steps: - name: "Checkout" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 390bfa4b7e..88444b1c02 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -60,6 +60,11 @@ jobs: shell: bash run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" + - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" + if: matrix.php-version == '7.2' + run: composer require composer/semver:"3.4.0 as 1.7.2" + shell: bash + - name: "Paratest patch" if: matrix.php-version == '7.2' run: composer config extra.patches.brianium/paratest --json --merge '["patches/paratest.patch"]' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f1a49d48f3..f721d746af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -191,6 +191,10 @@ jobs: shell: bash run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" + - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" + run: composer require composer/semver:"3.4.0 as 1.7.2" + shell: bash + - name: "Paratest patch" run: composer config extra.patches.brianium/paratest --json --merge '["patches/paratest.patch"]' shell: bash diff --git a/conf/config.neon b/conf/config.neon index ac8f18be39..d88326f090 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -397,8 +397,16 @@ services: - class: PHPStan\Php\PhpVersionFactoryFactory arguments: - versionId: %phpVersion% + phpVersion: %phpVersion% composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths% + bleedingEdge: %featureToggles.bleedingEdge% + + - + class: PHPStan\Php\ComposerPhpVersionFactory + arguments: + phpVersion: %phpVersion% + composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths% + bleedingEdge: %featureToggles.bleedingEdge% - class: PHPStan\PhpDocParser\Lexer\Lexer diff --git a/conf/parametersSchema.neon b/conf/parametersSchema.neon index f33fc0ba5d..ad662bd08a 100644 --- a/conf/parametersSchema.neon +++ b/conf/parametersSchema.neon @@ -140,7 +140,13 @@ parametersSchema: minimumNumberOfJobsPerProcess: int(), buffer: int() ]) - phpVersion: schema(anyOf(schema(int(), min(70100), max(80399))), nullable()) + phpVersion: schema(anyOf( + schema(int(), min(70100), max(80399)), + structure([ + min: schema(int(), min(70100), max(80399)), + max: schema(int(), min(70100), max(80399)) + ]) + ), nullable()) polluteScopeWithLoopInitialAssignments: bool() polluteScopeWithAlwaysIterableForeach: bool() propertyAlwaysWrittenTags: listOf(string()) diff --git a/e2e/composer-max-version/.gitignore b/e2e/composer-max-version/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-max-version/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-max-version/composer.json b/e2e/composer-max-version/composer.json new file mode 100644 index 0000000000..4d4ca141ef --- /dev/null +++ b/e2e/composer-max-version/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": "<=8.3" + } +} diff --git a/e2e/composer-max-version/phpstan.neon b/e2e/composer-max-version/phpstan.neon new file mode 100644 index 0000000000..49d50a5bac --- /dev/null +++ b/e2e/composer-max-version/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../conf/bleedingEdge.neon diff --git a/e2e/composer-max-version/test.php b/e2e/composer-max-version/test.php new file mode 100644 index 0000000000..038f559122 --- /dev/null +++ b/e2e/composer-max-version/test.php @@ -0,0 +1,10 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<5, 8>', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); + +\PHPStan\Testing\assertType('-1|0|1', version_compare(PHP_VERSION, '7.0.0')); +\PHPStan\Testing\assertType('bool', version_compare(PHP_VERSION, '7.0.0', '<')); +\PHPStan\Testing\assertType('bool', version_compare(PHP_VERSION, '7.0.0', '>')); diff --git a/e2e/composer-min-max-version/.gitignore b/e2e/composer-min-max-version/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-min-max-version/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-min-max-version/composer.json b/e2e/composer-min-max-version/composer.json new file mode 100644 index 0000000000..869fd2ce42 --- /dev/null +++ b/e2e/composer-min-max-version/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": ">=8.1, <=8.2.99" + } +} diff --git a/e2e/composer-min-max-version/phpstan.neon b/e2e/composer-min-max-version/phpstan.neon new file mode 100644 index 0000000000..49d50a5bac --- /dev/null +++ b/e2e/composer-min-max-version/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../conf/bleedingEdge.neon diff --git a/e2e/composer-min-max-version/test.php b/e2e/composer-min-max-version/test.php new file mode 100644 index 0000000000..16eb8a452c --- /dev/null +++ b/e2e/composer-min-max-version/test.php @@ -0,0 +1,10 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('8', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<0, 2>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); + +\PHPStan\Testing\assertType('1', version_compare(PHP_VERSION, '7.0.0')); +\PHPStan\Testing\assertType('false', version_compare(PHP_VERSION, '7.0.0', '<')); +\PHPStan\Testing\assertType('true', version_compare(PHP_VERSION, '7.0.0', '>')); diff --git a/e2e/composer-min-open-end-version/.gitignore b/e2e/composer-min-open-end-version/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-min-open-end-version/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-min-open-end-version/composer.json b/e2e/composer-min-open-end-version/composer.json new file mode 100644 index 0000000000..b6303c6b77 --- /dev/null +++ b/e2e/composer-min-open-end-version/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": ">= 8.1" + } +} diff --git a/e2e/composer-min-open-end-version/phpstan.neon b/e2e/composer-min-open-end-version/phpstan.neon new file mode 100644 index 0000000000..49d50a5bac --- /dev/null +++ b/e2e/composer-min-open-end-version/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../conf/bleedingEdge.neon diff --git a/e2e/composer-min-open-end-version/test.php b/e2e/composer-min-open-end-version/test.php new file mode 100644 index 0000000000..40d291eefd --- /dev/null +++ b/e2e/composer-min-open-end-version/test.php @@ -0,0 +1,6 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<8, max>', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); diff --git a/e2e/composer-min-version-bc/.gitignore b/e2e/composer-min-version-bc/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-min-version-bc/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-min-version-bc/composer.json b/e2e/composer-min-version-bc/composer.json new file mode 100644 index 0000000000..9be64619f1 --- /dev/null +++ b/e2e/composer-min-version-bc/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": "^8.1" + } +} diff --git a/e2e/composer-min-version-bc/test.php b/e2e/composer-min-version-bc/test.php new file mode 100644 index 0000000000..7a04552626 --- /dev/null +++ b/e2e/composer-min-version-bc/test.php @@ -0,0 +1,7 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<5, max>', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); diff --git a/e2e/composer-min-version/.gitignore b/e2e/composer-min-version/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-min-version/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-min-version/composer.json b/e2e/composer-min-version/composer.json new file mode 100644 index 0000000000..9be64619f1 --- /dev/null +++ b/e2e/composer-min-version/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": "^8.1" + } +} diff --git a/e2e/composer-min-version/phpstan.neon b/e2e/composer-min-version/phpstan.neon new file mode 100644 index 0000000000..49d50a5bac --- /dev/null +++ b/e2e/composer-min-version/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../conf/bleedingEdge.neon diff --git a/e2e/composer-min-version/test.php b/e2e/composer-min-version/test.php new file mode 100644 index 0000000000..0ccf54de56 --- /dev/null +++ b/e2e/composer-min-version/test.php @@ -0,0 +1,6 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<8, 9>', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); diff --git a/e2e/composer-version-config-patch/.gitignore b/e2e/composer-version-config-patch/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-version-config-patch/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-version-config-patch/composer.json b/e2e/composer-version-config-patch/composer.json new file mode 100644 index 0000000000..d6103988c8 --- /dev/null +++ b/e2e/composer-version-config-patch/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": ">=8.0.2, <8.0.15" + } +} diff --git a/e2e/composer-version-config-patch/phpstan.neon b/e2e/composer-version-config-patch/phpstan.neon new file mode 100644 index 0000000000..49d50a5bac --- /dev/null +++ b/e2e/composer-version-config-patch/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - ../../conf/bleedingEdge.neon diff --git a/e2e/composer-version-config-patch/test.php b/e2e/composer-version-config-patch/test.php new file mode 100644 index 0000000000..fc3e9997ce --- /dev/null +++ b/e2e/composer-version-config-patch/test.php @@ -0,0 +1,7 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('8', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('0', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<1, 15>', PHP_RELEASE_VERSION); diff --git a/e2e/composer-version-config/.gitignore b/e2e/composer-version-config/.gitignore new file mode 100644 index 0000000000..3a9875b460 --- /dev/null +++ b/e2e/composer-version-config/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +composer.lock diff --git a/e2e/composer-version-config/composer.json b/e2e/composer-version-config/composer.json new file mode 100644 index 0000000000..2da0adaf1c --- /dev/null +++ b/e2e/composer-version-config/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "php": "^8.0" + } +} diff --git a/e2e/composer-version-config/phpstan.neon b/e2e/composer-version-config/phpstan.neon new file mode 100644 index 0000000000..04365f4376 --- /dev/null +++ b/e2e/composer-version-config/phpstan.neon @@ -0,0 +1,6 @@ +includes: + - ../../conf/bleedingEdge.neon +parameters: + phpVersion: + min: 80103 + max: 80304 diff --git a/e2e/composer-version-config/test.php b/e2e/composer-version-config/test.php new file mode 100644 index 0000000000..a9afaa4b65 --- /dev/null +++ b/e2e/composer-version-config/test.php @@ -0,0 +1,11 @@ +', PHP_VERSION_ID); +\PHPStan\Testing\assertType('8', PHP_MAJOR_VERSION); +\PHPStan\Testing\assertType('int<1, 3>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); + +\PHPStan\Testing\assertType('1', version_compare(PHP_VERSION, '7.0.0')); +\PHPStan\Testing\assertType('false', version_compare(PHP_VERSION, '7.0.0', '<')); +\PHPStan\Testing\assertType('true', version_compare(PHP_VERSION, '7.0.0', '>')); diff --git a/src/Analyser/ConstantResolver.php b/src/Analyser/ConstantResolver.php index d8df652c42..c28883ec43 100644 --- a/src/Analyser/ConstantResolver.php +++ b/src/Analyser/ConstantResolver.php @@ -3,6 +3,7 @@ namespace PHPStan\Analyser; use PhpParser\Node\Name; +use PHPStan\Php\PhpVersion; use PHPStan\Reflection\NamespaceAnswerer; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Reflection\ReflectionProvider\ReflectionProviderProvider; @@ -20,6 +21,7 @@ use PHPStan\Type\UnionType; use function array_key_exists; use function in_array; +use function max; use function sprintf; use const INF; use const NAN; @@ -34,7 +36,12 @@ class ConstantResolver /** * @param string[] $dynamicConstantNames */ - public function __construct(private ReflectionProviderProvider $reflectionProviderProvider, private array $dynamicConstantNames) + public function __construct( + private ReflectionProviderProvider $reflectionProviderProvider, + private array $dynamicConstantNames, + private ?PhpVersion $composerMinPhpVersion, + private ?PhpVersion $composerMaxPhpVersion, + ) { } @@ -77,16 +84,60 @@ public function resolvePredefinedConstant(string $resolvedConstantName): ?Type ]); } if ($resolvedConstantName === 'PHP_MAJOR_VERSION') { - return IntegerRangeType::fromInterval(5, null); + $minMajor = 5; + $maxMajor = null; + + if ($this->composerMinPhpVersion !== null) { + $minMajor = max($minMajor, $this->composerMinPhpVersion->getMajor()); + } + if ($this->composerMaxPhpVersion !== null) { + $maxMajor = $this->composerMaxPhpVersion->getMajor(); + } + + return $this->createInteger($minMajor, $maxMajor); } if ($resolvedConstantName === 'PHP_MINOR_VERSION') { - return IntegerRangeType::fromInterval(0, null); + $minMinor = 0; + $maxMinor = null; + + if ( + $this->composerMinPhpVersion !== null + && $this->composerMaxPhpVersion !== null + && $this->composerMaxPhpVersion->getMajor() === $this->composerMinPhpVersion->getMajor() + ) { + $minMinor = $this->composerMinPhpVersion->getMinor(); + $maxMinor = $this->composerMaxPhpVersion->getMinor(); + } + + return $this->createInteger($minMinor, $maxMinor); } if ($resolvedConstantName === 'PHP_RELEASE_VERSION') { - return IntegerRangeType::fromInterval(0, null); + $minRelease = 0; + $maxRelease = null; + + if ( + $this->composerMinPhpVersion !== null + && $this->composerMaxPhpVersion !== null + && $this->composerMaxPhpVersion->getMajor() === $this->composerMinPhpVersion->getMajor() + && $this->composerMaxPhpVersion->getMinor() === $this->composerMinPhpVersion->getMinor() + ) { + $minRelease = $this->composerMinPhpVersion->getPatch(); + $maxRelease = $this->composerMaxPhpVersion->getPatch(); + } + + return $this->createInteger($minRelease, $maxRelease); } if ($resolvedConstantName === 'PHP_VERSION_ID') { - return IntegerRangeType::fromInterval(50207, null); + $minVersion = 50207; + $maxVersion = null; + if ($this->composerMinPhpVersion !== null) { + $minVersion = max($minVersion, $this->composerMinPhpVersion->getVersionId()); + } + if ($this->composerMaxPhpVersion !== null) { + $maxVersion = $this->composerMaxPhpVersion->getVersionId(); + } + + return $this->createInteger($minVersion, $maxVersion); } if ($resolvedConstantName === 'PHP_ZTS') { return new UnionType([ @@ -325,6 +376,14 @@ public function resolveClassConstantType(string $className, string $constantName return $constantType; } + private function createInteger(?int $min, ?int $max): Type + { + if ($min !== null && $min === $max) { + return new ConstantIntegerType($min); + } + return IntegerRangeType::fromInterval($min, $max); + } + private function getReflectionProvider(): ReflectionProvider { return $this->reflectionProviderProvider->getReflectionProvider(); diff --git a/src/Analyser/ConstantResolverFactory.php b/src/Analyser/ConstantResolverFactory.php index bd63830f59..c5336d0c2c 100644 --- a/src/Analyser/ConstantResolverFactory.php +++ b/src/Analyser/ConstantResolverFactory.php @@ -3,6 +3,7 @@ namespace PHPStan\Analyser; use PHPStan\DependencyInjection\Container; +use PHPStan\Php\ComposerPhpVersionFactory; use PHPStan\Reflection\ReflectionProvider\ReflectionProviderProvider; class ConstantResolverFactory @@ -17,9 +18,13 @@ public function __construct( public function create(): ConstantResolver { + $composerFactory = $this->container->getByType(ComposerPhpVersionFactory::class); + return new ConstantResolver( $this->reflectionProviderProvider, $this->container->getParameter('dynamicConstantNames'), + $composerFactory->getMinVersion(), + $composerFactory->getMaxVersion(), ); } diff --git a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php index cd93ab2247..2b08f4cab8 100644 --- a/src/DependencyInjection/ValidateIgnoredErrorsExtension.php +++ b/src/DependencyInjection/ValidateIgnoredErrorsExtension.php @@ -61,7 +61,7 @@ public function loadConfiguration(): void $reflectionProviderProvider = new DirectReflectionProviderProvider($reflectionProvider); ReflectionProviderStaticAccessor::registerInstance($reflectionProvider); PhpVersionStaticAccessor::registerInstance(new PhpVersion(PHP_VERSION_ID)); - $constantResolver = new ConstantResolver($reflectionProviderProvider, []); + $constantResolver = new ConstantResolver($reflectionProviderProvider, [], null, null); $ignoredRegexValidator = new IgnoredRegexValidator( $parser, new TypeStringResolver( diff --git a/src/Php/ComposerPhpVersionFactory.php b/src/Php/ComposerPhpVersionFactory.php new file mode 100644 index 0000000000..17a44fd6f0 --- /dev/null +++ b/src/Php/ComposerPhpVersionFactory.php @@ -0,0 +1,126 @@ +minVersion = new PhpVersion($phpVersion['min']); + $this->maxVersion = new PhpVersion($phpVersion['max']); + + return; + } + + if (!$bleedingEdge) { + return; + } + + // fallback to composer.json based php-version constraint + $composerPhpVersion = $this->getComposerRequireVersion(); + if ($composerPhpVersion === null) { + return; + } + + $parser = new VersionParser(); + $constraint = $parser->parseConstraints($composerPhpVersion); + + if ($this->minVersion === null && !$constraint->getLowerBound()->isZero()) { + $minVersion = $this->buildVersion($constraint->getLowerBound()->getVersion()); + // allow checks with < below lower bound to prevent errors like + // 'Comparison operation "<" between int<70205, 90000> and 70205 is always false.' + if ($minVersion !== null) { + $this->minVersion = new PhpVersion($minVersion->getVersionId() - 1); + } + } + if ($this->maxVersion !== null || $constraint->getUpperBound()->isPositiveInfinity()) { + return; + } + + $this->maxVersion = $this->buildVersion($constraint->getUpperBound()->getVersion()); + } + + public function getMinVersion(): ?PhpVersion + { + return $this->minVersion; + } + + public function getMaxVersion(): ?PhpVersion + { + return $this->maxVersion; + } + + private function getComposerRequireVersion(): ?string + { + $composerPhpVersion = null; + if (count($this->composerAutoloaderProjectPaths) > 0) { + $composerJsonPath = end($this->composerAutoloaderProjectPaths) . '/composer.json'; + if (is_file($composerJsonPath)) { + try { + $composerJsonContents = FileReader::read($composerJsonPath); + $composer = Json::decode($composerJsonContents, Json::FORCE_ARRAY); + $requiredVersion = $composer['require']['php'] ?? null; + if (is_string($requiredVersion)) { + $composerPhpVersion = $requiredVersion; + } + } catch (CouldNotReadFileException | JsonException) { + // pass + } + } + } + return $composerPhpVersion; + } + + private function buildVersion(string $minVersion): ?PhpVersion + { + $matches = Strings::match($minVersion, '#^(\d+)\.(\d+)(?:\.(\d+))?#'); + if ($matches === null) { + return null; + } + + $major = $matches[1]; + $minor = $matches[2]; + $patch = $matches[3] ?? 0; + $versionId = (int) sprintf('%d%02d%02d', $major, $minor, $patch); + + return new PhpVersion($versionId); + } + +} diff --git a/src/Php/PhpVersion.php b/src/Php/PhpVersion.php index c5afa1e22f..65e59878fb 100644 --- a/src/Php/PhpVersion.php +++ b/src/Php/PhpVersion.php @@ -39,11 +39,26 @@ public function getVersionId(): int return $this->versionId; } + public function getMajor(): int + { + return (int) floor($this->versionId / 10000); + } + + public function getMinor(): int + { + return (int) floor(($this->versionId % 10000) / 100); + } + + public function getPatch(): int + { + return (int) floor($this->versionId % 100); + } + public function getVersionString(): string { - $first = (int) floor($this->versionId / 10000); - $second = (int) floor(($this->versionId % 10000) / 100); - $third = (int) floor($this->versionId % 100); + $first = $this->getMajor(); + $second = $this->getMinor(); + $third = $this->getPatch(); return $first . '.' . $second . ($third !== 0 ? '.' . $third : ''); } diff --git a/src/Php/PhpVersionFactoryFactory.php b/src/Php/PhpVersionFactoryFactory.php index 870d1ff276..cf8cefe868 100644 --- a/src/Php/PhpVersionFactoryFactory.php +++ b/src/Php/PhpVersionFactoryFactory.php @@ -6,20 +6,26 @@ use Nette\Utils\JsonException; use PHPStan\File\CouldNotReadFileException; use PHPStan\File\FileReader; +use PHPStan\ShouldNotHappenException; +use function array_key_exists; use function count; use function end; +use function is_array; use function is_file; +use function is_int; use function is_string; class PhpVersionFactoryFactory { /** + * @param int|array{min: int, max: int}|null $phpVersion * @param string[] $composerAutoloaderProjectPaths */ public function __construct( - private ?int $versionId, + private int|array|null $phpVersion, private array $composerAutoloaderProjectPaths, + private bool $bleedingEdge, ) { } @@ -43,7 +49,20 @@ public function create(): PhpVersionFactory } } - return new PhpVersionFactory($this->versionId, $composerPhpVersion); + $versionId = null; + + if (is_int($this->phpVersion)) { + $versionId = $this->phpVersion; + } + + if ($this->bleedingEdge && is_array($this->phpVersion)) { + if (!array_key_exists('min', $this->phpVersion)) { + throw new ShouldNotHappenException(); + } + $versionId = $this->phpVersion['min']; + } + + return new PhpVersionFactory($versionId, $composerPhpVersion); } } diff --git a/src/Testing/PHPStanTestCase.php b/src/Testing/PHPStanTestCase.php index 14efcc7480..3b50ad9586 100644 --- a/src/Testing/PHPStanTestCase.php +++ b/src/Testing/PHPStanTestCase.php @@ -166,7 +166,7 @@ public static function createScopeFactory(ReflectionProvider $reflectionProvider } $reflectionProviderProvider = new DirectReflectionProviderProvider($reflectionProvider); - $constantResolver = new ConstantResolver($reflectionProviderProvider, $dynamicConstantNames); + $constantResolver = new ConstantResolver($reflectionProviderProvider, $dynamicConstantNames, null, null); return new ScopeFactory( new DirectInternalScopeFactory( diff --git a/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php b/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php index b8a77540cb..9802436f3b 100644 --- a/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php +++ b/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php @@ -2,12 +2,15 @@ namespace PHPStan\Type\Php; +use PhpParser\Node\Expr; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; +use PHPStan\Php\ComposerPhpVersionFactory; use PHPStan\Reflection\FunctionReflection; use PHPStan\Type\BooleanType; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantIntegerType; +use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\DynamicFunctionReturnTypeExtension; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; @@ -18,6 +21,10 @@ class VersionCompareFunctionDynamicReturnTypeExtension implements DynamicFunctionReturnTypeExtension { + public function __construct(private ComposerPhpVersionFactory $composerPhpVersionFactory) + { + } + public function isFunctionSupported(FunctionReflection $functionReflection): bool { return $functionReflection->getName() === 'version_compare'; @@ -29,19 +36,20 @@ public function getTypeFromFunctionCall( Scope $scope, ): ?Type { - if (count($functionCall->getArgs()) < 2) { + $args = $functionCall->getArgs(); + if (count($args) < 2) { return null; } - $version1Strings = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings(); - $version2Strings = $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings(); + $version1Strings = $this->getVersionStrings($args[0]->value, $scope); + $version2Strings = $this->getVersionStrings($args[1]->value, $scope); $counts = [ count($version1Strings), count($version2Strings), ]; - if (isset($functionCall->getArgs()[2])) { - $operatorStrings = $scope->getType($functionCall->getArgs()[2]->value)->getConstantStrings(); + if (isset($args[2])) { + $operatorStrings = $scope->getType($args[2]->value)->getConstantStrings(); $counts[] = count($operatorStrings); $returnType = new BooleanType(); } else { @@ -77,4 +85,24 @@ public function getTypeFromFunctionCall( return TypeCombinator::union(...$types); } + /** + * @return ConstantStringType[] + */ + private function getVersionStrings(Expr $expr, Scope $scope): array + { + if ( + $expr instanceof Expr\ConstFetch + && $expr->name->toString() === 'PHP_VERSION' + && $this->composerPhpVersionFactory->getMinVersion() !== null + && $this->composerPhpVersionFactory->getMaxVersion() !== null + ) { + return [ + new ConstantStringType($this->composerPhpVersionFactory->getMinVersion()->getVersionString()), + new ConstantStringType($this->composerPhpVersionFactory->getMaxVersion()->getVersionString()), + ]; + } + + return $scope->getType($expr)->getConstantStrings(); + } + } From 0aa5fd2a257d2657aba91aed7a77fbffbec3ed1a Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 1 Jun 2024 17:14:26 +0200 Subject: [PATCH 02/13] cleanup --- src/Php/ComposerPhpVersionFactory.php | 10 ++-------- src/Php/PhpVersionFactoryFactory.php | 5 ----- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/Php/ComposerPhpVersionFactory.php b/src/Php/ComposerPhpVersionFactory.php index 17a44fd6f0..1036f7feb5 100644 --- a/src/Php/ComposerPhpVersionFactory.php +++ b/src/Php/ComposerPhpVersionFactory.php @@ -13,7 +13,6 @@ use function end; use function is_array; use function is_file; -use function is_int; use function is_string; use function sprintf; @@ -34,10 +33,6 @@ public function __construct( bool $bleedingEdge, ) { - if (is_int($phpVersion)) { - return; - } - if (is_array($phpVersion)) { if ($phpVersion['max'] < $phpVersion['min']) { throw new ShouldNotHappenException('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.'); @@ -64,10 +59,9 @@ public function __construct( if ($this->minVersion === null && !$constraint->getLowerBound()->isZero()) { $minVersion = $this->buildVersion($constraint->getLowerBound()->getVersion()); - // allow checks with < below lower bound to prevent errors like - // 'Comparison operation "<" between int<70205, 90000> and 70205 is always false.' + if ($minVersion !== null) { - $this->minVersion = new PhpVersion($minVersion->getVersionId() - 1); + $this->minVersion = new PhpVersion($minVersion->getVersionId()); } } if ($this->maxVersion !== null || $constraint->getUpperBound()->isPositiveInfinity()) { diff --git a/src/Php/PhpVersionFactoryFactory.php b/src/Php/PhpVersionFactoryFactory.php index cf8cefe868..0319664c1c 100644 --- a/src/Php/PhpVersionFactoryFactory.php +++ b/src/Php/PhpVersionFactoryFactory.php @@ -6,8 +6,6 @@ use Nette\Utils\JsonException; use PHPStan\File\CouldNotReadFileException; use PHPStan\File\FileReader; -use PHPStan\ShouldNotHappenException; -use function array_key_exists; use function count; use function end; use function is_array; @@ -56,9 +54,6 @@ public function create(): PhpVersionFactory } if ($this->bleedingEdge && is_array($this->phpVersion)) { - if (!array_key_exists('min', $this->phpVersion)) { - throw new ShouldNotHappenException(); - } $versionId = $this->phpVersion['min']; } From c38dc9ef030ca464555efcec0d7dd978b659ec24 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 1 Jun 2024 17:17:49 +0200 Subject: [PATCH 03/13] simplify --- src/Php/ComposerPhpVersionFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Php/ComposerPhpVersionFactory.php b/src/Php/ComposerPhpVersionFactory.php index 1036f7feb5..8decdb3bdc 100644 --- a/src/Php/ComposerPhpVersionFactory.php +++ b/src/Php/ComposerPhpVersionFactory.php @@ -57,14 +57,14 @@ public function __construct( $parser = new VersionParser(); $constraint = $parser->parseConstraints($composerPhpVersion); - if ($this->minVersion === null && !$constraint->getLowerBound()->isZero()) { + if (!$constraint->getLowerBound()->isZero()) { $minVersion = $this->buildVersion($constraint->getLowerBound()->getVersion()); if ($minVersion !== null) { $this->minVersion = new PhpVersion($minVersion->getVersionId()); } } - if ($this->maxVersion !== null || $constraint->getUpperBound()->isPositiveInfinity()) { + if ($constraint->getUpperBound()->isPositiveInfinity()) { return; } From 2a29c80dd8581f0f2055b596d671b96cf30f350c Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 1 Jun 2024 17:36:13 +0200 Subject: [PATCH 04/13] validate php-version earlier --- .github/workflows/e2e-tests.yml | 6 +++++- e2e/composer-version-config-invalid/phpstan.neon | 7 +++++++ src/DependencyInjection/ContainerFactory.php | 12 ++++++++++++ .../InvalidPhpVersionException.php | 10 ++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 e2e/composer-version-config-invalid/phpstan.neon create mode 100644 src/DependencyInjection/InvalidPhpVersionException.php diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 5b38b2946d..ca698787b3 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -294,7 +294,11 @@ jobs: cd e2e/composer-version-config composer install ../../bin/phpstan analyze test.php --level=0 - + - script: | + cd e2e/composer-version-config-invalid + OUTPUT=$(../../bin/phpstan 2>&1) + grep 'Invalid configuration' <<< "$OUTPUT" + grep 'Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.' <<< "$OUTPUT" steps: - name: "Checkout" uses: actions/checkout@v4 diff --git a/e2e/composer-version-config-invalid/phpstan.neon b/e2e/composer-version-config-invalid/phpstan.neon new file mode 100644 index 0000000000..71a6bb7c5a --- /dev/null +++ b/e2e/composer-version-config-invalid/phpstan.neon @@ -0,0 +1,7 @@ +includes: + - ../../conf/bleedingEdge.neon +parameters: + phpVersion: + min: 80303 + max: 80104 + diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index cb3bf3006a..17c98cc709 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -7,6 +7,7 @@ use Nette\DI\Definitions\Statement; use Nette\DI\Extensions\ExtensionsExtension; use Nette\DI\Helpers; +use Nette\DI\InvalidConfigurationException; use Nette\Schema\Context as SchemaContext; use Nette\Schema\Elements\AnyOf; use Nette\Schema\Elements\Structure; @@ -352,6 +353,17 @@ private function validateParameters(array $parameters, array $parametersSchema): $context->path = ['parameters']; }; $processor->process($schema, $parameters); + + if ( + array_key_exists('phpVersion', $parameters) + && is_array($parameters['phpVersion'])) + { + $phpVersion = $parameters['phpVersion']; + + if ($phpVersion['max'] < $phpVersion['min']) { + throw new InvalidPhpVersionException('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.'); + } + } } /** diff --git a/src/DependencyInjection/InvalidPhpVersionException.php b/src/DependencyInjection/InvalidPhpVersionException.php new file mode 100644 index 0000000000..4195f26759 --- /dev/null +++ b/src/DependencyInjection/InvalidPhpVersionException.php @@ -0,0 +1,10 @@ + Date: Sat, 1 Jun 2024 17:42:27 +0200 Subject: [PATCH 05/13] fix expectations --- e2e/composer-min-max-version/test.php | 4 ++-- e2e/composer-min-open-end-version/test.php | 2 +- e2e/composer-min-version/test.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/e2e/composer-min-max-version/test.php b/e2e/composer-min-max-version/test.php index 16eb8a452c..28d770f3bb 100644 --- a/e2e/composer-min-max-version/test.php +++ b/e2e/composer-min-max-version/test.php @@ -1,8 +1,8 @@ ', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<80100, 80299>', PHP_VERSION_ID); \PHPStan\Testing\assertType('8', PHP_MAJOR_VERSION); -\PHPStan\Testing\assertType('int<0, 2>', PHP_MINOR_VERSION); +\PHPStan\Testing\assertType('int<1, 2>', PHP_MINOR_VERSION); \PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); \PHPStan\Testing\assertType('1', version_compare(PHP_VERSION, '7.0.0')); diff --git a/e2e/composer-min-open-end-version/test.php b/e2e/composer-min-open-end-version/test.php index 40d291eefd..d35bd6bca0 100644 --- a/e2e/composer-min-open-end-version/test.php +++ b/e2e/composer-min-open-end-version/test.php @@ -1,6 +1,6 @@ ', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<80100, max>', PHP_VERSION_ID); \PHPStan\Testing\assertType('int<8, max>', PHP_MAJOR_VERSION); \PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); \PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); diff --git a/e2e/composer-min-version/test.php b/e2e/composer-min-version/test.php index 0ccf54de56..a88c78b607 100644 --- a/e2e/composer-min-version/test.php +++ b/e2e/composer-min-version/test.php @@ -1,6 +1,6 @@ ', PHP_VERSION_ID); +\PHPStan\Testing\assertType('int<80100, 90000>', PHP_VERSION_ID); \PHPStan\Testing\assertType('int<8, 9>', PHP_MAJOR_VERSION); \PHPStan\Testing\assertType('int<0, max>', PHP_MINOR_VERSION); \PHPStan\Testing\assertType('int<0, max>', PHP_RELEASE_VERSION); From dcd31dc2c85e644d69a5a3ffe7ffa1df8ce0af14 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 1 Jun 2024 17:47:49 +0200 Subject: [PATCH 06/13] fix e2e tests --- .github/workflows/e2e-tests.yml | 2 +- src/DependencyInjection/ContainerFactory.php | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index ca698787b3..f9e623824b 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -296,7 +296,7 @@ jobs: ../../bin/phpstan analyze test.php --level=0 - script: | cd e2e/composer-version-config-invalid - OUTPUT=$(../../bin/phpstan 2>&1) + OUTPUT=$(../../bin/phpstan 2>&1 || true) grep 'Invalid configuration' <<< "$OUTPUT" grep 'Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.' <<< "$OUTPUT" steps: diff --git a/src/DependencyInjection/ContainerFactory.php b/src/DependencyInjection/ContainerFactory.php index 17c98cc709..423f413fd7 100644 --- a/src/DependencyInjection/ContainerFactory.php +++ b/src/DependencyInjection/ContainerFactory.php @@ -7,7 +7,6 @@ use Nette\DI\Definitions\Statement; use Nette\DI\Extensions\ExtensionsExtension; use Nette\DI\Helpers; -use Nette\DI\InvalidConfigurationException; use Nette\Schema\Context as SchemaContext; use Nette\Schema\Elements\AnyOf; use Nette\Schema\Elements\Structure; @@ -37,6 +36,7 @@ use PHPStan\Type\ObjectType; use Symfony\Component\Finder\Finder; use function array_diff_key; +use function array_key_exists; use function array_map; use function array_merge; use function array_unique; @@ -355,14 +355,15 @@ private function validateParameters(array $parameters, array $parametersSchema): $processor->process($schema, $parameters); if ( - array_key_exists('phpVersion', $parameters) - && is_array($parameters['phpVersion'])) - { - $phpVersion = $parameters['phpVersion']; + !array_key_exists('phpVersion', $parameters) + || !is_array($parameters['phpVersion'])) { + return; + } - if ($phpVersion['max'] < $phpVersion['min']) { - throw new InvalidPhpVersionException('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.'); - } + $phpVersion = $parameters['phpVersion']; + + if ($phpVersion['max'] < $phpVersion['min']) { + throw new InvalidPhpVersionException('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.'); } } From 3f680e4673cef8416a59021072038cf1d5967b5e Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 2 Jun 2024 08:31:28 +0200 Subject: [PATCH 07/13] try to fix build --- src/Php/ComposerPhpVersionFactory.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Php/ComposerPhpVersionFactory.php b/src/Php/ComposerPhpVersionFactory.php index 8decdb3bdc..baaaf75240 100644 --- a/src/Php/ComposerPhpVersionFactory.php +++ b/src/Php/ComposerPhpVersionFactory.php @@ -13,6 +13,7 @@ use function end; use function is_array; use function is_file; +use function is_int; use function is_string; use function sprintf; @@ -33,6 +34,10 @@ public function __construct( bool $bleedingEdge, ) { + if (is_int($phpVersion)) { + return; + } + if (is_array($phpVersion)) { if ($phpVersion['max'] < $phpVersion['min']) { throw new ShouldNotHappenException('Invalid PHP version range: phpVersion.max should be greater or equal to phpVersion.min.'); From 8b13baa98ec3fdfae2ebc78ddc2ce0ab8c58038a Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 09:16:27 +0200 Subject: [PATCH 08/13] Update composer.lock --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 534df49be6..7dafe8c030 100644 --- a/composer.lock +++ b/composer.lock @@ -219,16 +219,16 @@ }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", "shasum": "" }, "require": { @@ -280,7 +280,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.2" }, "funding": [ { @@ -296,7 +296,7 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-07-12T11:35:52+00:00" }, { "name": "composer/xdebug-handler", From fd369d0e5d52a09e83b57896e260e0eadf7ee305 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 22:49:09 +0200 Subject: [PATCH 09/13] update composer/semver --- .github/workflows/static-analysis.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 88444b1c02..47f3a291b9 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -62,7 +62,7 @@ jobs: - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" if: matrix.php-version == '7.2' - run: composer require composer/semver:"3.4.0 as 1.7.2" + run: composer require composer/semver:"3.4.2 as 1.7.2" shell: bash - name: "Paratest patch" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f721d746af..e8d3aaa28f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -192,7 +192,7 @@ jobs: run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" - run: composer require composer/semver:"3.4.0 as 1.7.2" + run: composer require composer/semver:"3.4.2 as 1.7.2" shell: bash - name: "Paratest patch" From 49f01cdb76fd53ff374da427f142c9b7b13e1212 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 23:17:16 +0200 Subject: [PATCH 10/13] try fix php 7.2 build --- .github/workflows/static-analysis.yml | 10 +++++----- .github/workflows/tests.yml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 47f3a291b9..f4fd1f9c29 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -55,16 +55,16 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Transform source code" - if: matrix.php-version != '8.1' && matrix.php-version != '8.2' && matrix.php-version != '8.3' - shell: bash - run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" - - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" if: matrix.php-version == '7.2' run: composer require composer/semver:"3.4.2 as 1.7.2" shell: bash + - name: "Transform source code" + if: matrix.php-version != '8.1' && matrix.php-version != '8.2' && matrix.php-version != '8.3' + shell: bash + run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" + - name: "Paratest patch" if: matrix.php-version == '7.2' run: composer config extra.patches.brianium/paratest --json --merge '["patches/paratest.patch"]' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e8d3aaa28f..cde3fbff5b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -187,14 +187,14 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Transform source code" - shell: bash - run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" - - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" run: composer require composer/semver:"3.4.2 as 1.7.2" shell: bash + - name: "Transform source code" + shell: bash + run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" + - name: "Paratest patch" run: composer config extra.patches.brianium/paratest --json --merge '["patches/paratest.patch"]' shell: bash From fa2949b5bb4bd733739b3133908e0b9f558ebb72 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 23:20:21 +0200 Subject: [PATCH 11/13] Discard changes to .github/workflows/static-analysis.yml --- .github/workflows/static-analysis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index f4fd1f9c29..390bfa4b7e 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -55,11 +55,6 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" - if: matrix.php-version == '7.2' - run: composer require composer/semver:"3.4.2 as 1.7.2" - shell: bash - - name: "Transform source code" if: matrix.php-version != '8.1' && matrix.php-version != '8.2' && matrix.php-version != '8.3' shell: bash From e1e38cadad7db995fdfff8007fb1ffcff5fe0d92 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 23:20:25 +0200 Subject: [PATCH 12/13] Discard changes to .github/workflows/tests.yml --- .github/workflows/tests.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cde3fbff5b..f1a49d48f3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -187,10 +187,6 @@ jobs: - name: "Install dependencies" run: "composer install --no-interaction --no-progress" - - name: "Downgrade composer/semver for brianium/paratest:4.0.0 compatibility" - run: composer require composer/semver:"3.4.2 as 1.7.2" - shell: bash - - name: "Transform source code" shell: bash run: "vendor/bin/simple-downgrade downgrade -c build/downgrade.php ${{ matrix.php-version }}" From 2a593f7f6f96b38ea04aa348757a02950be22b7d Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 20 Jul 2024 23:20:29 +0200 Subject: [PATCH 13/13] Discard changes to composer.lock --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 7dafe8c030..534df49be6 100644 --- a/composer.lock +++ b/composer.lock @@ -219,16 +219,16 @@ }, { "name": "composer/semver", - "version": "3.4.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", "shasum": "" }, "require": { @@ -280,7 +280,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.2" + "source": "https://github.com/composer/semver/tree/3.4.0" }, "funding": [ { @@ -296,7 +296,7 @@ "type": "tidelift" } ], - "time": "2024-07-12T11:35:52+00:00" + "time": "2023-08-31T09:50:34+00:00" }, { "name": "composer/xdebug-handler",