diff --git a/.ecrc b/.ecrc
new file mode 100644
index 0000000..4e244a2
--- /dev/null
+++ b/.ecrc
@@ -0,0 +1,10 @@
+{
+ "Exclude": [
+ "phpstan-baseline\\.neon$",
+ "^tests/runtime/",
+ "\\.min\\.css$",
+ "\\.min\\.js$",
+ "^vendor/",
+ "^runtime/"
+ ]
+}
diff --git a/.editorconfig b/.editorconfig
index 518c149..ef7ce10 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -14,6 +14,7 @@ trim_trailing_whitespace = true
indent_size = 2
[*.md]
+indent_size = 2
trim_trailing_whitespace = false
[*.php]
diff --git a/.gitattributes b/.gitattributes
index fdf0ca4..56db1bf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -21,24 +21,17 @@
*.gif binary
*.ttf binary
-# Avoid merge conflicts in CHANGELOG
-# https://about.gitlab.com/2015/02/10/gitlab-reduced-merge-conflicts-by-90-percent-with-changelog-placeholders/
-/CHANGELOG.md merge=union
-
# Exclude files from the archive
-/.editorconfig export-ignore
-/.gitattributes export-ignore
-/.github export-ignore
-/.gitignore export-ignore
-/.styleci.yml export-ignore
+/.github/dependabot.yml export-ignore
+/.github/workflows export-ignore
/codeception.yml export-ignore
-/composer-require-checker.json export-ignore
/docs export-ignore
-/ecs.php export-ignore
/infection.json* export-ignore
/phpstan*.neon* export-ignore
/phpunit.xml.dist export-ignore
-/psalm.xml export-ignore
-/rector.php export-ignore
/runtime export-ignore
/tests export-ignore
+
+# Avoid merge conflicts in CHANGELOG
+# https://about.gitlab.com/2015/02/10/gitlab-reduced-merge-conflicts-by-90-percent-with-changelog-placeholders/
+/CHANGELOG.md merge=union
diff --git a/.github/linters/.codespellrc b/.github/linters/.codespellrc
new file mode 100644
index 0000000..1375eee
--- /dev/null
+++ b/.github/linters/.codespellrc
@@ -0,0 +1,2 @@
+[codespell]
+skip = */tests/*,tests/**,*/composer.lock,*/composer.json
diff --git a/.github/linters/.gitleaks.toml b/.github/linters/.gitleaks.toml
new file mode 100644
index 0000000..fba3f57
--- /dev/null
+++ b/.github/linters/.gitleaks.toml
@@ -0,0 +1,7 @@
+title = "gitleaks config"
+
+[[allowlists]]
+description = "Allow test fixture data with dummy credentials"
+paths = [
+ '''tests/support/data/.*\.php''',
+]
diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml
new file mode 100644
index 0000000..0a6d8fc
--- /dev/null
+++ b/.github/linters/.markdown-lint.yml
@@ -0,0 +1,5 @@
+---
+MD007:
+ indent: 2
+MD013: false
+MD033: false
diff --git a/.github/workflows/ecs.yml b/.github/workflows/ecs.yml
index e18f15c..73388d3 100644
--- a/.github/workflows/ecs.yml
+++ b/.github/workflows/ecs.yml
@@ -19,3 +19,5 @@ permissions:
jobs:
easy-coding-standard:
uses: yii2-framework/actions/.github/workflows/ecs.yml@main
+ with:
+ command-options: check src --config src/ecs-83.php --ansi
diff --git a/.gitignore b/.gitignore
index d4c5c11..848ddae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,9 @@ package-lock.json
# phpstorm project (if present)
.idea
+# phpactor (if present)
+.phpactor.*
+
# phpunit (if present)
.phpunit.cache
.phpunit.result.cache
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..9793904
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,18 @@
+**/*.min.css
+**/*.min.js
+
+# Vite-built bundles (committed dist/) and lockfiles.
+**/dist/**
+**/node_modules/**
+**/package-lock.json
+
+# Yii AssetManager publishes a hashed copy of src/assets/ under tests/runtime/
+# whenever phpunit runs; the tree is regenerated on every test run, never
+# authored, and ignored by git already.
+tests/runtime/**
+
+# License texts ship verbatim — never auto-formatted.
+**/LICENSE*
+
+# Tool configs maintained by hand to keep their array order meaningful.
+composer-require-checker.json
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..8f87fe1
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,28 @@
+{
+ "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/.stylelintignore b/.stylelintignore
new file mode 100644
index 0000000..fd04c4f
--- /dev/null
+++ b/.stylelintignore
@@ -0,0 +1 @@
+**/*.min.css
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6102953..1f5af48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,16 @@
# Changelog
-## 0.1.1 Under development
+All notable changes to this project will be documented in this file.
-- Enh #3: Add social media badge for following on X in `README.md` (@terabytesoftw)
+The format is based on [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.2.0 Under development
+
+- docs: add social media badge for following on X in `README.md`.
+- feat!: convert into `yii2-extensions/scaffold` provider; centralize ECS, Rector, metadata and super-linter standards under `src/`.
## 0.1.0 January 24, 2026
-- Enh #1: Added shared configuration files under `config/` for Composer-based reuse (@terabytesoftw)
-- Bug #2: Update quality code section with `Super-Linter` and `StyleCI` badges (@terabytesoftw)
+- feat: add shared configuration files under `config/` for Composer-based reuse.
+- docs: update quality code section with `Super-Linter` and `StyleCI` badges.
diff --git a/README.md b/README.md
index 5b2eb8c..609f8f7 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-
+
Coding standard
@@ -23,42 +23,34 @@
## Installation
```bash
-composer require php-forge/coding-standard:^0.1 --dev
+composer require php-forge/coding-standard:^0.2 --dev
```
-## Quick start
+## Configuration files
-This package provides shared configuration files under `vendor/php-forge/coding-standard/config/`:
+This package ships shared ECS and Rector configurations under
+`vendor/php-forge/coding-standard/src/`:
-- `config/ecs.php` (shared ECS rules, no paths)
-- `config/rector.php` (shared Rector rules, no paths)
+| File | Purpose |
+| ------------------- | ------------------------------------------------------- |
+| `src/ecs.php` | Shared ECS base rules, no PHP migration set |
+| `src/ecs-81.php` | Base + `@PHP81Migration` PHP-CS-Fixer set |
+| `src/ecs-82.php` | Base + `@PHP82Migration` |
+| `src/ecs-83.php` | Base + `@PHP83Migration` |
+| `src/ecs-84.php` | Base + `@PHP84Migration` |
+| `src/rector.php` | Shared Rector base rules, no PHP level set |
+| `src/rector-81.php` | Base + `SetList::PHP_81` + `LevelSetList::UP_TO_PHP_81` |
+| `src/rector-82.php` | Base + `SetList::PHP_82` + `LevelSetList::UP_TO_PHP_82` |
+| `src/rector-83.php` | Base + `SetList::PHP_83` + `LevelSetList::UP_TO_PHP_83` |
+| `src/rector-84.php` | Base + `SetList::PHP_84` + `LevelSetList::UP_TO_PHP_84` |
-Consumer repositories should create wrapper config files at the repository root.
-Wrappers define the paths for that repository and import the shared configuration.
+Pick the version that matches the **minimum** PHP your project supports; Rector upgrades code up to that level and
+PHP-CS-Fixer enforces matching syntax. The plain `ecs.php` / `rector.php` apply no PHP-version migrations.
-### Generic repository
+### ECS wrapper (ecs.php)
-#### ECS (ecs.php)
-
-Create `ecs.php` in your repository root:
-
-```php
-withPaths(
- [
- __DIR__ . '/src',
- __DIR__ . '/tests',
- ],
-);
-```
-
-To override or skip rules locally, apply changes after requiring the shared config:
+Create `ecs.php` in your repository root, requiring the version that matches
+the minimum PHP your project supports (`ecs-83.php` for PHP 8.3, etc.):
```php
withPaths(
@@ -77,14 +69,15 @@ return $ecsConfigBuilder
)
->withSkip(
[
- // add project-specific skips here.
+ // project-specific skips here.
],
);
```
-#### Rector (rector.php)
+### Rector wrapper (rector.php)
-Create `rector.php` in your repository root:
+Create `rector.php` in your repository root, importing the version that
+matches your minimum PHP target:
```php
import(__DIR__ . '/vendor/php-forge/coding-standard/config/rector.php');
+ $rectorConfig->import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-83.php');
$rectorConfig->paths(
[
@@ -108,12 +101,11 @@ return static function (RectorConfig $rectorConfig): void {
};
```
-### Yii2 repositories
-
-If you need framework-specific rules (Yii2), keep them in a separate config file (or a separate package)
-and import it after the base configuration. Do not mix Yii2-specific rules into the generic base.
+### Yii2-specific rules
-Example (Rector):
+For framework-specific rules, keep them in a separate config file (or a
+separate package) and import it after the base configuration. Do not mix Yii2
+rules into the generic base:
```php
import(__DIR__ . '/vendor/php-forge/coding-standard/config/rector.php');
+ $rectorConfig->import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector.php');
$rectorConfig->import(__DIR__ . '/rector-yii2.php');
$rectorConfig->paths(
@@ -135,6 +127,76 @@ return static function (RectorConfig $rectorConfig): void {
};
```
+## Scaffolded distribution (optional)
+
+This package is also a [`yii2-extensions/scaffold`](https://github.com/yii2-extensions/scaffold) provider.
+
+When the scaffold plugin is installed and authorized, `composer install` distributes the canonical metadata and
+super-linter configs into your repository root automatically; so the ECS / Rector wrappers above and the shared linter
+rules stay in lock-step across every repository that opts in.
+
+Opt in by adding the plugin and authorizing this package as a provider:
+
+```bash
+composer require yii2-extensions/scaffold:^0.1 --dev
+```
+
+```json
+{
+ "config": {
+ "allow-plugins": {
+ "yii2-extensions/scaffold": true
+ }
+ },
+ "extra": {
+ "scaffold": {
+ "allowed-packages": [
+ "php-forge/coding-standard"
+ ]
+ }
+ }
+}
+```
+
+On the next `composer install` / `composer update`, these files land in your repository root:
+
+| File | Mode | Purpose |
+| ------------------------------------ | ---------- | -------------------------------------------------------- |
+| `.editorconfig` | `replace` | Editor settings (UTF-8, LF, indent) |
+| `.gitattributes` | `replace` | Text/binary handling, archive excludes |
+| `.gitignore` | `append` | Common ignore patterns; project-specific lines preserved |
+| `.styleci.yml` | `replace` | StyleCI config (PSR-12 + risky) |
+| `.ecrc` | `replace` | editor-config-checker exclusions |
+| `.prettierignore` | `replace` | Paths Prettier should skip |
+| `.prettierrc.json` | `replace` | Prettier formatting rules |
+| `.stylelintignore` | `replace` | Paths stylelint should skip |
+| `composer-require-checker.json` | `preserve` | Composer require-checker whitelist (project-specific) |
+| `.github/linters/actionlint.yml` | `replace` | actionlint config for Super-Linter |
+| `.github/linters/.codespellrc` | `replace` | codespell config |
+| `.github/linters/.gitleaks.toml` | `replace` | gitleaks config |
+| `.github/linters/.markdown-lint.yml` | `replace` | markdownlint config |
+| `ecs.php` | `preserve` | ECS wrapper for the project root |
+| `rector.php` | `preserve` | Rector wrapper for the project root |
+
+Mode semantics:
+
+- `replace`: lock-step with this package. Local edits trigger a warning and the file is skipped on update.
+ Use `vendor/bin/scaffold reapply --force` to re-sync.
+- `append`: provider content is appended to the existing file. Project lines are never blown away.
+- `preserve`: file is written once on first install and never overwritten.
+
+The scaffolded `ecs.php` / `rector.php` ship with `83` as the default PHP target; switch to `81`, `82`, or `84` to match
+your minimum PHP version. Mode `preserve` protects your edits across `composer update`.
+
+### Scaffold commands
+
+```bash
+vendor/bin/scaffold status # show which files are synced/modified/missing
+vendor/bin/scaffold diff # diff between local and provider version
+vendor/bin/scaffold reapply [] [--force] # re-apply provider content
+vendor/bin/scaffold eject # stop tracking a file (kept on disk)
+```
+
## Composer scripts
Follow the same convention used across PHP Forge repositories:
@@ -150,12 +212,11 @@ Follow the same convention used across PHP Forge repositories:
## Documentation
-- [Testing Guide](docs/testing.md)
-- [Development Guide](docs/development.md)
+- 📚 [Installation Guide](docs/installation.md)
## Package information
-[](https://www.php.net/releases/8.1/en.php)
+[](https://www.php.net/releases/8.3/en.php)
[](https://packagist.org/packages/php-forge/coding-standard)
[](https://packagist.org/packages/php-forge/coding-standard)
diff --git a/composer-require-checker.json b/composer-require-checker.json
new file mode 100644
index 0000000..66b091b
--- /dev/null
+++ b/composer-require-checker.json
@@ -0,0 +1,3 @@
+{
+ "symbol-whitelist": []
+}
diff --git a/composer.json b/composer.json
index 234d6a1..a330818 100644
--- a/composer.json
+++ b/composer.json
@@ -5,13 +5,14 @@
"keywords": [
"coding-standard",
"php",
+ "scaffold-provider",
"yii2"
],
"license": "BSD-3-Clause",
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
- "php": ">=8.1",
+ "php": ">=8.3",
"rector/rector": "^2.1",
"symplify/easy-coding-standard": "^13.0"
},
@@ -23,19 +24,38 @@
"extra": {
"branch-alias": {
"dev-main": "0.2.x-dev"
+ },
+ "scaffold": {
+ "copy": [
+ ".editorconfig",
+ ".gitattributes",
+ ".gitignore",
+ ".styleci.yml",
+ ".ecrc",
+ ".prettierignore",
+ ".prettierrc.json",
+ ".stylelintignore",
+ "composer-require-checker.json",
+ ".github/linters/actionlint.yml",
+ ".github/linters/.codespellrc",
+ ".github/linters/.gitleaks.toml",
+ ".github/linters/.markdown-lint.yml",
+ "ecs.php",
+ "rector.php"
+ ],
+ "modes": {
+ ".gitignore": "append",
+ "composer-require-checker.json": "preserve",
+ "ecs.php": "preserve",
+ "rector.php": "preserve"
+ }
}
},
"config": {
"sort-packages": true
},
"scripts": {
- "ecs": "./vendor/bin/ecs --fix",
- "sync-metadata": [
- "curl -fsSL -o .editorconfig https://raw.githubusercontent.com/yii2-extensions/template/main/.editorconfig",
- "curl -fsSL -o .gitattributes https://raw.githubusercontent.com/yii2-extensions/template/main/.gitattributes",
- "curl -fsSL -o .gitignore https://raw.githubusercontent.com/yii2-extensions/template/main/.gitignore",
- "curl -fsSL -o .styleci.yml https://raw.githubusercontent.com/yii2-extensions/template/main/.styleci.yml"
- ],
- "rector": "./vendor/bin/rector process"
+ "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/docs/configuration.md b/docs/configuration.md
deleted file mode 100644
index e1cdf21..0000000
--- a/docs/configuration.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Configuration reference
-
-## Overview
-
-## Basic configuration
-
-## Next steps
-
-- 💡 [Usage Examples](examples.md)
-- 🧪 [Testing Guide](testing.md)
diff --git a/docs/development.md b/docs/development.md
deleted file mode 100644
index fd10316..0000000
--- a/docs/development.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Development
-
-This document describes development workflows and maintenance tasks for the project.
-
-## Sync Metadata
-
-To keep configuration files synchronized with the latest template updates, use the `sync-metadata` command. This command
-downloads the latest configuration files from the template repository.
-
-```bash
-composer run sync-metadata
-```
-
-### Updated Files
-
-This command updates the following configuration files:
-
-| File | Purpose |
-| ---------------- | -------------------------------------------- |
-| `.editorconfig` | Editor settings and code style configuration |
-| `.gitattributes` | Git attributes and file handling rules |
-| `.gitignore` | Git ignore patterns and exclusions |
-
-## Shared configuration layout
-
-This package exposes shared configuration files under `config/`.
-Consumer repositories should create wrapper config files at their repository root
-and import these shared configs.
-
-### When to Run
-
-Run this command in the following scenarios:
-
-- **Periodic Updates** - Monthly or quarterly to benefit from template improvements.
-- **After Template Updates** - When the template repository has new configuration improvements.
-- **Before Major Releases** - Ensure your project uses the latest best practices.
-- **When Issues Occur** - If configuration files become outdated or incompatible.
-
-### Important Notes
-
-- This command overwrites existing configuration files with the latest versions from the template.
-- Ensure you have committed any custom configuration changes before running this command.
-- Review the updated files after syncing to ensure they work with your specific project needs.
-- Some projects may require customizations after syncing configuration files.
diff --git a/docs/examples.md b/docs/examples.md
deleted file mode 100644
index 6e994d5..0000000
--- a/docs/examples.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Usage examples
-
-## Next steps
-
-- 📚 [Installation Guide](installation.md)
-- ⚙️ [Configuration Guide](configuration.md)
-- 🧪 [Testing Guide](testing.md)
diff --git a/docs/installation.md b/docs/installation.md
index 0e56654..4f32a9b 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -2,9 +2,8 @@
## System requirements
-- [`PHP`](https://www.php.net/downloads) 8.1 or higher.
+- [`PHP`](https://www.php.net/downloads) 8.3 or higher.
- [`Composer`](https://getcomposer.org/download/) for dependency management.
-- [`Yii2`](https://github.com/yiisoft/yii2) 2.0.53+ or 22.x.
## Installation
@@ -13,7 +12,7 @@
Install the extension.
```bash
-composer require github_username/github_repository-name
+composer require php-forge/coding-standard:^0.2 --dev
```
### Method 2: Manual installation
@@ -22,8 +21,8 @@ Add to your `composer.json`.
```json
{
- "require": {
- "github_username/github_repository-name": "^1.0"
+ "require-dev": {
+ "php-forge/coding-standard": "^0.2"
}
}
```
@@ -36,8 +35,4 @@ composer update
## Next steps
-Once the installation is complete.
-
-- ⚙️ [Configuration Reference](configuration.md)
-- 💡 [Usage Examples](examples.md)
-- 🧪 [Testing Guide](testing.md)
+- 📖 [Readme](../README.md)
diff --git a/docs/svgs/features-mobile.svg b/docs/svgs/features-mobile.svg
index 275ea03..26db843 100644
--- a/docs/svgs/features-mobile.svg
+++ b/docs/svgs/features-mobile.svg
@@ -1,67 +1,38 @@
-
-
diff --git a/docs/svgs/features.svg b/docs/svgs/features.svg
index ad2ff55..2a0aa70 100644
--- a/docs/svgs/features.svg
+++ b/docs/svgs/features.svg
@@ -1,64 +1,40 @@
-
diff --git a/docs/testing.md b/docs/testing.md
deleted file mode 100644
index 9db2f98..0000000
--- a/docs/testing.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Testing
-
-This package provides a consistent set of [Composer](https://getcomposer.org/) scripts for local validation.
-
-Tool references:
-
-- [Composer Require Checker](https://github.com/maglnet/ComposerRequireChecker) for dependency definition checks.
-- [Easy Coding Standard (ECS)](https://github.com/easy-coding-standard/easy-coding-standard) for coding standards.
-- [Infection](https://infection.github.io/) for mutation testing.
-- [PHPStan](https://phpstan.org/) for static analysis.
-- [PHPUnit](https://phpunit.de/) for unit tests.
-
-## Coding standards (ECS)
-
-Run Easy Coding Standard (ECS) and apply fixes.
-
-```bash
-composer run ecs
-```
-
-### Shared configuration
-
-This repository ships shared configuration files under `config/` for reuse.
-Consumer repositories should define their own wrapper `ecs.php` and set project paths there.
-
-## Dependency definition check
-
-Verify that runtime dependencies are correctly declared in `composer.json`.
-
-```bash
-composer run check-dependencies
-```
-
-## Mutation testing (Infection)
-
-Run mutation testing.
-
-```bash
-composer run mutation
-```
-
-Run mutation testing with static analysis enabled.
-
-```bash
-composer run mutation-static
-```
-
-## Static analysis (PHPStan)
-
-Run static analysis.
-
-```bash
-composer run static
-```
-
-## Unit tests (PHPUnit)
-
-Run the full test suite.
-
-```bash
-composer run tests
-```
-
-## Passing extra arguments
-
-Composer scripts support forwarding additional arguments using `--`.
-
-Example: run a specific PHPUnit test or filter by name.
-
-```bash
-composer run tests -- --filter SvgTest
-```
-
-Example: run PHPStan with a different memory limit:
-
-```bash
-composer run static -- --memory-limit=512M
-```
diff --git a/ecs.php b/ecs.php
index f6c705f..e5046fe 100644
--- a/ecs.php
+++ b/ecs.php
@@ -2,15 +2,12 @@
declare(strict_types=1);
-/**
- * Prefer importing vendor/php-forge/coding-standard/config/ecs.php in consumer repositories.
- *
- * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $ecsConfigBuilder
- */
-$ecsConfigBuilder = require __DIR__ . '/config/ecs.php';
+/** @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder */
+$builder = require __DIR__ . '/vendor/php-forge/coding-standard/src/ecs-83.php';
-return $ecsConfigBuilder->withPaths(
+return $builder->withPaths(
[
- __DIR__ . '/config',
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
],
);
diff --git a/rector.php b/rector.php
index 70de101..e1d5c7e 100644
--- a/rector.php
+++ b/rector.php
@@ -4,15 +4,13 @@
use Rector\Config\RectorConfig;
-/**
- * Prefer importing vendor/php-forge/coding-standard/config/rector.php in consumer repositories.
- */
return static function (RectorConfig $rectorConfig): void {
- $rectorConfig->import(__DIR__ . '/config/rector.php');
+ $rectorConfig->import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-83.php');
$rectorConfig->paths(
[
- __DIR__ . '/config',
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
],
);
};
diff --git a/src/Example.php b/src/Example.php
deleted file mode 100644
index 7c0d196..0000000
--- a/src/Example.php
+++ /dev/null
@@ -1,13 +0,0 @@
-withPaths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * ```
+ *
+ * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder
+ */
+$builder = require __DIR__ . '/ecs.php';
+
+return $builder->withPhpCsFixerSets(php81Migration: true);
diff --git a/src/ecs-82.php b/src/ecs-82.php
new file mode 100644
index 0000000..a26dc91
--- /dev/null
+++ b/src/ecs-82.php
@@ -0,0 +1,25 @@
+withPaths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * ```
+ *
+ * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder
+ */
+$builder = require __DIR__ . '/ecs.php';
+
+return $builder->withPhpCsFixerSets(php82Migration: true);
diff --git a/src/ecs-83.php b/src/ecs-83.php
new file mode 100644
index 0000000..5ce4827
--- /dev/null
+++ b/src/ecs-83.php
@@ -0,0 +1,25 @@
+withPaths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * ```
+ *
+ * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder
+ */
+$builder = require __DIR__ . '/ecs.php';
+
+return $builder->withPhpCsFixerSets(php83Migration: true);
diff --git a/src/ecs-84.php b/src/ecs-84.php
new file mode 100644
index 0000000..63d08be
--- /dev/null
+++ b/src/ecs-84.php
@@ -0,0 +1,25 @@
+withPaths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * ```
+ *
+ * @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $builder
+ */
+$builder = require __DIR__ . '/ecs.php';
+
+return $builder->withPhpCsFixerSets(php84Migration: true);
diff --git a/config/ecs.php b/src/ecs.php
similarity index 72%
rename from config/ecs.php
rename to src/ecs.php
index cb68994..bdfd7d9 100644
--- a/config/ecs.php
+++ b/src/ecs.php
@@ -7,15 +7,21 @@
use PhpCsFixer\Fixer\LanguageConstruct\NullableTypeDeclarationFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesOrderFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer;
+use PhpCsFixer\Fixer\Strict\{DeclareStrictTypesFixer, StrictComparisonFixer, StrictParamFixer};
use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;
/**
- * Shared ECS configuration.
+ * Shared base ECS configuration.
*
- * This file intentionally contains no project-specific paths.
- * Consumer repositories should provide their own wrapper ecs.php
- * and set paths there.
+ * 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(
@@ -85,12 +91,14 @@
comments: true,
docblocks: true,
namespaces: true,
- strict: true,
)
->withRules(
[
+ DeclareStrictTypesFixer::class,
NoUnusedImportsFixer::class,
OrderedTraitsFixer::class,
SingleQuoteFixer::class,
+ StrictComparisonFixer::class,
+ StrictParamFixer::class,
],
);
diff --git a/src/rector-81.php b/src/rector-81.php
new file mode 100644
index 0000000..efdaf20
--- /dev/null
+++ b/src/rector-81.php
@@ -0,0 +1,34 @@
+import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-81.php');
+ * $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * };
+ * ```
+ */
+return static function (RectorConfig $rectorConfig): void {
+ (require __DIR__ . '/rector.php')($rectorConfig);
+
+ $rectorConfig->sets(
+ [
+ LevelSetList::UP_TO_PHP_81,
+ ],
+ );
+};
diff --git a/src/rector-82.php b/src/rector-82.php
new file mode 100644
index 0000000..432657e
--- /dev/null
+++ b/src/rector-82.php
@@ -0,0 +1,34 @@
+import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-81.php');
+ * $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * };
+ * ```
+ */
+return static function (RectorConfig $rectorConfig): void {
+ (require __DIR__ . '/rector.php')($rectorConfig);
+
+ $rectorConfig->sets(
+ [
+ LevelSetList::UP_TO_PHP_82,
+ ],
+ );
+};
diff --git a/src/rector-83.php b/src/rector-83.php
new file mode 100644
index 0000000..8102dab
--- /dev/null
+++ b/src/rector-83.php
@@ -0,0 +1,34 @@
+import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-83.php');
+ * $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * };
+ * ```
+ */
+return static function (RectorConfig $rectorConfig): void {
+ (require __DIR__ . '/rector.php')($rectorConfig);
+
+ $rectorConfig->sets(
+ [
+ LevelSetList::UP_TO_PHP_83,
+ ],
+ );
+};
diff --git a/src/rector-84.php b/src/rector-84.php
new file mode 100644
index 0000000..d5636fd
--- /dev/null
+++ b/src/rector-84.php
@@ -0,0 +1,34 @@
+import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-84.php');
+ * $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']);
+ * };
+ * ```
+ */
+return static function (RectorConfig $rectorConfig): void {
+ (require __DIR__ . '/rector.php')($rectorConfig);
+
+ $rectorConfig->sets(
+ [
+ LevelSetList::UP_TO_PHP_84,
+ ],
+ );
+};
diff --git a/config/rector.php b/src/rector.php
similarity index 60%
rename from config/rector.php
rename to src/rector.php
index ccc509b..99aa40a 100644
--- a/config/rector.php
+++ b/src/rector.php
@@ -4,36 +4,31 @@
use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector;
use Rector\Config\RectorConfig;
-use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector;
/**
- * Shared Rector configuration.
+ * Shared base Rector configuration.
*
- * This file intentionally contains no project-specific paths.
- * Consumer repositories should provide their own wrapper rector.php
- * and set paths there.
+ * This file intentionally contains no project-specific paths and no PHP version-level set. Consumer repositories should
+ * import either this file (no version target) or one of the version-pinned wrappers (`rector-81.php`, `rector-82.php`,
+ * `rector-83.php`, `rector-84.php`) and set their own paths.
+ *
+ * The version-pinned wrappers add the matching `SetList::PHP_XX` and `LevelSetList::UP_TO_PHP_XX` on top of this base.
*/
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->parallel();
-
$rectorConfig->importNames();
-
$rectorConfig->sets(
[
- SetList::PHP_81,
- LevelSetList::UP_TO_PHP_81,
SetList::TYPE_DECLARATION,
],
);
-
$rectorConfig->skip(
[
TypedPropertyFromCreateMockAssignRector::class,
],
);
-
$rectorConfig->rules(
[
SimplifyEmptyArrayCheckRector::class,
diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php
deleted file mode 100644
index b2ffae0..0000000
--- a/tests/ExampleTest.php
+++ /dev/null
@@ -1,27 +0,0 @@
-getExample(),
- "Method should return 'false' by default.",
- );
- self::assertSame(
- true,
- $example->getExample(true),
- "Method should return 'true' when legacy parameter is 'true'.",
- );
- }
-}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
deleted file mode 100644
index e69de29..0000000