From 971e1e1bc463d165c7b63b062674e5ac2b29a11f Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Sun, 26 Jan 2025 19:04:49 +0100 Subject: [PATCH 1/7] Use secret token for Codecov upload --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43d0140..4e11d3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,9 +102,10 @@ jobs: if: ${{ matrix.os == 'windows-latest' }} run: vendor/bin/phan --allow-polyfill-parser - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: verbose: true + token: ${{ secrets.CODECOV_TOKEN }} slack-notify: needs: [run-tests, style-checks] From 6d07777466c7f83c65cfd04a3f592521cdd51b26 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Wed, 16 Jul 2025 19:42:40 +0200 Subject: [PATCH 2/7] Add Codecov Test Analytics --- .github/workflows/ci.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e11d3a..6b3910e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,9 +82,6 @@ jobs: run: composer update ${{ matrix.dependencies_level }} --prefer-dist --no-interaction --no-progress - name: Check composer.json run: composer normalize --dry-run - - name: Run tests with coverage - if: ${{ matrix.os != 'windows-latest' && matrix.php_version == '8.1' && matrix.dependencies_level != '--prefer-lowest' }} - run: php vendor/bin/phpunit --coverage-clover=coverage.xml - name: Run tests run: vendor/bin/phpunit - name: Run integration tests @@ -101,10 +98,18 @@ jobs: - name: Run phan with polyfill if: ${{ matrix.os == 'windows-latest' }} run: vendor/bin/phan --allow-polyfill-parser + - name: Run tests with coverage + if: ${{ matrix.os != 'windows-latest' && matrix.php_version == '8.1' && matrix.dependencies_level != '--prefer-lowest' }} + run: php vendor/bin/phpunit --coverage-clover=coverage.xml --log-junit=junit.xml - name: Upload coverage to Codecov + if: ${{ matrix.os != 'windows-latest' && matrix.php_version == '8.1' && matrix.dependencies_level != '--prefer-lowest' }} uses: codecov/codecov-action@v5 with: - verbose: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results to Codecov + if: ${{ matrix.os != 'windows-latest' && matrix.php_version == '8.1' && matrix.dependencies_level != '--prefer-lowest' }} + uses: codecov/test-results-action@v1 + with: token: ${{ secrets.CODECOV_TOKEN }} slack-notify: From 717fe1f3cfa10c4ae167f2c5c75f0750d866e905 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Mon, 16 Dec 2024 21:29:04 +0100 Subject: [PATCH 3/7] raise minimum PHPStan version --- composer.json | 4 ++-- phpstan.neon | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 475b6a2..7fa6848 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,8 @@ "require-dev": { "ergebnis/composer-normalize": ">=2.19 <2.30", "phan/phan": "^5.4.2", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-strict-rules": "^1.6", "phpunit/phpunit": "^7.5.20 || ^8.5.36 || ^9.6.15", "psalm/plugin-phpunit": "^0.18", "vimeo/psalm": "^4.30" diff --git a/phpstan.neon b/phpstan.neon index 603b51e..a42fc6b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,6 +5,7 @@ parameters: paths: - %rootDir%/../../../MO4 - %rootDir%/../../../tests - checkMissingIterableValueType: false + ignoreErrors: + - identifier: missingType.iterableValue includes: - vendor/phpstan/phpstan-strict-rules/rules.neon From c4646246126978c447b2f86466be5e4b73de91fe Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Wed, 16 Jul 2025 14:17:45 +0200 Subject: [PATCH 4/7] separate static analysis bootstrap --- phpstan.neon | 2 +- psalm.xml | 2 +- tests/static_analysis_bootstrap.php | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 tests/static_analysis_bootstrap.php diff --git a/phpstan.neon b/phpstan.neon index a42fc6b..bab2201 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,7 +1,7 @@ parameters: level: max bootstrapFiles: - - %rootDir%/../../../tests/bootstrap.php + - %rootDir%/../../../tests/static_analysis_bootstrap.php paths: - %rootDir%/../../../MO4 - %rootDir%/../../../tests diff --git a/psalm.xml b/psalm.xml index f4813e5..ab2a6a3 100644 --- a/psalm.xml +++ b/psalm.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" - autoloader="tests/bootstrap.php" + autoloader="tests/static_analysis_bootstrap.php" > diff --git a/tests/static_analysis_bootstrap.php b/tests/static_analysis_bootstrap.php new file mode 100644 index 0000000..5953ddf --- /dev/null +++ b/tests/static_analysis_bootstrap.php @@ -0,0 +1,18 @@ + + * + * @license http://spdx.org/licenses/MIT MIT License + * + * @link https://github.com/mayflower/mo4-coding-standard + */ + +declare(strict_types=1); + +require_once __DIR__.'/../vendor/squizlabs/php_codesniffer/autoload.php'; +require_once __DIR__.'/../vendor/squizlabs/php_codesniffer/src/Util/Tokens.php'; From e0b6f100f59b327d8ab108537087da68fe71873f Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Sun, 26 Jan 2025 17:42:10 +0100 Subject: [PATCH 5/7] Optimize boolean conditions --- MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php | 4 ++-- MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php | 2 +- MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php b/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php index d4ee76b..839d6e0 100644 --- a/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php +++ b/MO4/Sniffs/Arrays/ArrayDoubleArrowAlignmentSniff.php @@ -96,7 +96,7 @@ public function process(File $phpcsFile, $stackPtr): void $previous = $tokens[($i - 1)]; // Skip nested arrays. - if (true === \in_array($current['code'], $this->arrayTokens, true)) { + if (\in_array($current['code'], $this->arrayTokens, true)) { $i = T_ARRAY === $current['code'] ? ($current['parenthesis_closer'] + 1) : ($current['bracket_closer'] + 1); continue; @@ -145,7 +145,7 @@ public function process(File $phpcsFile, $stackPtr): void $j = ($i - 1); while (($j >= 0) && ($tokens[$j]['line'] === $current['line'])) { - if (false === \in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::$emptyTokens, true)) { + if (!\in_array($tokens[$j]['code'], PHP_CodeSniffer_Tokens::$emptyTokens, true)) { $hasKeyInLine = true; } diff --git a/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php b/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php index 86f00e2..02b4ff9 100644 --- a/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php +++ b/MO4/Sniffs/Formatting/AlphabeticalUseStatementsSniff.php @@ -89,7 +89,7 @@ class AlphabeticalUseStatementsSniff extends UseDeclarationSniff */ public function process(File $phpcsFile, $stackPtr): void { - if (false === \in_array($this->order, self::SUPPORTED_ORDERING_METHODS, true)) { + if (!\in_array($this->order, self::SUPPORTED_ORDERING_METHODS, true)) { $error = \sprintf( "'%s' is not a valid order function for %s! Pick one of: %s", $this->order, diff --git a/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php b/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php index 28860e9..0f3ccb3 100644 --- a/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php +++ b/MO4/Sniffs/Formatting/UnnecessaryNamespaceUsageSniff.php @@ -125,7 +125,7 @@ public function process(File $phpcsFile, $stackPtr): void foreach ($tokens[$nsSep]['comment_tags'] as $tag) { $content = $tokens[$tag]['content']; - if (false === \array_key_exists($content, $docCommentTags)) { + if (!\array_key_exists($content, $docCommentTags)) { continue; } @@ -179,7 +179,7 @@ public function process(File $phpcsFile, $stackPtr): void // phpcs:enable foreach ($typeTokens as $typeToken) { - if (true === \in_array($typeToken, $useStatements, true)) { + if (\in_array($typeToken, $useStatements, true)) { continue; } @@ -341,7 +341,7 @@ private function checkShorthandPossible(File $phpcsFile, array $useStatements, s $fullClassName = $this->getFullyQualifiedClassName($className); - if (true === \array_key_exists($fullClassName, $useStatements)) { + if (\array_key_exists($fullClassName, $useStatements)) { $replacement = $useStatements[$fullClassName]; $data = [ From b26599a83fb0be674287ac1608eaa5b3727f97fd Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Sun, 13 Jul 2025 17:56:10 +0200 Subject: [PATCH 6/7] Raise minimum Symfony CS release closes GH-218 --- CHANGELOG.md | 4 ++++ composer.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1221bad..a5facff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [10.0.2] - 2025-07-28 +### Changed +- Raised minimum Symfony CS release, fixes #218 + ## [10.0.1] - 2024-12-16 ### Changed - Fix uninitialized string offset in UnnecessaryNamespaceUsage, fixes #212 diff --git a/composer.json b/composer.json index 7fa6848..615c1e6 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "require": { "php": "~7.2 || ~8.0", "dealerdirect/phpcodesniffer-composer-installer": "~0.7 || ~1.0", - "escapestudios/symfony2-coding-standard": "^3.10.0", + "escapestudios/symfony2-coding-standard": "^3.16.0", "slevomat/coding-standard": "^8.14", "squizlabs/php_codesniffer": "^3.8.0" }, From e88599fffd7feb4b588193fda0e356968d985aa7 Mon Sep 17 00:00:00 2001 From: Michael Moll Date: Mon, 21 Jul 2025 21:07:04 +0200 Subject: [PATCH 7/7] Migrate Codeclimate to Qlty closes GH-220 --- .codeclimate.yml | 12 ------ .github/workflows/ci.yml | 10 ++++- .qlty/.gitignore | 7 +++ .qlty/configs/.yamllint.yaml | 8 ++++ .qlty/qlty.toml | 84 ++++++++++++++++++++++++++++++++++++ README.md | 2 +- 6 files changed, 109 insertions(+), 14 deletions(-) delete mode 100644 .codeclimate.yml create mode 100644 .qlty/.gitignore create mode 100644 .qlty/configs/.yamllint.yaml create mode 100644 .qlty/qlty.toml diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 4a3c616..0000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: "2" -exclude_patterns: - - "integrationtests/" -checks: - method-lines: - config: - threshold: 120 - method-complexity: - config: - threshold: 15 - return-statements: - enabled: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b3910e..b560af9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,6 +111,14 @@ jobs: uses: codecov/test-results-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload coverage to Qlty + if: ${{ matrix.os != 'windows-latest' && matrix.php_version == '8.1' && matrix.dependencies_level != '--prefer-lowest' }} + uses: qltysh/qlty-action/coverage@v1 + with: + token: ${{ secrets.QLTY_COVERAGE_TOKEN }} + files: coverage.xml + env: + QLTY_COVERAGE_TOKEN: ${{ secrets.QLTY_COVERAGE_TOKEN }} slack-notify: needs: [run-tests, style-checks] @@ -122,7 +130,7 @@ jobs: id: slack uses: slackapi/slack-github-action@v1.23.0 with: - # Slack channel id, channel name, or user id to post message. + # Slack channel id, channel name, or user id to post a message. # See also: https://api.slack.com/methods/chat.postMessage#channels channel-id: '#mo4' # For posting a simple plain text message diff --git a/.qlty/.gitignore b/.qlty/.gitignore new file mode 100644 index 0000000..3036618 --- /dev/null +++ b/.qlty/.gitignore @@ -0,0 +1,7 @@ +* +!configs +!configs/** +!hooks +!hooks/** +!qlty.toml +!.gitignore diff --git a/.qlty/configs/.yamllint.yaml b/.qlty/configs/.yamllint.yaml new file mode 100644 index 0000000..d22fa77 --- /dev/null +++ b/.qlty/configs/.yamllint.yaml @@ -0,0 +1,8 @@ +rules: + document-start: disable + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.qlty/qlty.toml b/.qlty/qlty.toml new file mode 100644 index 0000000..3fbf1b1 --- /dev/null +++ b/.qlty/qlty.toml @@ -0,0 +1,84 @@ +# This file was automatically generated by `qlty init`. +# You can modify it to suit your needs. +# We recommend you to commit this file to your repository. +# +# This configuration is used by both Qlty CLI and Qlty Cloud. +# +# Qlty CLI -- Code quality toolkit for developers +# Qlty Cloud -- Fully automated Code Health Platform +# +# Try Qlty Cloud: https://qlty.sh +# +# For a guide to configuration, visit https://qlty.sh/d/config +# Or for a full reference, visit https://qlty.sh/d/qlty-toml +config_version = "0" + +exclude_patterns = [ + "*_min.*", + "*-min.*", + "*.min.*", + "**/.yarn/**", + "**/*.d.ts", + "**/assets/**", + "**/bower_components/**", + "**/build/**", + "**/cache/**", + "**/config/**", + "**/db/**", + "**/deps/**", + "**/dist/**", + "**/extern/**", + "**/external/**", + "**/generated/**", + "**/Godeps/**", + "**/gradlew/**", + "**/mvnw/**", + "**/node_modules/**", + "**/protos/**", + "**/seed/**", + "**/target/**", + "**/templates/**", + "**/testdata/**", + "**/vendor/**", "integrationtests/", +] + +test_patterns = [ + "**/test/**", + "**/spec/**", + "**/*.test.*", + "**/*.spec.*", + "**/*_test.*", + "**/*_spec.*", + "**/test_*.*", + "**/spec_*.*", +] + +[smells] +mode = "comment" + +[smells.boolean_logic] +threshold = 4 + +[smells.file_complexity] +threshold = 55 + +[smells.return_statements] +threshold = 4 +enabled = false + +[smells.nested_control_flow] +threshold = 4 + +[smells.function_parameters] +threshold = 4 + +[smells.function_complexity] +threshold = 16 + +[smells.duplication] +enabled = true +threshold = 20 + +[[source]] +name = "default" +default = true diff --git a/README.md b/README.md index b45e51e..10b0737 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Provides a PHP CodeSniffer ruleset for the MO4 coding standard [![Build Status](https://github.com/mayflower/mo4-coding-standard/actions/workflows/ci.yml/badge.svg)](https://github.com/mayflower/mo4-coding-standard/actions) [![Code Coverage](https://codecov.io/gh/mayflower/mo4-coding-standard/branch/master/graph/badge.svg)](https://codecov.io/gh/mayflower/mo4-coding-standard/branch/master/) -[![Codeclimate Maintainability](https://api.codeclimate.com/v1/badges/16114548a0315d993868/maintainability)](https://codeclimate.com/github/mayflower/mo4-coding-standard/maintainability) +[![Qlty Maintainability](https://qlty.sh/gh/mayflower/projects/mo4-coding-standard/maintainability.svg)](https://qlty.sh/gh/mayflower/projects/mo4-coding-standard) [![SonarQube Maintainability](https://sonarcloud.io/api/project_badges/measure?project=mayflower_mo4-coding-standard&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=mayflower_mo4-coding-standard) [![Latest Stable Version](https://poser.pugx.org/mayflower/mo4-coding-standard/v/stable)](https://packagist.org/packages/mayflower/mo4-coding-standard)