Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .ecrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Exclude": [
"phpstan-baseline\\.neon$",
"^tests/runtime/",
"\\.min\\.css$",
"\\.min\\.js$",
"^vendor/",
"^runtime/"
]
}
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ trim_trailing_whitespace = true
indent_size = 2

[*.md]
indent_size = 2
trim_trailing_whitespace = false

[*.php]
Expand Down
19 changes: 6 additions & 13 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions .github/linters/.codespellrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[codespell]
skip = */tests/*,tests/**,*/composer.lock,*/composer.json
7 changes: 7 additions & 0 deletions .github/linters/.gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title = "gitleaks config"

[[allowlists]]
description = "Allow test fixture data with dummy credentials"
paths = [
'''tests/support/data/.*\.php''',
]
5 changes: 5 additions & 0 deletions .github/linters/.markdown-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
MD007:
indent: 2
MD013: false
MD033: false
2 changes: 2 additions & 0 deletions .github/workflows/ecs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ package-lock.json
# phpstorm project (if present)
.idea

# phpactor (if present)
.phpactor.*

# phpunit (if present)
.phpunit.cache
.phpunit.result.cache
Expand Down
18 changes: 18 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -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
}
}
]
}
1 change: 1 addition & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/*.min.css
14 changes: 10 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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/`.

Comment thread
terabytesoftw marked this conversation as resolved.
## 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.
149 changes: 105 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- markdownlint-disable MD041 -->
<p align="center">
<a href="https://github.com/php-forge/coding-standard" target="_blank">
<img src="https://avatars.githubusercontent.com/u/103309199?s%25253D400%252526u%25253Dca3561c692f53ed7eb290d3bb226a2828741606f%252526v%25253D4" height="150px" alt="PHP Forge">
<img src="https://avatars.githubusercontent.com/u/103309199?s%25253D400%252526u%25253Dca3561c692f53ed7eb290d3bb226a2828741606f%252526v%25253D4" width="50%" alt="PHP Forge">
</a>
<h1 align="center">Coding standard</h1>
<br>
Expand All @@ -23,50 +23,42 @@
## 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
<?php

declare(strict_types=1);

/** @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $ecsConfigBuilder */
$ecsConfigBuilder = require __DIR__ . '/vendor/php-forge/coding-standard/config/ecs.php';

return $ecsConfigBuilder->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
<?php

declare(strict_types=1);

/** @var \Symplify\EasyCodingStandard\Configuration\ECSConfigBuilder $ecsConfigBuilder */
$ecsConfigBuilder = require __DIR__ . '/vendor/php-forge/coding-standard/config/ecs.php';
$ecsConfigBuilder = require __DIR__ . '/vendor/php-forge/coding-standard/src/ecs-83.php';

return $ecsConfigBuilder
->withPaths(
Expand All @@ -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
<?php
Expand All @@ -94,7 +87,7 @@ declare(strict_types=1);
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/vendor/php-forge/coding-standard/config/rector.php');
$rectorConfig->import(__DIR__ . '/vendor/php-forge/coding-standard/src/rector-83.php');

$rectorConfig->paths(
[
Expand All @@ -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
<?php
Expand All @@ -123,7 +115,7 @@ declare(strict_types=1);
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->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(
Expand All @@ -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 <file> --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 <file> # diff between local and provider version
vendor/bin/scaffold reapply [<file>] [--force] # re-apply provider content
vendor/bin/scaffold eject <file> # stop tracking a file (kept on disk)
```

## Composer scripts

Follow the same convention used across PHP Forge repositories:
Expand All @@ -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

[![PHP](https://img.shields.io/badge/%3E%3D8.1-777BB4.svg?style=for-the-badge&logo=php&logoColor=white)](https://www.php.net/releases/8.1/en.php)
[![PHP](https://img.shields.io/badge/%3E%3D8.3-777BB4.svg?style=for-the-badge&logo=php&logoColor=white)](https://www.php.net/releases/8.3/en.php)
[![Latest Stable Version](https://img.shields.io/packagist/v/php-forge/coding-standard.svg?style=for-the-badge&logo=packagist&logoColor=white&label=Stable)](https://packagist.org/packages/php-forge/coding-standard)
[![Total Downloads](https://img.shields.io/packagist/dt/php-forge/coding-standard.svg?style=for-the-badge&logo=composer&logoColor=white&label=Downloads)](https://packagist.org/packages/php-forge/coding-standard)

Expand Down
3 changes: 3 additions & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"symbol-whitelist": []
}
Loading
Loading