Skip to content

A set of Wieni best practices, coding standards and tools to enforce them.

License

Notifications You must be signed in to change notification settings

wieni/wmcodestyle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wmcodestyle

Latest Stable Version Total Downloads License

A set of Wieni best practices, coding standards and tools to enforce them.

Why?

  • A central location to keep track of our written coding standards and best practices
  • Make configuration for tools to enforce our codestyle available in all of our repositories, without having to duplicate and sync them manually

Table of Contents

  1. Coding standards
  2. Tooling
  3. Changelog
  4. Security
  5. License
  6. Acknowledgments

Coding standards

Tooling

Installation

This package requires PHP 7.1 or higher and can be installed using Composer:

 composer require --dev wieni/wmcodestyle

Sync config files with your project

This package provides a command to sync any file from this repository to your project. It is recommended to add it to the scripts section of composer.json so it is automatically executed at the appropriate time.

 {
   "name": "foo/bar",
   "require": {
     "php": "^8.0",
   },
   "require-dev": {
     "wieni/wmcodestyle": "^1.0"
+  },
+  "scripts": {
+    "post-update-cmd": [
+      "wmcodestyle sync .editorconfig --quiet"
+    ]
   }
 }

This package provides a configuration factory and multiple rule sets for friendsofphp/php-cs-fixer.

Configuration

Pick one of the rule sets:

Create a configuration file .php_cs.php in the root of your project:

<?php

use Wieni\wmcodestyle\PhpCsFixer\Config\Factory;
use Wieni\wmcodestyle\PhpCsFixer\Config\RuleSet\Php73;

$config = Factory::fromRuleSet(new Php73);

$config->getFinder()
    ->ignoreVCSIgnored(true)
    ->in(__DIR__)
    ->name('/\.(php|module|inc|install|test|profile|theme)$/')
    ->notPath('/(public|web)\/(index|update)\.php/');

$config->setCacheFile(__DIR__ . '/.cache/php_cs.cache');

return $config;

By default, risky rules are not used. To use them, pass --allow-risky=yes to php-cs-fixer or set the WMCODESTYLE_RISKY=1 environment variable.

Git

All configuration examples use the caching feature, and if you want to use it as well, you should add the cache folder to .gitignore:

# Ignore files generated by wieni/wmcodestyle
.cache

Configuration with override rules

💡 Optionally override rules from a rule set by passing in an array of rules to be merged in:

<?php

use Wieni\wmcodestyle\PhpCsFixer\Config\Factory;
use Wieni\wmcodestyle\PhpCsFixer\Config\RuleSet\Php73;

-$config = Factory::fromRuleSet(new Php73);
+$config = Factory::fromRuleSet(new Php73, [
+    'mb_str_functions' => false,
+    'strict_comparison' => false,
+]);

$config->getFinder()
    ->ignoreVCSIgnored(true)
    ->in(__DIR__)
    ->name('/\.(php|module|inc|install|test|profile|theme)$/')
    ->notPath('/(public|web)\/(index|update)\.php/');

$config->setCacheFile(__DIR__ . '/.php_cs.cache');

return $config;

Instant upgrade and refactoring of your PHP code

This package provides multiple rule sets for rector/rector. These rule sets are largely identical to the default rule sets, with the exception of a couple individual rules we don't like/need. Instead of rector/rector, rector/rector-prefixed is added as dependency to make it easier to include this package in your Composer project.

Rule sets

Pick one of the rule sets:

Example configuration

<?php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\TwigSetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Wieni\wmcodestyle\Rector\SetList as WieniSetList;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();

    $parameters->set(Option::AUTO_IMPORT_NAMES, true);
    $parameters->set(Option::IMPORT_SHORT_CLASSES, false);

    $parameters->set(Option::PATHS, [
        __DIR__ . '/public/modules/custom',
    ]);

    $parameters->set(Option::AUTOLOAD_PATHS, [
        __DIR__ . '/public/core',
        __DIR__ . '/public/core/modules',
        __DIR__ . '/public/modules',
        __DIR__ . '/public/profiles',
        __DIR__ . '/public/sites',
        __DIR__ . '/public/themes',
    ]);

    $parameters->set(Option::SETS, [
        SetList::DEAD_CODE,
        SetList::PHP_73,
        SetList::PHP_74,
        TwigSetList::TWIG_UNDERSCORE_TO_NAMESPACE,
    ]);

    $containerConfigurator->import(WieniSetList::CODE_QUALITY);
    $containerConfigurator->import(WieniSetList::CODING_STYLE);
    $containerConfigurator->import(WieniSetList::DEPENDENCY_INJECTION);
    $containerConfigurator->import(WieniSetList::EARLY_RETURN);
    $containerConfigurator->import(WieniSetList::TYPE_DECLARATION);
};

Add Symfony container XML

To work with some Symfony rules, you now need to link your container XML file:

<?php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Wieni\wmcodestyle\Rector\SetList as WieniSetList;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();
    $parameters->set(Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER, __DIR__ . '/.cache/drupal_container.xml');
};
// phpstan-for-rector.neon
parameters:
    symfony:
        container_xml_path: %currentWorkingDirectory%/.cache/drupal_container.xml

includes:
	- vendor/wieni/wmcodestyle/phpstan/for-rector.neon

Dumping the container is not possible out-of-the-box when using Drupal, but our Container Dumper module makes this possible.

PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.

Drupal

For better integration with Drupal, consider adding mglaman/phpstan-drupal and phpstan/phpstan-symfony to your project. These extensions are required when using the drupal-module or drupal-site configs.

You can use the Container Dumper module to dump the Symfony container to an XML file. The Symfony extension can then use this file to get better insights into your project. Add the following to your PHPStan config:

parameters:
    symfony:
        container_xml_path: %currentWorkingDirectory%/.cache/drupal_container.xml

Symfony

For better integration with Symfony, consider adding phpstan/phpstan-symfony and phpstan/phpstan-doctrine to your project.

Provides a composer plugin for normalizing composer.json.

We highly recommend this Composer plugin to make sure your composer.json is formatted consistently.

Running code style fixers

Makefile

If you like Makefiles, create a Makefile with a coding-standards target:

+.PHONY: coding-standards
+coding-standards: vendor
+    mkdir -p .build/php-cs-fixer
+    vendor/bin/php-cs-fixer fix --config=.php_cs --diff --verbose
+    composer normalize"
+    vendor/bin/rector process"
+    vendor/bin/php-cs-fixer fix --config=.php_cs.php
+    vendor/bin/phpstan analyse

 vendor: composer.json composer.lock
     composer validate
     composer install

Run

$ make coding-standards

to automatically fix coding standard violations.

Composer script

If you like composer scripts, add a coding-standards script to composer.json:

 {
   "name": "foo/bar",
   "require": {
     "php": "^8.0",
   },
   "require-dev": {
     "wieni/wmcodestyle": "^1.0"
+  },
+  "scripts": {
+    "coding-standards": [
+      "@composer normalize",
+      "rector process",
+      "php-cs-fixer fix --config=.php_cs.php",
+      "phpstan analyse"
+    ]
   }
 }

Run

$ composer coding-standards

Changelog

All notable changes to this project will be documented in the CHANGELOG file.

Security

If you discover any security-related issues, please email security@wieni.be instead of using the issue tracker.

License

Distributed under the MIT License. See the LICENSE file for more information.

Acknowledgments