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

[CI] Added phpstan #60

Merged
merged 4 commits into from
Dec 23, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ jobs:
- name: Run test suite
run: composer run-script --timeout=600 test

- name: Run PHPStan analysis
run: composer run-script phpstan

integration-tests:
name: Integration yests
needs: tests
Expand Down
9 changes: 7 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@
"ibexa/design-engine": "~4.6.0@dev",
"ibexa/user": "~4.6.0@dev",
"ibexa/fieldtype-richtext": "~4.6.0@dev",
"ibexa/phpstan": "~4.6.0@dev",
"ibexa/rest": "~4.6.0@dev",
"ibexa/search": "~4.6.0@dev",
"ibexa/test-core": "~4.6.0@dev",
"ibexa/http-cache": "~4.6.0@dev",
"ibexa/notifications": "^4.6.x-dev",
"phpunit/phpunit": "^8.2",
"matthiasnoback/symfony-dependency-injection-test": "^4.0"
"matthiasnoback/symfony-dependency-injection-test": "^4.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-symfony": "^2.0"
},
"autoload": {
"psr-4": {
Expand All @@ -55,7 +59,8 @@
"fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php -v --show-progress=dots",
"check-cs": "@fix-cs --dry-run",
"test": "phpunit -c phpunit.xml",
"test-integration": "phpunit -c phpunit.integration.xml"
"test-integration": "phpunit -c phpunit.integration.xml",
"phpstan": "phpstan analyse"
},
"config": {
"allow-plugins": false
Expand Down
25 changes: 25 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
parameters:
ignoreErrors:
-
message: '#^Binary operation "\." between array\|bool\|float\|int\|string\|null and ''/vendor/'' results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/bundle/DependencyInjection/IbexaSystemInfoExtension.php

-
message: '#^Method Ibexa\\Bundle\\SystemInfo\\DependencyInjection\\IbexaSystemInfoExtension\:\:getConfiguration\(\) has parameter \$config with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/bundle/DependencyInjection/IbexaSystemInfoExtension.php

-
message: '#^Parameter \#4 \$condition of method Doctrine\\DBAL\\Query\\QueryBuilder\:\:innerJoin\(\) expects string\|null, Doctrine\\DBAL\\Query\\Expression\\CompositeExpression given\.$#'
identifier: argument.type
count: 1
path: src/lib/Storage/Metrics/DraftsCountMetrics.php

-
message: '#^Parameter \#1 \$items of class Ibexa\\Bundle\\SystemInfo\\SystemInfo\\Registry\\IdentifierBased constructor expects array\<Ibexa\\Bundle\\SystemInfo\\SystemInfo\\Collector\\SystemInfoCollector\>, array\<Ibexa\\Bundle\\SystemInfo\\SystemInfo\\Collector\\SystemInfoCollector\|PHPUnit\\Framework\\MockObject\\MockObject\> given\.$#'
identifier: argument.type
count: 3
path: tests/bundle/SystemInfo/Registry/IdentifierBasedTest.php
15 changes: 15 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
includes:
- phpstan-baseline.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-symfony/extension.neon
- vendor/ibexa/phpstan/extension.neon

parameters:
level: 8
paths:
- src
- tests
treatPhpDocTypesAsCertain: false
ignoreErrors:
-
message: "#^Cannot call method (fetchOne|fetchColumn|fetchAllAssociative|fetchAssociative|fetchAllKeyValue|fetchFirstColumn)\\(\\) on Doctrine\\\\DBAL\\\\ForwardCompatibility\\\\Result\\|int\\|string\\.$#"
9 changes: 3 additions & 6 deletions src/bundle/Command/SystemInfoDumpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ public function __construct(SystemInfoCollectorRegistry $systemInfoCollectorRegi
parent::__construct();
}

/**
* Define command and input options.
*/
protected function configure()
protected function configure(): void
{
$this
->setName('ibexa:system-info:dump')
Expand Down Expand Up @@ -79,9 +76,9 @@ protected function configure()
protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption('list-info-collectors')) {
$output->writeln('Available info collectors:', true);
$output->writeln('Available info collectors:', OutputInterface::OUTPUT_NORMAL);
foreach ($this->systemInfoCollectorRegistry->getIdentifiers() as $identifier) {
$output->writeln(" $identifier", true);
$output->writeln(" $identifier", OutputInterface::OUTPUT_NORMAL);
}

return Command::SUCCESS;
Expand Down
9 changes: 3 additions & 6 deletions src/bundle/Controller/SystemInfoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct(SystemInfoCollectorRegistry $collectorRegistry)
$this->collectorRegistry = $collectorRegistry;
}

public function performAccessCheck()
public function performAccessCheck(): void
{
parent::performAccessCheck();
$this->denyAccessUnlessGranted(new Attribute('setup', 'system_info'));
Expand All @@ -43,23 +43,20 @@ public function infoAction(): Response
]);
}

public function viewInfoAction(SystemInfoView $view)
public function viewInfoAction(SystemInfoView $view): SystemInfoView
{
return $view;
}

/**
* Renders a PHP info page.
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function phpinfoAction(): Response
{
ob_start();
phpinfo();
$response = new Response(ob_get_clean());

return $response;
return new Response(ob_get_clean() ?: '');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class OutputFormatPass implements CompilerPassInterface
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (!$container->has(OutputFormatRegistry::class)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@

class SystemInfoCollectorPass implements CompilerPassInterface
{
/**
* Registers the SystemInfoCollector into the system info collector registry.
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (!$container->has(IdentifierBased::class)) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
class SystemInfoTabGroupPass implements CompilerPassInterface
{
/**
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
*
* @throws \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @throws \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
*/
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (!$container->hasDefinition(TabRegistry::class)) {
return;
Expand Down
6 changes: 3 additions & 3 deletions src/bundle/DependencyInjection/IbexaSystemInfoExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ public function getAlias()
return self::EXTENSION_NAME;
}

public function getConfiguration(array $config, ContainerBuilder $container)
public function getConfiguration(array $config, ContainerBuilder $container): Configuration
{
return new Configuration();
}

/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\YamlFileLoader(
$container,
Expand All @@ -61,7 +61,7 @@ public function load(array $configs, ContainerBuilder $container)
}
}

public function prepend(ContainerBuilder $container)
public function prepend(ContainerBuilder $container): void
{
$this->prependJMSTranslation($container);
}
Expand Down
2 changes: 1 addition & 1 deletion src/bundle/IbexaSystemInfoBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class IbexaSystemInfoBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new SystemInfoCollectorPass());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ class ConfigurationSymfonyKernelSystemInfoCollector implements SystemInfoCollect
* 'AsseticBundle' => 'Symfony\\Bundle\\AsseticBundle\\AsseticBundle',
* )
*
* @var array
* @var array<string, class-string>
*/
private $bundles;

/**
* @param array<string, class-string> $bundles
*/
public function __construct(Kernel $kernel, array $bundles)
{
$this->kernel = $kernel;
Expand Down
2 changes: 0 additions & 2 deletions src/bundle/SystemInfo/Collector/EzcPhpSystemInfoCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public function __construct(EzcSystemInfoWrapper $ezcSystemInfo)
* Collects information about the PHP installation Ibexa DXP is using.
* - php version
* - php accelerator info.
*
* @return \Ibexa\Bundle\SystemInfo\SystemInfo\Value\PhpSystemInfo
*/
public function collect(): PhpSystemInfo
{
Expand Down
20 changes: 8 additions & 12 deletions src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,16 @@ class IbexaSystemInfoCollector implements SystemInfoCollector
/** @var string */
private $kernelProjectDir;

/**
* @param \Ibexa\Bundle\SystemInfo\SystemInfo\Collector\JsonComposerLockSystemInfoCollector|\Ibexa\Bundle\SystemInfo\SystemInfo\Collector\SystemInfoCollector $composerCollector
* @param bool $debug
*/
public function __construct(
SystemInfoCollector $composerCollector,
string $kernelProjectDir,
bool $debug = false
) {
try {
$this->composerInfo = $composerCollector->collect();
$composerInfo = $composerCollector->collect();
if ($composerInfo instanceof ComposerSystemInfo) {
$this->composerInfo = $composerInfo;
}
} catch (ComposerLockFileNotFoundException | ComposerFileValidationException $e) {
// do nothing
}
Expand Down Expand Up @@ -225,19 +224,13 @@ private function extractComposerInfo(IbexaSystemInfo $ibexa): void
$ibexa->stability = $ibexa->lowestStability = self::getStability($this->composerInfo);
}

/**
* @throws \Exception
*/
private function getEOMDate(string $ibexaRelease): ?DateTime
{
return isset(self::EOM[$ibexaRelease]) ?
new DateTime(self::EOM[$ibexaRelease]) :
null;
}

/**
* @throws \Exception
*/
private function getEOLDate(string $ibexaRelease): ?DateTime
{
return isset(self::EOL[$ibexaRelease]) ?
Expand All @@ -255,7 +248,7 @@ private static function getStability(ComposerSystemInfo $composerInfo): string
$stabilityFlags['stable'];

// Check if any of the watched packages has lower stability than root
foreach ($composerInfo->packages as $name => $package) {
foreach ($composerInfo->packages ?? [] as $name => $package) {
if (!preg_match(self::PACKAGE_WATCH_REGEX, $name)) {
continue;
}
Expand All @@ -272,6 +265,9 @@ private static function getStability(ComposerSystemInfo $composerInfo): string
return Stability::STABILITIES[$stabilityFlag];
}

/**
* @param list<string> $packageNames
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beacuse I do not know if it is int or string indexed, and it dosent matter for this function. List is just less hustle.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually...

list<X> is basically equal to array<int, X>, with added assumption that keys will be always incrementing by 1. So it is in fact more narrow than array.

But yes, it should not matter in this context.

*/
private static function hasAnyPackage(
ComposerSystemInfo $composerInfo,
array $packageNames
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,21 @@ class JsonComposerLockSystemInfoCollector implements SystemInfoCollector
{
public const IBEXA_OSS_PACKAGE = 'ibexa/oss';

/** @var \Ibexa\SystemInfo\VersionStability\VersionStabilityChecker */
private $versionStabilityChecker;
private VersionStabilityChecker $versionStabilityChecker;

/**
* @var string Composer lock file with full path.
*/
private $lockFile;
private string $lockFile;

/**
* @var string Composer json file with full path.
*/
private $jsonFile;
private string $jsonFile;

/**
* @var \Ibexa\Bundle\SystemInfo\SystemInfo\Value\ComposerSystemInfo The collected value, cached in case info is collected by other collectors.
* The collected value, cached in case info is collected by other collectors.
*/
private $value;
private ?ComposerSystemInfo $value = null;

public function __construct(
VersionStabilityChecker $versionStabilityChecker,
$lockFile,
$jsonFile
string $lockFile,
string $jsonFile
) {
$this->versionStabilityChecker = $versionStabilityChecker;
$this->lockFile = $lockFile;
Expand All @@ -51,13 +44,9 @@ public function __construct(
/**
* Collects information about installed composer packages.
*
* @return \Ibexa\Bundle\SystemInfo\SystemInfo\Value\ComposerSystemInfo
*
* @throws Exception\ComposerLockFileNotFoundException if the composer.lock file was not found.
* @throws Exception\ComposerJsonFileNotFoundException if the composer.json file was not found.
* @throws Exception\ComposerFileValidationException if composer.lock of composer.json are not valid.
*
* @return \Ibexa\Bundle\SystemInfo\SystemInfo\Value\ComposerSystemInfo
*/
public function collect(): ComposerSystemInfo
{
Expand All @@ -73,8 +62,8 @@ public function collect(): ComposerSystemInfo
throw new Exception\ComposerJsonFileNotFoundException($this->jsonFile);
}

$lockData = json_decode(file_get_contents($this->lockFile), true);
$jsonData = json_decode(file_get_contents($this->jsonFile), true);
$lockData = json_decode(file_get_contents($this->lockFile) ?: '', true);
$jsonData = json_decode(file_get_contents($this->jsonFile) ?: '', true);

if (!is_array($lockData)) {
throw new Exception\ComposerFileValidationException($this->lockFile);
Expand All @@ -86,7 +75,7 @@ public function collect(): ComposerSystemInfo

$stability = InstalledVersions::isInstalled(self::IBEXA_OSS_PACKAGE)
? $this->versionStabilityChecker->getStability(
InstalledVersions::getVersion(self::IBEXA_OSS_PACKAGE)
InstalledVersions::getVersion(self::IBEXA_OSS_PACKAGE) ?? ''
)
: $this->getMinimumStability($lockData);

Expand All @@ -98,7 +87,7 @@ public function collect(): ComposerSystemInfo
}

/**
* @param array $lockData
* @param array<string, mixed> $lockData
*
* @return \Ibexa\Bundle\SystemInfo\SystemInfo\Value\ComposerPackage[]
*/
Expand Down Expand Up @@ -145,7 +134,7 @@ private function extractPackages(array $lockData): array
}

/**
* @param array $jsonData
* @param array<string, mixed> $jsonData
*
* @return string[]
*/
Expand Down Expand Up @@ -189,6 +178,9 @@ private static function setNormalizedVersion(ComposerPackage $package): void
$package->version = $version;
}

/**
* @param array<string, mixed> $lockData
*/
private function getMinimumStability(array $lockData): ?string
{
return $lockData['minimum-stability'] ?? null;
Expand Down
Loading
Loading