Skip to content

Commit d235195

Browse files
committed
Read targeted PHP version from composer.json's config.platform.php (bleeding edge)
1 parent f9ee84b commit d235195

5 files changed

Lines changed: 152 additions & 2 deletions

File tree

conf/bleedingEdge.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ parameters:
66
nullCoalesce: true
77
fileWhitespace: true
88
unusedClassElements: true
9+
readComposerPhpVersion: true

conf/config.neon

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ parameters:
1515
nullCoalesce: false
1616
fileWhitespace: false
1717
unusedClassElements: false
18+
readComposerPhpVersion: false
1819
fileExtensions:
1920
- php
2021
checkAlwaysTrueCheckTypeFunctionCall: false
@@ -154,7 +155,8 @@ parametersSchema:
154155
randomIntParameters: bool(),
155156
nullCoalesce: bool(),
156157
fileWhitespace: bool(),
157-
unusedClassElements: bool()
158+
unusedClassElements: bool(),
159+
readComposerPhpVersion: bool()
158160
])
159161
fileExtensions: listOf(string())
160162
checkAlwaysTrueCheckTypeFunctionCall: bool()
@@ -293,8 +295,14 @@ services:
293295

294296
-
295297
class: PHPStan\Php\PhpVersionFactory
298+
factory: @PHPStan\Php\PhpVersionFactoryFactory::create
299+
300+
-
301+
class: PHPStan\Php\PhpVersionFactoryFactory
296302
arguments:
297303
versionId: %phpVersion%
304+
readComposerPhpVersion: %featureToggles.readComposerPhpVersion%
305+
composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths%
298306

299307
-
300308
class: PHPStan\PhpDocParser\Lexer\Lexer

src/Php/PhpVersionFactory.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,27 @@ class PhpVersionFactory
99

1010
private ?int $versionId;
1111

12-
public function __construct(?int $versionId)
12+
private ?string $composerPhpVersion;
13+
14+
public function __construct(
15+
?int $versionId,
16+
?string $composerPhpVersion
17+
)
1318
{
1419
$this->versionId = $versionId;
20+
$this->composerPhpVersion = $composerPhpVersion;
1521
}
1622

1723
public function create(): PhpVersion
1824
{
1925
$versionId = $this->versionId;
26+
if ($versionId === null && $this->composerPhpVersion !== null) {
27+
$parts = explode('.', $this->composerPhpVersion);
28+
$tmp = (int) $parts[0] * 10000 + (int) ($parts[1] ?? 0) * 100 + (int) ($parts[2] ?? 0);
29+
$tmp = max($tmp, 70100);
30+
$versionId = min($tmp, 80000);
31+
}
32+
2033
if ($versionId === null) {
2134
$versionId = PHP_VERSION_ID;
2235
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Php;
4+
5+
use Nette\Utils\Json;
6+
use PHPStan\File\FileReader;
7+
8+
class PhpVersionFactoryFactory
9+
{
10+
11+
private ?int $versionId;
12+
13+
private bool $readComposerPhpVersion;
14+
15+
/** @var string[] */
16+
private array $composerAutoloaderProjectPaths;
17+
18+
/**
19+
* @param bool $readComposerPhpVersion
20+
* @param string[] $composerAutoloaderProjectPaths
21+
*/
22+
public function __construct(
23+
?int $versionId,
24+
bool $readComposerPhpVersion,
25+
array $composerAutoloaderProjectPaths
26+
)
27+
{
28+
$this->versionId = $versionId;
29+
$this->readComposerPhpVersion = $readComposerPhpVersion;
30+
$this->composerAutoloaderProjectPaths = $composerAutoloaderProjectPaths;
31+
}
32+
33+
public function create(): PhpVersionFactory
34+
{
35+
$composerPhpVersion = null;
36+
if ($this->readComposerPhpVersion && count($this->composerAutoloaderProjectPaths) > 0) {
37+
$composerJsonPath = end($this->composerAutoloaderProjectPaths) . '/composer.json';
38+
if (is_file($composerJsonPath)) {
39+
try {
40+
$composerJsonContents = FileReader::read($composerJsonPath);
41+
$composer = Json::decode($composerJsonContents, Json::FORCE_ARRAY);
42+
$platformVersion = $composer['config']['platform']['php'] ?? null;
43+
if (is_string($platformVersion)) {
44+
$composerPhpVersion = $platformVersion;
45+
}
46+
} catch (\PHPStan\File\CouldNotReadFileException | \Nette\Utils\JsonException $e) {
47+
// pass
48+
}
49+
}
50+
}
51+
52+
return new PhpVersionFactory($this->versionId, $composerPhpVersion);
53+
}
54+
55+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Php;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
class PhpVersionFactoryTest extends TestCase
8+
{
9+
10+
public function dataCreate(): array
11+
{
12+
return [
13+
[
14+
null,
15+
null,
16+
PHP_VERSION_ID,
17+
],
18+
[
19+
70200,
20+
null,
21+
70200,
22+
],
23+
[
24+
70200,
25+
'7.4.6',
26+
70200,
27+
],
28+
[
29+
null,
30+
'7.4.6',
31+
70406,
32+
],
33+
[
34+
null,
35+
'7.0',
36+
70100,
37+
],
38+
[
39+
null,
40+
'7.1.1',
41+
70101,
42+
],
43+
[
44+
null,
45+
'5.4.1',
46+
70100,
47+
],
48+
[
49+
null,
50+
'8.1',
51+
80000,
52+
],
53+
];
54+
}
55+
56+
/**
57+
* @dataProvider dataCreate
58+
* @param int|null $versionId
59+
* @param string|null $composerPhpVersion
60+
* @param int $expectedVersion
61+
*/
62+
public function testCreate(
63+
?int $versionId,
64+
?string $composerPhpVersion,
65+
int $expectedVersion
66+
): void
67+
{
68+
$factory = new PhpVersionFactory($versionId, $composerPhpVersion);
69+
$phpVersion = $factory->create();
70+
$this->assertSame($expectedVersion, $phpVersion->getVersionId());
71+
}
72+
73+
}

0 commit comments

Comments
 (0)