diff --git a/.github/linters/.codespellrc b/.github/linters/.codespellrc index 303604d..636396c 100644 --- a/.github/linters/.codespellrc +++ b/.github/linters/.codespellrc @@ -1,2 +1,2 @@ [codespell] -skip = ./.git,.claude/*,.codex/*,.vscode/*,code_coverage/*,composer.lock,runtime/*,scaffold-lock.json,vendor/*,*/tests/*,tests/**,*/composer.lock,*/composer.json,*/package-lock.json,*/dist/*,*/node_modules/* +skip = ./.git,.claude/*,.codex/*,.config/gh/*,.github/agents/*,.github/copilot-instructions.md,.github/copilot/*,.github/instructions/*,.github/prompts/*,.github/skills/*,.vscode/*,*/composer.json,*/composer.lock,*/dist/*,*/node_modules/*,*/package-lock.json,*/tests/*,code_coverage/*,CHANGELOG.md,UPGRADE.md,runtime/*,scaffold-lock.json,vendor/* diff --git a/.github/linters/.editorconfig-checker.json b/.github/linters/.editorconfig-checker.json index 0e57707..3b52d57 100644 --- a/.github/linters/.editorconfig-checker.json +++ b/.github/linters/.editorconfig-checker.json @@ -1,16 +1,23 @@ { "Exclude": [ + "\\.min\\.css$", + "\\.min\\.js$", "^\\.claude/", "^\\.codex/", + "^\\.config/gh/", + "^\\.github/agents/", + "^\\.github/copilot-instructions\\.md$", + "^\\.github/copilot/", + "^\\.github/instructions/", + "^\\.github/prompts/", + "^\\.github/skills/", "^\\.vscode/", "^code_coverage/", "^composer\\.lock$", - "phpstan-baseline\\.neon$", + "^runtime/", "^tests/runtime/", - "\\.min\\.css$", - "\\.min\\.js$", "^vendor/", - "^runtime/", + "phpstan-baseline\\.neon$", "scaffold-lock\\.json$" ] } diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 8b3d9e6..fc7f2ab 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -17,6 +17,4 @@ jobs: codespell-config: .github/linters/.codespellrc editorconfig-checker-config: .github/linters/.editorconfig-checker.json markdownlint-config: .github/linters/.markdown-lint.yml - prettier-config: .prettierrc.json - prettier-ignore-path: .prettierignore yamllint-targets: .github diff --git a/.gitignore b/.gitignore index b38f935..f5ae66e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -# AI agents (if present) -.codex +# Local AI agent, editor, and GitHub CLI config (if present) .claude +.codex +.config/gh # codecoverage (if present) code_coverage @@ -11,7 +12,7 @@ c3.php # composer composer.lock -# gitHub copilot config (if present) +# GitHub Copilot config (if present) .github/agents/** .github/copilot-instructions.md .github/copilot/** @@ -28,18 +29,74 @@ nbproject # node_modules (if present) node_modules package-lock.json -!src/assets/package-lock.json + +# phpstorm project (if present) +.idea # phpactor (if present) .phpactor.* +# phpunit (if present) +.phpunit.cache +.phpunit.result.cache + +# vagrant (if present) +.vagrant + +# vendor +vendor + +# vscode project (if present) +.vscode + +# windows thumbnail cache (if present) +Thumbs.db + +# zend studio for eclipse project (if present) +.buildpath +.project +.settings +# Local AI agent, editor, and GitHub CLI config (if present) +.claude +.codex +.config/gh + +# codecoverage (if present) +code_coverage + +# codeception (if present) +c3.php + +# composer +composer.lock + +# GitHub Copilot config (if present) +.github/agents/** +.github/copilot-instructions.md +.github/copilot/** +.github/instructions/** +.github/prompts/** +.github/skills/** + +# mac ds_store (if present) +.DS_Store + +# netbeans project (if present) +nbproject + +# node_modules (if present) +node_modules +package-lock.json + # phpstorm project (if present) .idea +# phpactor (if present) +.phpactor.* + # phpunit (if present) .phpunit.cache .phpunit.result.cache -phpunit.xml # vagrant (if present) .vagrant diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 37e9c50..0000000 --- a/.prettierignore +++ /dev/null @@ -1,21 +0,0 @@ -# Local agent, editor, coverage, and generated runtime state. -.claude/** -.codex/** -.vscode/** -code_coverage/** -runtime/** - -# Dependencies. -vendor/** - -# Dependency lockfile ignored by git. -composer.lock - -# License texts ship verbatim. -**/LICENSE* - -# Tool config maintained by hand to keep array order meaningful. -composer-require-checker.json - -# Auto-generated by yii2-extensions/scaffold. -scaffold-lock.json diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 8f87fe1..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": false, - "singleQuote": false, - "trailingComma": "all", - "printWidth": 80, - "overrides": [ - { - "files": ["**/*.{js,jsx,ts,tsx,vue,css,scss,html,yml,yaml}"], - "options": { - "tabWidth": 2 - } - }, - { - "files": "**/*.md", - "options": { - "embeddedLanguageFormatting": "off", - "tabWidth": 2 - } - }, - { - "files": ["**/package.json", "**/package-lock.json"], - "options": { - "tabWidth": 2 - } - } - ] -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 74ffe3a..c9e4b48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.3.4 Under development +- fix: support ECS `13.3.2+` with the native PER-CS set and explicit PHP `8.1-8.4` migration rules instead of the removed `withPhpCsFixerSets()` arguments. + ## 0.3.3 July 05, 2026 - ci: replace Super-Linter with reusable quality and security workflows, pin reusable ECS workflow, group Dependabot updates, and refresh linter and Gitleaks configs. diff --git a/README.md b/README.md index 9079904..f97717e 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ Or add the dependency manually to `composer.json`: ```json { - "require-dev": { - "php-forge/coding-standard": "^0.3" - } + "require-dev": { + "php-forge/coding-standard": "^0.3" + } } ``` @@ -146,19 +146,17 @@ composer require yii2-extensions/scaffold:^0.1 --dev ```json { - "config": { - "allow-plugins": { - "yii2-extensions/scaffold": true - } - }, - "extra": { - "scaffold": { - "auto": false, - "allowed-packages": [ - "php-forge/coding-standard" - ] - } + "config": { + "allow-plugins": { + "yii2-extensions/scaffold": true + } + }, + "extra": { + "scaffold": { + "auto": false, + "allowed-packages": ["php-forge/coding-standard"] } + } } ``` @@ -182,10 +180,10 @@ Follow the same convention used across PHP Forge repositories: ```json { - "scripts": { - "ecs": "./vendor/bin/ecs --fix", - "rector": "./vendor/bin/rector process" - } + "scripts": { + "ecs": "./vendor/bin/ecs --fix", + "rector": "./vendor/bin/rector process" + } } ``` diff --git a/composer.json b/composer.json index fdf3a5b..3830292 100644 --- a/composer.json +++ b/composer.json @@ -21,10 +21,10 @@ "require": { "php": ">=8.1", "rector/rector": "^2.4", - "symplify/easy-coding-standard": "^13.2" + "symplify/easy-coding-standard": "^13.3.2" }, "require-dev": { - "php-forge/baseline": "^0.1", + "php-forge/baseline": "^0.2", "yii2-extensions/scaffold": "^0.2" }, "autoload": { @@ -50,6 +50,7 @@ } }, "scripts": { + "tests": "php tests/ecs.php", "ecs": "./vendor/bin/ecs check src --config src/ecs-83.php --fix", "rector": "./vendor/bin/rector process src --config src/rector-83.php" } diff --git a/scaffold-lock.json b/scaffold-lock.json index 0098675..e38cd29 100644 --- a/scaffold-lock.json +++ b/scaffold-lock.json @@ -1,7 +1,7 @@ { "providers": { "php-forge/baseline": { - "version": "0.1.3", + "version": "0.2.0", "path": "vendor/php-forge/baseline" } }, @@ -19,7 +19,7 @@ "mode": "replace" }, ".gitignore": { - "hash": "sha256:9e5e968a4f71578af06247a009998c24d27682fa88f4c0883de2e4bec80d45ca", + "hash": "sha256:c2f25a729e950d919448fae89454bdb53cb22700a4d19da6dce4303fcf5d00a3", "provider": "php-forge/baseline", "source": "metadata/.gitignore", "mode": "append" @@ -30,24 +30,6 @@ "source": "metadata/.styleci.yml", "mode": "replace" }, - ".prettierignore": { - "hash": "sha256:f4b6198902354d400815e6169439b5805da5ce8fb50797f9ec79c6f91e6c22a4", - "provider": "php-forge/baseline", - "source": "metadata/.prettierignore", - "mode": "replace" - }, - ".prettierrc.json": { - "hash": "sha256:4bf1ad096981736c7bd00136026e046f4b23fcefa1f8db84dcd0bacac19e97a2", - "provider": "php-forge/baseline", - "source": "metadata/.prettierrc.json", - "mode": "replace" - }, - ".stylelintignore": { - "hash": "sha256:12186f0a5c42b4f894f7bdda1b1ca5ebc69f92d906aa9075a459d4d08fe4edc1", - "provider": "php-forge/baseline", - "source": "metadata/.stylelintignore", - "mode": "replace" - }, "composer-require-checker.json": { "hash": "sha256:f4fbbc7876fa3f695b69dd7dc7ad4637d33dfab97fe445b476de26480f85055d", "provider": "php-forge/baseline", @@ -55,13 +37,13 @@ "mode": "preserve" }, ".github/linters/.codespellrc": { - "hash": "sha256:b1a66a59f2042ac1601a277d09b21326aa8c85da8ba18592a138d1681760c9c7", + "hash": "sha256:0ec9825d6022c7b0edcdbc6f8a8e3fdea30bbd65f76084cc9f046bdd432bdc1f", "provider": "php-forge/baseline", "source": "metadata/.github/linters/.codespellrc", "mode": "replace" }, ".github/linters/.editorconfig-checker.json": { - "hash": "sha256:83ce0f9e83f68fb23500061cb17836eaa5e3107df93cc4ccfb578a7500b7f958", + "hash": "sha256:17587db6b4d163e43b47dd1f55809b2ab6f3a2d9b170ca88fdd23d703feb3064", "provider": "php-forge/baseline", "source": "metadata/.github/linters/.editorconfig-checker.json", "mode": "replace" diff --git a/src/ecs-81.php b/src/ecs-81.php index ef597ff..077ee3b 100644 --- a/src/ecs-81.php +++ b/src/ecs-81.php @@ -5,21 +5,12 @@ /** * ECS configuration targeting PHP `8.1` syntax. * - * Adds the `@PHP81Migration` PHP-CS-Fixer set on top of the shared base configuration. + * Adds explicit ECS rules equivalent to the `@PHP81Migration` PHP-CS-Fixer set. * - * ```php - * withPaths([__DIR__ . '/src', __DIR__ . '/tests']); - * ``` - * - * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder + * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder */ $builder = require __DIR__ . '/ecs.php'; -return $builder->withPhpCsFixerSets(php81Migration: true); +return $builder->withSets( + [__DIR__ . '/sets/php-81.php'], +); diff --git a/src/ecs-82.php b/src/ecs-82.php index a26dc91..7baf434 100644 --- a/src/ecs-82.php +++ b/src/ecs-82.php @@ -5,21 +5,12 @@ /** * ECS configuration targeting PHP `8.2` syntax. * - * Adds the `@PHP82Migration` PHP-CS-Fixer set on top of the shared base configuration. + * Adds explicit ECS rules equivalent to the `@PHP82Migration` PHP-CS-Fixer set. * - * ```php - * withPaths([__DIR__ . '/src', __DIR__ . '/tests']); - * ``` - * - * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder + * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder */ $builder = require __DIR__ . '/ecs.php'; -return $builder->withPhpCsFixerSets(php82Migration: true); +return $builder->withSets( + [__DIR__ . '/sets/php-82.php'], +); diff --git a/src/ecs-83.php b/src/ecs-83.php index 5ce4827..422ad83 100644 --- a/src/ecs-83.php +++ b/src/ecs-83.php @@ -5,21 +5,12 @@ /** * ECS configuration targeting PHP `8.3` syntax. * - * Adds the `@PHP83Migration` PHP-CS-Fixer set on top of the shared base configuration. + * Adds explicit ECS rules equivalent to the `@PHP83Migration` PHP-CS-Fixer set. * - * ```php - * withPaths([__DIR__ . '/src', __DIR__ . '/tests']); - * ``` - * - * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder + * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder */ $builder = require __DIR__ . '/ecs.php'; -return $builder->withPhpCsFixerSets(php83Migration: true); +return $builder->withSets( + [__DIR__ . '/sets/php-82.php'], +); diff --git a/src/ecs-84.php b/src/ecs-84.php index 63d08be..cbc0862 100644 --- a/src/ecs-84.php +++ b/src/ecs-84.php @@ -5,21 +5,12 @@ /** * ECS configuration targeting PHP `8.4` syntax. * - * Adds the `@PHP84Migration` PHP-CS-Fixer set on top of the shared base configuration. + * Adds explicit ECS rules equivalent to the `@PHP84Migration` PHP-CS-Fixer set. * - * ```php - * withPaths([__DIR__ . '/src', __DIR__ . '/tests']); - * ``` - * - * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder + * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder */ $builder = require __DIR__ . '/ecs.php'; -return $builder->withPhpCsFixerSets(php84Migration: true); +return $builder->withSets( + [__DIR__ . '/sets/php-84.php'], +); diff --git a/src/ecs.php b/src/ecs.php index 84df174..62fdd6a 100644 --- a/src/ecs.php +++ b/src/ecs.php @@ -12,18 +12,6 @@ use PhpCsFixer\Fixer\Whitespace\HeredocIndentationFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; -/** - * Shared base ECS configuration. - * - * This file intentionally contains no project-specific paths and no PHP-version migration set. Consumer repositories - * should require either this file (no migration) or one of the version-pinned wrappers (`ecs-81.php`, `ecs-82.php`, - * `ecs-83.php`, `ecs-84.php`) and set their own paths. - * - * The "strict" prepared set is intentionally NOT used: it was deprecated in Symplify ECS `13` with guidance to enable - * the underlying fixers explicitly so the consumer keeps direct control over the strict-typing surface. The three - * fixers it used to bundle (`DeclareStrictTypesFixer`, `StrictComparisonFixer`, `StrictParamFixer`) are added as - * individual rules below to preserve behavior. - */ return ECSConfig::configure() ->withConfiguredRule( ClassDefinitionFixer::class, @@ -80,8 +68,8 @@ ['call_type' => 'self'], ) ->withFileExtensions(['php']) - ->withPhpCsFixerSets(perCS30: true) ->withPreparedSets( + perCs: true, cleanCode: true, comments: true, docblocks: true, diff --git a/src/sets/php-81.php b/src/sets/php-81.php new file mode 100644 index 0000000..446c5a2 --- /dev/null +++ b/src/sets/php-81.php @@ -0,0 +1,49 @@ +withConfiguredRule( + MethodArgumentSpaceFixer::class, + ['after_heredoc' => true], + ) + ->withConfiguredRule( + NoWhitespaceBeforeCommaInArrayFixer::class, + ['after_heredoc' => true], + ) + ->withConfiguredRule( + TrailingCommaInMultilineFixer::class, + ['after_heredoc' => true], + ) + ->withRules( + [ + ArraySyntaxFixer::class, + AssignNullCoalescingToCoalesceEqualFixer::class, + CleanNamespaceFixer::class, + HeredocIndentationFixer::class, + ListSyntaxFixer::class, + ModifierKeywordsFixer::class, + NormalizeIndexBraceFixer::class, + NoUnsetCastFixer::class, + OctalNotationFixer::class, + ShortScalarCastFixer::class, + TernaryToNullCoalescingFixer::class, + ], + ); diff --git a/src/sets/php-82.php b/src/sets/php-82.php new file mode 100644 index 0000000..2e84f13 --- /dev/null +++ b/src/sets/php-82.php @@ -0,0 +1,17 @@ +withSets( + [__DIR__ . '/php-81.php'], + ) + ->withRules( + [SimpleToComplexStringVariableFixer::class], + ); diff --git a/src/sets/php-84.php b/src/sets/php-84.php new file mode 100644 index 0000000..cf5a8b9 --- /dev/null +++ b/src/sets/php-84.php @@ -0,0 +1,21 @@ +withSets( + [__DIR__ . '/php-82.php'], + ) + ->withRules( + [ + NewExpressionParenthesesFixer::class, + NullableTypeDeclarationForDefaultNullValueFixer::class, + ], + );