Skip to content

Commit

Permalink
Introduced NoConfigResolverInConstructorRule PHPStan custom rule
Browse files Browse the repository at this point in the history
  • Loading branch information
konradoboza committed Dec 11, 2024
1 parent 70b5f38 commit f14626c
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 18 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/backend-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Backend build

on:
push:
branches:
- main
- '[0-9]+.[0-9]+'
pull_request: ~

jobs:
cs-fix:
name: Run code style check
runs-on: "ubuntu-22.04"
strategy:
matrix:
php:
- '8.3'
steps:
- uses: actions/checkout@v4

- name: Setup PHP Action
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
extensions: 'pdo_sqlite, gd'
tools: cs2pr

- uses: ramsey/composer-install@v3
with:
dependency-versions: "highest"

- name: Run code style check
run: composer run-script check-cs -- --format=checkstyle | cs2pr

tests:
name: Tests
runs-on: "ubuntu-22.04"
timeout-minutes: 10

strategy:
fail-fast: false
matrix:
php:
- '8.3'

steps:
- uses: actions/checkout@v4

- name: Setup PHP Action
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
extensions: pdo_sqlite, gd
tools: cs2pr

- uses: ramsey/composer-install@v3
with:
dependency-versions: "highest"
composer-options: "--prefer-dist --no-progress --no-suggest"

- name: Setup problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

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

- name: Run test suite
run: composer run-script --timeout=600 test
14 changes: 14 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

return \Ibexa\CodeStyle\PhpCsFixer\InternalConfigFactory::build()->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__ . '/rules')
->in(__DIR__ . '/tests')
->files()->name('*.php')
);
69 changes: 51 additions & 18 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,54 @@
{
"name": "ibexa/phpstan",
"license": "proprietary",
"type": "ibexa-bundle",
"keywords": [
"ibexa-dxp"
],
"require": {
"php": "^7.4 || ^8.0"
},
"config": {
"sort-packages": true
},
"extra": {
"phpstan": {
"includes": [
"extension.neon"
]
"name": "ibexa/phpstan",
"license": "proprietary",
"type": "ibexa-bundle",
"keywords": [
"ibexa-dxp"
],
"require": {
"ibexa/core": "5.0.x-dev",
"ibexa/doctrine-schema": "5.0.x-dev",
"php": ">= 8.3"
},
"require-dev": {
"ibexa/code-style": "~2.0.0",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan-strict-rules": "^1.6",
"phpstan/phpstan-symfony": "^1.3",
"phpunit/phpunit": "^9"
},
"autoload": {
"psr-4": {
"Ibexa\\PHPStan\\Rules\\": "rules/"
}
},
"autoload-dev": {
"psr-4": {
"Ibexa\\Tests\\PHPStan\\Rules\\": "tests/rules/"
}
},
"scripts": {
"fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php --show-progress=dots",
"check-cs": "@fix-cs --dry-run",
"test": "phpunit -c phpunit.xml.dist",
"phpstan": "phpstan analyse -c phpstan.neon"
},
"scripts-descriptions": {
"fix-cs": "Automatically fixes code style in all files",
"check-cs": "Run code style checker for all files",
"test": "Run automatic tests",
"phpstan": "Run static code analysis"
},
"config": {
"sort-packages": true,
"allow-plugins": false
},
"extra": {
"phpstan": {
"includes": [
"extension.neon"
]
}
}
}
}
2 changes: 2 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ parameters:
- stubs/Money/Money.stub
- stubs/Money/MoneyFormatter.stub
- stubs/Money/MoneyParser.stub
rules:
- Ibexa\PHPStan\Rules\NoConfigResolverParametersInConstructorRule
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
parameters:
level: 8
paths:
- rules
- tests
checkMissingCallableSignature: true
64 changes: 64 additions & 0 deletions rules/NoConfigResolverParametersInConstructorRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\PHPStan\Rules;

use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\ObjectType;

/**
* @implements \PHPStan\Rules\Rule<\PhpParser\Node\Expr\MethodCall>
*/
final readonly class NoConfigResolverParametersInConstructorRule implements Rule
{
public function getNodeType(): string
{
return Node\Expr\MethodCall::class;
}

/**
* @throws \PHPStan\ShouldNotHappenException
*/
public function processNode(Node $node, Scope $scope): array
{
if (!$node->name instanceof Node\Identifier) {
return [];
}

if ($scope->getFunction()?->getName() !== '__construct') {
return [];
}

$methodName = $node->name->name;
if (
$methodName === 'getParameter'
|| $methodName === 'hasParameter'
|| !isset($node->getArgs()[0])
) {
return [];
}

$type = $scope->getType($node->var);
$configResolverInterfaceType = new ObjectType(ConfigResolverInterface::class);
if (!$configResolverInterfaceType->isSuperTypeOf($type)->yes()) {
return [];
}

return [
RuleErrorBuilder
::message('Referring to ConfigResolver parameters in constructor is not allowed due to potential scope change.')
->identifier('Ibexa.NoConfigResolverParametersInConstructor')
->nonIgnorable()
->build(),
];
}
}
18 changes: 18 additions & 0 deletions tests/rules/NoConfigResolverParametersInConstructorRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules;

use PHPUnit\Framework\TestCase;

final class NoConfigResolverParametersInConstructorRuleTest extends TestCase
{
public function testRule(): void
{
}
}

0 comments on commit f14626c

Please sign in to comment.