Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check runtime requirements #8782

Merged
merged 1 commit into from Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Psalm/Internal/Cli/LanguageServer.php
Expand Up @@ -61,6 +61,7 @@ final class LanguageServer
/** @param array<int,string> $argv */
public static function run(array $argv): void
{
CliUtils::checkRuntimeRequirements();
gc_disable();
ErrorHandler::install($argv);
$valid_short_options = [
Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Internal/Cli/Plugin.php
Expand Up @@ -26,6 +26,7 @@ final class Plugin
{
public static function run(): void
{
CliUtils::checkRuntimeRequirements();
$current_dir = (string)getcwd() . DIRECTORY_SEPARATOR;
$vendor_dir = CliUtils::getVendorDir($current_dir);
CliUtils::requireAutoloaders($current_dir, false, $vendor_dir);
Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Internal/Cli/Psalm.php
Expand Up @@ -165,6 +165,7 @@ final class Psalm
*/
public static function run(array $argv): void
{
CliUtils::checkRuntimeRequirements();
gc_collect_cycles();
gc_disable();

Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Internal/Cli/Psalter.php
Expand Up @@ -94,6 +94,7 @@ final class Psalter
/** @param array<int,string> $argv */
public static function run(array $argv): void
{
CliUtils::checkRuntimeRequirements();
gc_collect_cycles();
gc_disable();

Expand Down
1 change: 1 addition & 0 deletions src/Psalm/Internal/Cli/Refactor.php
Expand Up @@ -67,6 +67,7 @@ final class Refactor
/** @param array<int,string> $argv */
public static function run(array $argv): void
{
CliUtils::checkRuntimeRequirements();
ini_set('memory_limit', '8192M');

gc_collect_cycles();
Expand Down
58 changes: 56 additions & 2 deletions src/Psalm/Internal/CliUtils.php
Expand Up @@ -13,11 +13,13 @@
use Psalm\Report;
use RuntimeException;

use function array_filter;
use function array_slice;
use function assert;
use function count;
use function define;
use function dirname;
use function extension_loaded;
use function fgets;
use function file_exists;
use function file_get_contents;
Expand Down Expand Up @@ -47,6 +49,8 @@
use const DIRECTORY_SEPARATOR;
use const JSON_THROW_ON_ERROR;
use const PHP_EOL;
use const PHP_VERSION;
use const PHP_VERSION_ID;
use const STDERR;
use const STDIN;

Expand Down Expand Up @@ -88,7 +92,7 @@ public static function requireAutoloaders(
foreach ($autoload_roots as $autoload_root) {
$has_autoloader = false;

$nested_autoload_file = dirname($autoload_root, 2). DIRECTORY_SEPARATOR . 'autoload.php';
$nested_autoload_file = dirname($autoload_root, 2) . DIRECTORY_SEPARATOR . 'autoload.php';

// note: don't realpath $nested_autoload_file, or phar version will fail
if (file_exists($nested_autoload_file)) {
Expand Down Expand Up @@ -300,7 +304,7 @@ public static function getPathsToCheck($f_paths): ?array
if ($stdin = fgets(STDIN)) {
$filtered_input_paths = preg_split('/\s+/', trim($stdin));
if ($filtered_input_paths === false) {
throw new RuntimeException('Invalid paths: '.preg_last_error_msg());
throw new RuntimeException('Invalid paths: ' . preg_last_error_msg());
}
}
$blocked = $meta['blocked'];
Expand Down Expand Up @@ -515,4 +519,54 @@ public static function runningInCI(): bool
|| isset($_SERVER['GITHUB_WORKFLOW'])
|| isset($_SERVER['DRONE']);
}

public static function checkRuntimeRequirements(): void
{
$required_php_version = 7_04_00;
$required_php_version_text = '7.4.0';

// the following list was taken from vendor/composer/platform_check.php
// It includes both Psalm's requirements (from composer.json) and the
// requirements of our dependencies `netresearch/jsonmapper` and
// `phpdocumentor/reflection-docblock`. The latter is transitive
// dependency of `felixfbecker/advanced-json-rpc`
$required_extensions = [
'dom',
'filter',
'json',
'libxml',
'pcre',
'reflection',
'simplexml',
'spl',
'tokenizer',
];
$issues = [];

if (PHP_VERSION_ID < $required_php_version) {
$issues[] = 'Psalm requires a PHP version ">= ' . $required_php_version_text . '".'
. ' You are running ' . PHP_VERSION . '.';
}

$missing_extensions = array_filter(
$required_extensions,
static fn(string $ext) => !extension_loaded($ext)
);

if ($missing_extensions) {
$issues[] = 'Psalm requires the following PHP extensions to be installed: '
. implode(', ', $missing_extensions)
. '.';
}

if ($issues) {
fwrite(
STDERR,
'Psalm has detected issues in your platform:' . PHP_EOL . PHP_EOL
. implode(PHP_EOL, $issues)
. PHP_EOL . PHP_EOL
);
exit(1);
}
}
}