From 1218356db55a791f2784f01e4c16c669046391f8 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 21 Apr 2026 10:29:07 +1000 Subject: [PATCH 1/5] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Support=20drupal/coder?= =?UTF-8?q?=20^9.0=20for=20PHP=208.5=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update drupal/coder ^8.3.26 → ^9.0 - Update squizlabs/php_codesniffer ^3.11.1 → ^4.0.1 - Update slevomat/coding-standard ^8.16.0 → ^8.28.1 - Update dev dependencies to pin minimum versions - Update CI matrix to test PHP 8.2 and 8.5 - Fix renamed sniff reference in tests (Coder 9 API change) - Update PHPCS ignore annotation syntax for v4 Closes #93 --- .github/workflows/workflows.yml | 6 +++--- composer.json | 16 ++++++++-------- tests/Sniffs/AlphabeticallySortedUsesTest.php | 4 ++-- tests/Sniffs/Base.php | 3 +-- tests/Sniffs/DrupalRulesetTest.php | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/workflows.yml b/.github/workflows/workflows.yml index b1fe286..8ad3c02 100644 --- a/.github/workflows/workflows.yml +++ b/.github/workflows/workflows.yml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.3', '8.4'] + php-versions: ['8.2', '8.5'] steps: - uses: actions/checkout@v4 - uses: "shivammathur/setup-php@v2" @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.3', '8.4'] + php-versions: ['8.2', '8.5'] steps: - uses: actions/checkout@v4 - uses: "shivammathur/setup-php@v2" @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.3', '8.4'] + php-versions: ['8.2', '8.5'] dependency-versions: ['highest', 'lowest'] steps: - uses: actions/checkout@v4 diff --git a/composer.json b/composer.json index 7ad7a2c..b549347 100644 --- a/composer.json +++ b/composer.json @@ -5,17 +5,17 @@ "keywords": ["drupal", "phpcs"], "require": { "php": "^8.2", - "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", - "drupal/coder": "^8.3.26", - "slevomat/coding-standard": "^8.16.0", - "squizlabs/php_codesniffer": "^3.11.1" + "dealerdirect/phpcodesniffer-composer-installer": "^1.2", + "drupal/coder": "^9.0", + "slevomat/coding-standard": "^8.28.1", + "squizlabs/php_codesniffer": "^4.0.1" }, "require-dev": { "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.0.3", - "phpstan/phpstan-deprecation-rules": "^2.0.1", - "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "^11.5" + "phpstan/phpstan": "^2.1.50", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^11.5.55" }, "license": "MIT", "autoload": { diff --git a/tests/Sniffs/AlphabeticallySortedUsesTest.php b/tests/Sniffs/AlphabeticallySortedUsesTest.php index bf74e0c..f1fc3a1 100644 --- a/tests/Sniffs/AlphabeticallySortedUsesTest.php +++ b/tests/Sniffs/AlphabeticallySortedUsesTest.php @@ -21,8 +21,8 @@ public function testError(): void { self::assertSniffError($report, 8, AlphabeticallySortedUsesSniff::CODE_INCORRECT_ORDER); } - protected static function getSniffName(): string { - return 'SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses'; + protected static function getSniffClassName(): string { + return AlphabeticallySortedUsesSniff::class; } } diff --git a/tests/Sniffs/Base.php b/tests/Sniffs/Base.php index a57f093..bcdad6e 100644 --- a/tests/Sniffs/Base.php +++ b/tests/Sniffs/Base.php @@ -1,8 +1,7 @@ getErrorCount()); - self::assertSniffError($report, 5, sniffName: 'Drupal.ControlStructures.InlineControlStructure', code: 'NotAllowed'); + self::assertSniffError($report, 5, sniffName: 'Generic.ControlStructures.InlineControlStructure', code: 'NotAllowed'); self::assertSniffError($report, 5, sniffName: 'Generic.PHP.UpperCaseConstant', code: 'Found'); } From c14410390028b22ebfc2c25ef21f095922046c76 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 21 Apr 2026 10:32:01 +1000 Subject: [PATCH 2/5] Fix PHPStan null array key error in Base.php --- tests/Sniffs/Base.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Sniffs/Base.php b/tests/Sniffs/Base.php index bcdad6e..e28d35f 100644 --- a/tests/Sniffs/Base.php +++ b/tests/Sniffs/Base.php @@ -45,8 +45,9 @@ protected static function checkFile(string $filePath, array $sniffProperties = [ $codeSniffer->init(); - if (count($sniffProperties) > 0) { - $codeSniffer->ruleset->ruleset[self::getSniffName()]['properties'] = $sniffProperties; + $sniffName = self::getSniffName(); + if (count($sniffProperties) > 0 && $sniffName !== null) { + $codeSniffer->ruleset->ruleset[$sniffName]['properties'] = $sniffProperties; } $sniffClassName = static::getSniffClassName(); From e12b3afeebfbee7abd51afbef2829528ad18b7e5 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 21 Apr 2026 11:41:23 +1000 Subject: [PATCH 3/5] Support both drupal/coder ^8 and ^9 - Allow drupal/coder ^8.3.26 || ^9.0 and squizlabs/php_codesniffer ^3.9.1 || ^4.0.1 - Add version detection helper for conditional test assertions - Test PHP 8.2-8.5 with lowest/highest dependency matrix --- .github/workflows/workflows.yml | 6 +++--- composer.json | 16 ++++++++-------- tests/Sniffs/Base.php | 10 ++++++++++ tests/Sniffs/DrupalRulesetTest.php | 6 +++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/workflows.yml b/.github/workflows/workflows.yml index 8ad3c02..6250e2e 100644 --- a/.github/workflows/workflows.yml +++ b/.github/workflows/workflows.yml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.5'] + php-versions: ['8.2', '8.3', '8.4', '8.5'] steps: - uses: actions/checkout@v4 - uses: "shivammathur/setup-php@v2" @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.5'] + php-versions: ['8.2', '8.3', '8.4', '8.5'] steps: - uses: actions/checkout@v4 - uses: "shivammathur/setup-php@v2" @@ -41,7 +41,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.2', '8.5'] + php-versions: ['8.2', '8.3', '8.4', '8.5'] dependency-versions: ['highest', 'lowest'] steps: - uses: actions/checkout@v4 diff --git a/composer.json b/composer.json index b549347..a5a0da9 100644 --- a/composer.json +++ b/composer.json @@ -5,17 +5,17 @@ "keywords": ["drupal", "phpcs"], "require": { "php": "^8.2", - "dealerdirect/phpcodesniffer-composer-installer": "^1.2", - "drupal/coder": "^9.0", - "slevomat/coding-standard": "^8.28.1", - "squizlabs/php_codesniffer": "^4.0.1" + "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", + "drupal/coder": "^8.3.26 || ^9.0", + "slevomat/coding-standard": "^8.11", + "squizlabs/php_codesniffer": "^3.9.1 || ^4.0.1" }, "require-dev": { "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.50", - "phpstan/phpstan-deprecation-rules": "^2.0.4", - "phpstan/phpstan-strict-rules": "^2.0.10", - "phpunit/phpunit": "^11.5.55" + "phpstan/phpstan": "^2.0.3", + "phpstan/phpstan-deprecation-rules": "^2.0.1", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^11.5" }, "license": "MIT", "autoload": { diff --git a/tests/Sniffs/Base.php b/tests/Sniffs/Base.php index e28d35f..21a8614 100644 --- a/tests/Sniffs/Base.php +++ b/tests/Sniffs/Base.php @@ -7,6 +7,7 @@ namespace PreviousNext\CodingStandard\Tests\Sniffs; +use Composer\InstalledVersions; use Drupal\Sniffs\Commenting\FileCommentSniff; use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Files\File; @@ -23,6 +24,7 @@ use function preg_replace; use function sprintf; use function strpos; +use function version_compare; /** * @codeCoverageIgnore @@ -220,4 +222,12 @@ protected static function excludeSniffs(): array { ]; } + /** + * Check if drupal/coder 9.x or higher is installed. + */ + protected static function isCoderVersion9OrHigher(): bool { + $version = InstalledVersions::getVersion('drupal/coder'); + return $version !== null && version_compare($version, '9.0.0', '>='); + } + } diff --git a/tests/Sniffs/DrupalRulesetTest.php b/tests/Sniffs/DrupalRulesetTest.php index f7f3991..2c7c414 100644 --- a/tests/Sniffs/DrupalRulesetTest.php +++ b/tests/Sniffs/DrupalRulesetTest.php @@ -17,7 +17,11 @@ public function testNoError(): void { public function testMissing(): void { $report = self::checkFile(__DIR__ . '/fixtures/DrupalRulesetError.php'); self::assertSame(2, $report->getErrorCount()); - self::assertSniffError($report, 5, sniffName: 'Generic.ControlStructures.InlineControlStructure', code: 'NotAllowed'); + // Sniff name changed in drupal/coder 9.x. + $inlineControlSniff = self::isCoderVersion9OrHigher() + ? 'Generic.ControlStructures.InlineControlStructure' + : 'Drupal.ControlStructures.InlineControlStructure'; + self::assertSniffError($report, 5, sniffName: $inlineControlSniff, code: 'NotAllowed'); self::assertSniffError($report, 5, sniffName: 'Generic.PHP.UpperCaseConstant', code: 'Found'); } From b38881692ee26a0eaff5e00dddbfbe9ac5c0254e Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 21 Apr 2026 14:16:23 +1000 Subject: [PATCH 4/5] Use feature detection instead of version checking --- tests/Sniffs/Base.php | 10 ---------- tests/Sniffs/DrupalRulesetTest.php | 8 ++++---- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/Sniffs/Base.php b/tests/Sniffs/Base.php index 21a8614..e28d35f 100644 --- a/tests/Sniffs/Base.php +++ b/tests/Sniffs/Base.php @@ -7,7 +7,6 @@ namespace PreviousNext\CodingStandard\Tests\Sniffs; -use Composer\InstalledVersions; use Drupal\Sniffs\Commenting\FileCommentSniff; use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Files\File; @@ -24,7 +23,6 @@ use function preg_replace; use function sprintf; use function strpos; -use function version_compare; /** * @codeCoverageIgnore @@ -222,12 +220,4 @@ protected static function excludeSniffs(): array { ]; } - /** - * Check if drupal/coder 9.x or higher is installed. - */ - protected static function isCoderVersion9OrHigher(): bool { - $version = InstalledVersions::getVersion('drupal/coder'); - return $version !== null && version_compare($version, '9.0.0', '>='); - } - } diff --git a/tests/Sniffs/DrupalRulesetTest.php b/tests/Sniffs/DrupalRulesetTest.php index 2c7c414..961fda7 100644 --- a/tests/Sniffs/DrupalRulesetTest.php +++ b/tests/Sniffs/DrupalRulesetTest.php @@ -17,10 +17,10 @@ public function testNoError(): void { public function testMissing(): void { $report = self::checkFile(__DIR__ . '/fixtures/DrupalRulesetError.php'); self::assertSame(2, $report->getErrorCount()); - // Sniff name changed in drupal/coder 9.x. - $inlineControlSniff = self::isCoderVersion9OrHigher() - ? 'Generic.ControlStructures.InlineControlStructure' - : 'Drupal.ControlStructures.InlineControlStructure'; + // Sniff removed in drupal/coder 9.x. + $inlineControlSniff = \class_exists(\Drupal\Sniffs\ControlStructures\InlineControlStructureSniff::class) + ? 'Drupal.ControlStructures.InlineControlStructure' + : 'Generic.ControlStructures.InlineControlStructure'; self::assertSniffError($report, 5, sniffName: $inlineControlSniff, code: 'NotAllowed'); self::assertSniffError($report, 5, sniffName: 'Generic.PHP.UpperCaseConstant', code: 'Found'); } From f0cf499bed498ff0ca21ca87e186cbff49efdbb4 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Tue, 21 Apr 2026 14:17:58 +1000 Subject: [PATCH 5/5] Fix PHPCS: use statement for namespaced class --- tests/Sniffs/DrupalRulesetTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Sniffs/DrupalRulesetTest.php b/tests/Sniffs/DrupalRulesetTest.php index 961fda7..0779581 100644 --- a/tests/Sniffs/DrupalRulesetTest.php +++ b/tests/Sniffs/DrupalRulesetTest.php @@ -4,6 +4,8 @@ namespace PreviousNext\CodingStandard\Tests\Sniffs; +use Drupal\Sniffs\ControlStructures\InlineControlStructureSniff; + /** * Tests inherits from Drupal ruleset. */ @@ -18,7 +20,7 @@ public function testMissing(): void { $report = self::checkFile(__DIR__ . '/fixtures/DrupalRulesetError.php'); self::assertSame(2, $report->getErrorCount()); // Sniff removed in drupal/coder 9.x. - $inlineControlSniff = \class_exists(\Drupal\Sniffs\ControlStructures\InlineControlStructureSniff::class) + $inlineControlSniff = \class_exists(InlineControlStructureSniff::class) ? 'Drupal.ControlStructures.InlineControlStructure' : 'Generic.ControlStructures.InlineControlStructure'; self::assertSniffError($report, 5, sniffName: $inlineControlSniff, code: 'NotAllowed');