Skip to content

Commit 9a0db79

Browse files
committed
Use different PHP version information for PHPCS and PHPStant
* Split version decorators in MinimalVersionDecorator and VersionDecorator * Updated min versions of some dependencies
1 parent 943bb7a commit 9a0db79

File tree

21 files changed

+484
-102
lines changed

21 files changed

+484
-102
lines changed

composer.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
"ext-xml": "*",
3030
"composer-runtime-api": "^2.0",
3131
"bamarni/composer-bin-plugin": "^1.8",
32-
"composer/semver": "^3.3",
32+
"composer/semver": "^3.4",
3333
"dealerdirect/phpcodesniffer-composer-installer": "^1.0.0",
3434
"nette/neon": "^3.3",
35-
"nikic/php-parser": "^4.15",
35+
"nikic/php-parser": "^4.18",
3636
"php-di/php-di": "^7.0.1",
3737
"slevomat/coding-standard": "^8.10.0",
3838
"squizlabs/php_codesniffer": "^3.7.2",
@@ -47,10 +47,10 @@
4747
"amphp/amp": "^v2.6.2",
4848
"amphp/phpunit-util": "^2.0.0",
4949
"amphp/process": "^v1.1.4",
50-
"brianium/paratest": "^6.8.1",
51-
"infection/infection": ">=0.26.16",
52-
"mockery/mockery": "^1.5.1",
53-
"phpunit/phpunit": "^9.5.28",
50+
"brianium/paratest": "^6.11.0",
51+
"infection/infection": ">=0.27.9",
52+
"mockery/mockery": "^1.6.7",
53+
"phpunit/phpunit": "^9.6.16",
5454
"roave/security-advisories": "dev-latest",
5555
"sebastianknott/hamcrest-object-accessor": "^3.0.0"
5656
},

src/main/php/CommandLine/ApplicationLifeCycle/EventDispatcherFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Extension\FileExtensionDecorator;
1111
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Fix\FixDecorator;
1212
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Multiprocess\MultiprocessDecorator;
13+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\MinimalVersionDecorator;
1314
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\VersionDecorator;
1415
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Target\TargetDecorator;
1516
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Verbose\VerboseDecorator;
@@ -32,6 +33,7 @@ class EventDispatcherFactory
3233
TargetDecorator::class,
3334
VerboseDecorator::class,
3435
MultiprocessDecorator::class,
36+
MinimalVersionDecorator::class,
3537
VersionDecorator::class,
3638
];
3739

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
6+
7+
use JsonException;
8+
use Safe\Exceptions\FilesystemException;
9+
use Zooroyal\CodingStandard\CommandLine\EnhancedFileInfo\EnhancedFileInfoFactory;
10+
use Zooroyal\CodingStandard\CommandLine\Environment\Environment;
11+
12+
use function Safe\file_get_contents;
13+
14+
class ComposerInterpreter
15+
{
16+
public function __construct(
17+
private readonly Environment $environment,
18+
private readonly EnhancedFileInfoFactory $enhancedFileInfoFactory,
19+
private readonly ConstraintToVersionConverter $constraintToVersionConverter,
20+
) {
21+
}
22+
23+
/**
24+
* Get local php-version-constraints from root composer.json.
25+
*
26+
* @throws FilesystemException
27+
* @throws JsonException
28+
*/
29+
public function getLocalPhpVersionConstraint(): string
30+
{
31+
$rootDirectory = $this->environment->getRootDirectory();
32+
$path = $rootDirectory->getRealPath();
33+
$composerFile = $this->enhancedFileInfoFactory->buildFromPath($path . '/composer.json');
34+
$composerConfig = json_decode(
35+
file_get_contents($composerFile->getRealPath()),
36+
associative: true,
37+
flags: JSON_THROW_ON_ERROR
38+
);
39+
40+
$phpVersionConstraint = $composerConfig['config']['platform']['php']
41+
?? $composerConfig['require']['php']
42+
?? '*';
43+
44+
$phpVersionConstraintExtracted = $this->constraintToVersionConverter
45+
->extractActualPhpVersion($phpVersionConstraint);
46+
47+
return $phpVersionConstraintExtracted;
48+
}
49+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
6+
7+
use Composer\Semver\Semver;
8+
9+
use function Safe\preg_match;
10+
11+
class ConstraintToVersionConverter
12+
{
13+
/** @var array<string> */
14+
private array $phpVersions = [];
15+
16+
public function __construct()
17+
{
18+
$phpVersionRanges = [
19+
'7.4.' => '33',
20+
'8.0.' => '27',
21+
'8.1.' => '17',
22+
'8.2.' => (explode('.', phpversion()))[2],
23+
];
24+
25+
foreach ($phpVersionRanges as $phpVersionString => $phpMaxPatchVersion) {
26+
$phpPatchLevels = range('0', $phpMaxPatchVersion);
27+
foreach ($phpPatchLevels as $phpPatchLevel) {
28+
$this->phpVersions[] = $phpVersionString . $phpPatchLevel;
29+
}
30+
}
31+
}
32+
33+
/**
34+
* Check if $phpVersionConstraint is a version number and return it or if we find a php version that satisfies
35+
* the constraint.
36+
*/
37+
public function extractActualPhpVersion(string $phpVersionConstraint): string
38+
{
39+
if (preg_match('/^(\d+)(\.\d)?(\.\d)?$/', $phpVersionConstraint, $matches)) {
40+
return $matches[1] . ($matches[2] ?? '.0') . ($matches[3] ?? '.0');
41+
}
42+
43+
$minPhpVersion = '7.4.0';
44+
foreach ($this->phpVersions as $phpVersion) {
45+
if (SemVer::satisfies($phpVersion, $phpVersionConstraint)) {
46+
$minPhpVersion = $phpVersion;
47+
break;
48+
}
49+
}
50+
return $minPhpVersion;
51+
}
52+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
6+
7+
use Symfony\Component\Console\Output\OutputInterface;
8+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\DecorateEvent;
9+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\TerminalCommandDecorator;
10+
11+
class MinimalVersionDecorator extends TerminalCommandDecorator
12+
{
13+
private ?string $cachedMinPhpVersion = null;
14+
15+
public function __construct(
16+
private readonly ConstraintToVersionConverter $constraintToVersionConverter,
17+
private readonly ComposerInterpreter $composerInterpreter,
18+
) {
19+
}
20+
21+
public function decorate(DecorateEvent $event): void
22+
{
23+
$terminalCommand = $event->getTerminalCommand();
24+
25+
if (!$terminalCommand instanceof MinimalVersionDependantTerminalCommand) {
26+
return;
27+
}
28+
29+
if ($this->cachedMinPhpVersion === null) {
30+
$phpVersionConstraint = $this->composerInterpreter->getLocalPhpVersionConstraint();
31+
32+
$this->cachedMinPhpVersion = $this->constraintToVersionConverter
33+
->extractActualPhpVersion($phpVersionConstraint);
34+
}
35+
36+
$terminalCommand->setMinimalPhpVersion($this->cachedMinPhpVersion);
37+
38+
$event->getOutput()->writeln(
39+
'<info>Targeted minimal PHP version is ' . $this->cachedMinPhpVersion . '</info>' . PHP_EOL,
40+
OutputInterface::VERBOSITY_VERBOSE,
41+
);
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
6+
7+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\TerminalCommand;
8+
9+
interface MinimalVersionDependantTerminalCommand extends TerminalCommand
10+
{
11+
/**
12+
* This method receives the minimal php version the source code to check is written in.
13+
*/
14+
public function setMinimalPhpVersion(string $phpVersion): void;
15+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
6+
7+
trait MinimalVersionDependentTrait
8+
{
9+
protected string $minimalPhpVersion = '7.4';
10+
11+
/**
12+
* {@inheritDoc}
13+
*/
14+
public function setMinimalPhpVersion(string $minimalPhpVersion): void
15+
{
16+
$this->minimalPhpVersion = $minimalPhpVersion;
17+
}
18+
}

src/main/php/CommandLine/StaticCodeAnalysis/Generic/TerminalCommand/PhpVersion/VersionDecorator.php

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,25 @@
44

55
namespace Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion;
66

7-
use Composer\Semver\Semver;
87
use Symfony\Component\Console\Output\OutputInterface;
98
use Zooroyal\CodingStandard\CommandLine\EnhancedFileInfo\EnhancedFileInfo;
10-
use Zooroyal\CodingStandard\CommandLine\EnhancedFileInfo\EnhancedFileInfoFactory;
119
use Zooroyal\CodingStandard\CommandLine\Environment\Environment;
1210
use Zooroyal\CodingStandard\CommandLine\FileSearch\FileSearchInterface;
1311
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\DecorateEvent;
1412
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\TerminalCommandDecorator;
1513

1614
use function Safe\file_get_contents;
17-
use function Safe\preg_match;
1815

1916
class VersionDecorator extends TerminalCommandDecorator
2017
{
21-
/** @var array<string> */
22-
private array $phpVersions = [];
2318
private ?string $cachedMinPhpVersion = null;
2419

2520
public function __construct(
2621
private readonly Environment $environment,
2722
private readonly FileSearchInterface $fileSearchInterface,
28-
private readonly EnhancedFileInfoFactory $enhancedFileInfoFactory,
23+
private readonly ConstraintToVersionConverter $constraintToVersionConverter,
24+
private readonly ComposerInterpreter $composerInterpreter,
2925
) {
30-
$phpVersionRanges = [
31-
'7.4.' => '33',
32-
'8.0.' => '27',
33-
'8.1.' => '17',
34-
'8.2.' => (explode('.', phpversion()))[2],
35-
];
36-
37-
foreach ($phpVersionRanges as $phpVersionString => $phpMaxPatchVersion) {
38-
$phpPatchLevels = range('0', $phpMaxPatchVersion);
39-
foreach ($phpPatchLevels as $phpPatchLevel) {
40-
$this->phpVersions[] = $phpVersionString . $phpPatchLevel;
41-
}
42-
}
4326
}
4427

4528
public function decorate(DecorateEvent $event): void
@@ -63,26 +46,6 @@ public function decorate(DecorateEvent $event): void
6346
);
6447
}
6548

66-
/**
67-
* Check if $phpVersionConstraint is a version number and return it or if we find a php version that satisfies
68-
* the constraint.
69-
*/
70-
private function extractActualPhpVersion(string $phpVersionConstraint): string
71-
{
72-
if (preg_match('/^(\d+)(\.\d)?(\.\d)?$/', $phpVersionConstraint, $matches)) {
73-
return $matches[1] . ($matches[2] ?? '.0') . ($matches[3] ?? '.0');
74-
}
75-
76-
$minPhpVersion = '7.4.0';
77-
foreach ($this->phpVersions as $phpVersion) {
78-
if (SemVer::satisfies($phpVersion, $phpVersionConstraint)) {
79-
$minPhpVersion = $phpVersion;
80-
break;
81-
}
82-
}
83-
return $minPhpVersion;
84-
}
85-
8649
/**
8750
* Finds all composer files in the project.
8851
*
@@ -91,18 +54,15 @@ private function extractActualPhpVersion(string $phpVersionConstraint): string
9154
private function gatherComposerFiles(): array
9255
{
9356
$rootDirectory = $this->environment->getRootDirectory();
94-
$path = $rootDirectory->getRealPath();
95-
$composerFiles[] = $this->enhancedFileInfoFactory->buildFromPath($path . '/composer.json');
9657

9758
$foundComposerFiles = $this->fileSearchInterface->listFolderFiles(
9859
fileName: 'composer.json',
9960
path: $rootDirectory,
10061
minDepth: 1,
101-
maxDepth: 4
62+
maxDepth: 4,
10263
);
10364

104-
$composerFiles = [...$composerFiles, ...$foundComposerFiles];
105-
return $composerFiles;
65+
return $foundComposerFiles;
10666
}
10767

10868
/**
@@ -112,22 +72,15 @@ private function gatherComposerFiles(): array
11272
*/
11373
private function searchMinimalViablePhpVersion(array $composerFiles): string
11474
{
115-
$minPhpVersion = '7.4.0';
75+
$minPhpVersion = $this->composerInterpreter->getLocalPhpVersionConstraint();
11676

117-
foreach ($composerFiles as $key => $composerFile) {
77+
foreach ($composerFiles as $composerFile) {
11878
$contents = file_get_contents($composerFile->getRealPath());
11979
$composerConfig = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
12080

121-
// The first file is the root composer file, so we need to check the platform config.
122-
if ($key === 0) {
123-
$phpVersionConstraint = $composerConfig['config']['platform']['php']
124-
?? $composerConfig['require']['php']
125-
?? '*';
126-
} else {
127-
$phpVersionConstraint = $composerConfig['require']['php'] ?? '*';
128-
}
81+
$phpVersionConstraint = $composerConfig['require']['php'] ?? '*';
12982

130-
$minPhpVersionPackage = $this->extractActualPhpVersion($phpVersionConstraint);
83+
$minPhpVersionPackage = $this->constraintToVersionConverter->extractActualPhpVersion($phpVersionConstraint);
13184
$minPhpVersion = version_compare($minPhpVersion, $minPhpVersionPackage, '<')
13285
? $minPhpVersionPackage
13386
: $minPhpVersion;

src/main/php/CommandLine/StaticCodeAnalysis/PHPCodeSniffer/TerminalCommand.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Fix\FixTrait;
1717
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Multiprocess\MultiprocessTerminalCommand;
1818
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Multiprocess\MultiprocessTrait;
19+
// phpcs:ignore -- I did not find a way to either break this line or to make it shorter.
20+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\MinimalVersionDependantTerminalCommand;
21+
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\MinimalVersionDependentTrait;
1922
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\PhpVersionConverter;
20-
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\VersionDependentTerminalCommand;
21-
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\PhpVersion\VersionDependentTrait;
2223
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Target\TargetTerminalCommand;
2324
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Target\TargetTrait;
2425
use Zooroyal\CodingStandard\CommandLine\StaticCodeAnalysis\Generic\TerminalCommand\Verbose\VerboseTerminalCommand;
@@ -31,15 +32,15 @@ class TerminalCommand extends AbstractTerminalCommand implements
3132
FileExtensionTerminalCommand,
3233
VerboseTerminalCommand,
3334
MultiprocessTerminalCommand,
34-
VersionDependentTerminalCommand
35+
MinimalVersionDependantTerminalCommand
3536
{
3637
use TargetTrait;
3738
use FixTrait;
3839
use ExclusionTrait;
3940
use FileExtensionTrait;
4041
use VerboseTrait;
4142
use MultiprocessTrait;
42-
use VersionDependentTrait;
43+
use MinimalVersionDependentTrait;
4344

4445
private const TEMPLATE = 'php %1$s %5$s%6$s--parallel=%7$d -p --standard=%2$s%3$s%8$s%4$s';
4546

@@ -148,7 +149,7 @@ private function buildTargetingString(): string
148149
private function buildPhpVersionString(): string
149150
{
150151
$template = ' --runtime-set php_version %d';
151-
$phpVersion = $this->phpVersionConverter->convertSemVerToPhpString($this->phpVersion);
152+
$phpVersion = $this->phpVersionConverter->convertSemVerToPhpString($this->minimalPhpVersion);
152153

153154
$result = sprintf($template, $phpVersion);
154155

0 commit comments

Comments
 (0)