diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 611ce43c..19e1e0dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,8 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] - coverage-driver: [ 'pcov' ] + php-versions: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] steps: - uses: actions/checkout@v6 @@ -23,6 +22,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} + coverage: pcov tools: composer:v2.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -43,18 +43,23 @@ jobs: run: composer install --prefer-dist - name: Coding Standard Checks - if: ${{ matrix.php-versions == '7.4' }} + if: ${{ matrix.php-versions == '8.0' }} run: PHP_CS_FIXER_IGNORE_ENV=1 ./bin/php-cs-fixer fix --dry-run --diff - name: Static Analysis - if: ${{ matrix.php-versions == '7.4' }} + if: ${{ matrix.php-versions == '8.0' }} run: ./bin/psalm.phar --no-cache - - name: Test + - name: Test with coverage + if: ${{ matrix.php-versions == '8.0' }} run: ./bin/phpunit -d memory_limit=-1 --coverage-clover clover.xml + - name: Test without coverage + if: ${{ matrix.php-versions != '8.0' }} + run: ./bin/phpunit -d memory_limit=-1 + - name: Upload coverage to Codecov - if: ${{ matrix.php-versions == '7.4' }} + if: ${{ matrix.php-versions == '8.0' }} uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -68,7 +73,7 @@ jobs: - name: Install PHP uses: shivammathur/setup-php@v2 with: - php-version: 7.4 + php-version: 8.0 tools: composer:v2.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -97,7 +102,7 @@ jobs: runs-on: "ubuntu-22.04" strategy: matrix: - php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] + php-versions: [ '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] steps: - name: Install PHP uses: shivammathur/setup-php@v2 diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 5ea44f9d..f74a4367 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -12,7 +12,7 @@ '@PER-CS' => true, '@Symfony' => true, '@Symfony:risky' => true, - '@PHP71Migration:risky' => true, + '@PHP80Migration:risky' => true, '@PSR2' => true, '@DoctrineAnnotation' => true, 'array_syntax' => ['syntax' => 'short'], @@ -24,7 +24,7 @@ 'modernize_types_casting' => true, // Replaces intval, floatval, doubleval, strval and boolval function calls with according type casting operator. 'multiline_whitespace_before_semicolons' => true, // Forbid multi-line whitespace before the closing semicolon or move the semicolon to the new line for chained calls. 'no_unreachable_default_argument_value' => true, // In function arguments there must not be arguments with default values before non-default ones. - 'no_superfluous_phpdoc_tags' => ['allow_mixed' => true], // To avoid problems of compatibility with the old php-cs-fixer version used on PHP 7.3 + 'no_superfluous_phpdoc_tags' => ['allow_mixed' => true], 'no_useless_else' => true, 'no_useless_return' => true, 'ordered_class_elements' => true, // Orders the elements of classes/interfaces/traits. diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 7df0ee74..26e02fd5 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -1,4 +1,4 @@ build: environment: - php: 7.4 + php: 8.0 diff --git a/Dockerfile b/Dockerfile index 3647b1fe..04a400a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG PHP_VERSION=7.4 +ARG PHP_VERSION=8.0 FROM php:${PHP_VERSION}-cli-alpine AS php_build diff --git a/README.md b/README.md index 882dc41a..d2d2ce95 100644 --- a/README.md +++ b/README.md @@ -473,7 +473,7 @@ You can add parameters when you launch the tool. At the moment you can add these phparkitect check --config=/project/yourConfigFile.php ``` * `--target-php-version`: With this parameter, you can specify which PHP version should use the parser. This can be useful to debug problems and to understand if there are problems with a different PHP version. -Supported PHP versions are: 7.4, 8.0, 8.1, 8.2 8.3 +Supported PHP versions are: 8.0, 8.1, 8.2, 8.3, 8.4, 8.5 * `--stop-on-failure`: With this option the process will end immediately after the first violation. * `--autoload`: specify the path of an autoload file to be loaded when running phparkitect. diff --git a/composer.json b/composer.json index 1b6b33db..007b08ef 100644 --- a/composer.json +++ b/composer.json @@ -22,15 +22,14 @@ } ], "require": { - "php": "^7.4|^8", + "php": "^8.0", "ext-json": "*", "nikic/php-parser": "~5", "ondram/ci-detector": "^4.2", - "phpstan/phpdoc-parser": "^1.2|^2.0", - "symfony/console": "^3.0|^4.0|^5.0|^6.0|^7.0|^8.0", - "symfony/event-dispatcher": "^3.0|^4.0|^5.0|^6.0|^7.0|^8.0", - "symfony/finder": "^3.0|^4.0|^5.0|^6.0|^7.0|^8.0", - "symfony/polyfill-php80": "^1.33", + "phpstan/phpdoc-parser": "^2.0", + "symfony/console": "^5.4 || ^6.0 <6.4", + "symfony/event-dispatcher": "^5.4 || ^6.0 <6.4", + "symfony/finder": "^5.4 || ^6.0 <6.4", "webmozart/assert": "^1.12" }, "require-dev": { @@ -38,9 +37,9 @@ "mikey179/vfsstream": "^1.6", "phpspec/prophecy": "^1.10", "phpspec/prophecy-phpunit": "^2.4", - "phpunit/phpunit": "^7.5|^9.0|^10.0", + "phpunit/phpunit": "^9.6|^10.0|^11.0", "roave/security-advisories": "dev-master", - "symfony/var-dumper": "^3.0|^4.0|^5.0|^6.0|^7.0|^8.0" + "symfony/var-dumper": "^5.4 || ^6.0 <6.4" }, "autoload": { "psr-4": { diff --git a/src/Analyzer/ClassDescription.php b/src/Analyzer/ClassDescription.php index 93545a98..a0a0d946 100644 --- a/src/Analyzer/ClassDescription.php +++ b/src/Analyzer/ClassDescription.php @@ -57,7 +57,7 @@ public function __construct( bool $enum, array $docBlock, array $attributes, - string $filePath + string $filePath, ) { $this->FQCN = $FQCN; $this->filePath = $filePath; @@ -196,9 +196,7 @@ public function hasAttribute(string $pattern): bool { return array_reduce( $this->attributes, - static function (bool $carry, FullyQualifiedClassName $attribute) use ($pattern): bool { - return $carry || $attribute->matches($pattern); - }, + static fn (bool $carry, FullyQualifiedClassName $attribute): bool => $carry || $attribute->matches($pattern), false ); } diff --git a/src/Analyzer/FileParser.php b/src/Analyzer/FileParser.php index e9ea68f0..2d6a6222 100644 --- a/src/Analyzer/FileParser.php +++ b/src/Analyzer/FileParser.php @@ -29,7 +29,7 @@ public function __construct( FileVisitor $fileVisitor, NameResolver $nameResolver, DocblockTypesResolver $docblockTypesResolver, - TargetPhpVersion $targetPhpVersion + TargetPhpVersion $targetPhpVersion, ) { $this->fileVisitor = $fileVisitor; $this->parsingErrors = []; diff --git a/src/CLI/Runner.php b/src/CLI/Runner.php index 6cc9047a..3abe7382 100644 --- a/src/CLI/Runner.php +++ b/src/CLI/Runner.php @@ -44,7 +44,7 @@ public function check( Parser $fileParser, Violations $violations, ParsingErrors $parsingErrors, - bool $stopOnFailure + bool $stopOnFailure, ): void { /** @var SplFileInfo $file */ foreach ($classSetRule->getClassSet() as $file) { diff --git a/src/CLI/TargetPhpVersion.php b/src/CLI/TargetPhpVersion.php index 64d553fd..1d46d620 100644 --- a/src/CLI/TargetPhpVersion.php +++ b/src/CLI/TargetPhpVersion.php @@ -8,7 +8,6 @@ class TargetPhpVersion { - public const PHP_7_4 = '7.4'; public const PHP_8_0 = '8.0'; public const PHP_8_1 = '8.1'; public const PHP_8_2 = '8.2'; @@ -17,7 +16,6 @@ class TargetPhpVersion public const PHP_8_5 = '8.5'; public const VALID_PHP_VERSIONS = [ - '7.4', '8.0', '8.1', '8.2', diff --git a/src/Expression/ForClasses/Implement.php b/src/Expression/ForClasses/Implement.php index 6dd906de..a64554de 100644 --- a/src/Expression/ForClasses/Implement.php +++ b/src/Expression/ForClasses/Implement.php @@ -40,9 +40,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str $interface = $this->interface; $interfaces = $theClass->getInterfaces(); - $implements = function (FullyQualifiedClassName $FQCN) use ($interface): bool { - return $FQCN->matches($interface); - }; + $implements = fn (FullyQualifiedClassName $FQCN): bool => $FQCN->matches($interface); if (0 === \count(array_filter($interfaces, $implements))) { $violation = Violation::create( diff --git a/src/Expression/ForClasses/NotHaveDependencyOutsideNamespace.php b/src/Expression/ForClasses/NotHaveDependencyOutsideNamespace.php index 4501d6e1..017ecded 100644 --- a/src/Expression/ForClasses/NotHaveDependencyOutsideNamespace.php +++ b/src/Expression/ForClasses/NotHaveDependencyOutsideNamespace.php @@ -36,9 +36,7 @@ public function describe(ClassDescription $theClass, string $because): Descripti public function evaluate(ClassDescription $theClass, Violations $violations, string $because): void { $namespace = $this->namespace; - $depends = function (ClassDependency $dependency) use ($namespace): bool { - return !$dependency->getFQCN()->matches($namespace); - }; + $depends = fn (ClassDependency $dependency): bool => !$dependency->getFQCN()->matches($namespace); $dependencies = $theClass->getDependencies(); $externalDeps = array_filter($dependencies, $depends); diff --git a/src/Expression/ForClasses/NotImplement.php b/src/Expression/ForClasses/NotImplement.php index 0f410b91..55257f71 100644 --- a/src/Expression/ForClasses/NotImplement.php +++ b/src/Expression/ForClasses/NotImplement.php @@ -40,9 +40,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str $interface = $this->interface; $interfaces = $theClass->getInterfaces(); - $implements = function (FullyQualifiedClassName $FQCN) use ($interface): bool { - return $FQCN->matches($interface); - }; + $implements = fn (FullyQualifiedClassName $FQCN): bool => $FQCN->matches($interface); if (\count(array_filter($interfaces, $implements)) > 0) { $violation = Violation::create( diff --git a/src/PHPUnit/ArchRuleCheckerConstraintAdapter.php b/src/PHPUnit/ArchRuleCheckerConstraintAdapter.php index faede6de..5ea448e7 100644 --- a/src/PHPUnit/ArchRuleCheckerConstraintAdapter.php +++ b/src/PHPUnit/ArchRuleCheckerConstraintAdapter.php @@ -61,7 +61,7 @@ public function toString(): string protected function matches( /** @var ArchRule $rule */ - $other + $other, ): bool { $this->runner->check( ClassSetRules::create($this->classSet, $other), diff --git a/src/RuleBuilders/Architecture/Architecture.php b/src/RuleBuilders/Architecture/Architecture.php index 3468830d..18b70512 100644 --- a/src/RuleBuilders/Architecture/Architecture.php +++ b/src/RuleBuilders/Architecture/Architecture.php @@ -90,9 +90,7 @@ public function rules(string $because = 'of component architecture'): iterable $forbiddenComponents = array_diff($layerNames, [$name], $this->allowedDependencies[$name]); if (!empty($forbiddenComponents)) { - $forbiddenSelectors = array_values(array_map(function (string $componentName): string { - return $this->componentSelectors[$componentName]; - }, $forbiddenComponents)); + $forbiddenSelectors = array_values(array_map(fn (string $componentName): string => $this->componentSelectors[$componentName], $forbiddenComponents)); yield Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces($selector)) @@ -105,9 +103,7 @@ public function rules(string $because = 'of component architecture'): iterable continue; } - $allowedDependencies = array_values(array_map(function (string $componentName): string { - return $this->componentSelectors[$componentName]; - }, $this->componentDependsOnlyOnTheseNamespaces[$name])); + $allowedDependencies = array_values(array_map(fn (string $componentName): string => $this->componentSelectors[$componentName], $this->componentDependsOnlyOnTheseNamespaces[$name])); yield Rule::allClasses() ->that(new ResideInOneOfTheseNamespaces($selector)) diff --git a/src/Rules/ArchRule.php b/src/Rules/ArchRule.php index cd2e772f..8a811ccc 100644 --- a/src/Rules/ArchRule.php +++ b/src/Rules/ArchRule.php @@ -28,7 +28,7 @@ public function __construct( Constraints $constraints, string $because, array $classesToBeExcluded, - bool $runOnlyThis + bool $runOnlyThis, ) { $this->thats = $specs; $this->shoulds = $constraints; diff --git a/src/Rules/Violations.php b/src/Rules/Violations.php index 5d17b485..b632870a 100644 --- a/src/Rules/Violations.php +++ b/src/Rules/Violations.php @@ -27,9 +27,7 @@ public static function fromJson(string $json): self $instance = new self(); - $instance->violations = array_map(function (array $json): Violation { - return Violation::fromJson($json); - }, $json['violations']); + $instance->violations = array_map(fn (array $json): Violation => Violation::fromJson($json), $json['violations']); return $instance; } @@ -113,9 +111,7 @@ public function remove(self $violations, bool $ignoreBaselineLinenumbers = false public function sort(): void { - usort($this->violations, static function (Violation $v1, Violation $v2): int { - return $v1 <=> $v2; - }); + usort($this->violations, static fn (Violation $v1, Violation $v2): int => $v1 <=> $v2); } public function jsonSerialize(): array diff --git a/tests/E2E/Cli/CheckCommandTest.php b/tests/E2E/Cli/CheckCommandTest.php index 8d6db7e9..c60ef9c5 100644 --- a/tests/E2E/Cli/CheckCommandTest.php +++ b/tests/E2E/Cli/CheckCommandTest.php @@ -269,7 +269,7 @@ protected function runCheck( bool $skipBaseline = false, bool $ignoreBaselineNumbers = false, string $format = 'text', - ?string $autoloadFilePath = null + ?string $autoloadFilePath = null, ): ApplicationTester { $input = ['check']; diff --git a/tests/Unit/Analyzer/FileParser/CanParseClassTest.php b/tests/Unit/Analyzer/FileParser/CanParseClassTest.php index e7fe8673..86654b39 100644 --- a/tests/Unit/Analyzer/FileParser/CanParseClassTest.php +++ b/tests/Unit/Analyzer/FileParser/CanParseClassTest.php @@ -602,7 +602,7 @@ public function __construct() { private function parseCode(string $code, ?string $version = null): array { - $fp = FileParserFactory::forPhpVersion($version ?? TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion($version ?? TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); return $fp->getClassDescriptions(); diff --git a/tests/Unit/Analyzer/FileParser/CanParseDocblocksTest.php b/tests/Unit/Analyzer/FileParser/CanParseDocblocksTest.php index d0c7c201..c3363c6c 100644 --- a/tests/Unit/Analyzer/FileParser/CanParseDocblocksTest.php +++ b/tests/Unit/Analyzer/FileParser/CanParseDocblocksTest.php @@ -105,7 +105,7 @@ class MyClass } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -134,7 +134,7 @@ class MyClass } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -163,7 +163,7 @@ class MyClass } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -194,7 +194,7 @@ public function __construct(array $dtoList) } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -225,7 +225,7 @@ public function __construct(array $dtoList) } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -256,7 +256,7 @@ public function __construct(array $dtoList) } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -290,7 +290,7 @@ public function __construct(string $var1, array $dtoList, $var2, array $voList) } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -322,7 +322,7 @@ public function getList(): array } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -354,7 +354,7 @@ public function getList(): array } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); @@ -386,7 +386,7 @@ public function getList(): array } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $cd = $fp->getClassDescriptions(); diff --git a/tests/Unit/Analyzer/FileParser/CanParseNonWellFormedFilesTest.php b/tests/Unit/Analyzer/FileParser/CanParseNonWellFormedFilesTest.php index 0650b291..e31adea4 100644 --- a/tests/Unit/Analyzer/FileParser/CanParseNonWellFormedFilesTest.php +++ b/tests/Unit/Analyzer/FileParser/CanParseNonWellFormedFilesTest.php @@ -14,7 +14,7 @@ class CanParseNonWellFormedFilesTest extends TestCase { public function test_should_parse_non_php_file(): void { - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse('', 'path/to/class.php'); self::assertEmpty($fp->getClassDescriptions()); @@ -26,7 +26,7 @@ public function test_should_parse_empty_file(): void parse($code, 'path/to/class.php'); self::assertEmpty($fp->getClassDescriptions()); @@ -48,7 +48,7 @@ public function __construct() } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $parsingErrors = $fp->getParsingErrors(); @@ -78,7 +78,7 @@ public function save(Quote $quote): void; } EOF; - $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_7_4); + $fp = FileParserFactory::forPhpVersion(TargetPhpVersion::PHP_8_0); $fp->parse($code, 'relativePathName'); $violations = new Violations(); diff --git a/tests/Unit/Analyzer/FileParserTest.php b/tests/Unit/Analyzer/FileParserTest.php index a4522c37..951f6a9e 100644 --- a/tests/Unit/Analyzer/FileParserTest.php +++ b/tests/Unit/Analyzer/FileParserTest.php @@ -37,7 +37,7 @@ public function test_parse_file(): void $fileVisitor->reveal(), $nameResolver->reveal(), $docblockResolver->reveal(), - TargetPhpVersion::create('7.4') + TargetPhpVersion::create('8.0') ); $content = 'reveal(), $nameResolver->reveal(), $docblockResolver->reveal(), - TargetPhpVersion::create('7.4') + TargetPhpVersion::create('8.0') ); $content = 'get()); + self::assertEquals('8.0', $targetPhpVersion->get()); } public function test_it_should_throw_exception_if_not_valid_php_version(): void diff --git a/tests/Unit/ClassSetTest.php b/tests/Unit/ClassSetTest.php index c9ba60c0..f810abb5 100644 --- a/tests/Unit/ClassSetTest.php +++ b/tests/Unit/ClassSetTest.php @@ -54,9 +54,7 @@ public function test_can_exclude_files_or_directories(): void 'View/UserView.php', ]; - $actual = array_values(array_map(function ($item) { - return $item->getRelativePathname(); - }, iterator_to_array($set))); + $actual = array_values(array_map(fn ($item) => $item->getRelativePathname(), iterator_to_array($set))); self::assertEquals($expected, $actual); } @@ -83,9 +81,7 @@ public function test_can_exclude_glob_patterns(): void 'View/UserView.php', ]; - $actual = array_values(array_map(function ($item) { - return $item->getRelativePathname(); - }, iterator_to_array($set))); + $actual = array_values(array_map(fn ($item) => $item->getRelativePathname(), iterator_to_array($set))); self::assertEquals($expected, $actual); }