michaelmcandrew/civicrm-coding-standards

Coding standards for CiviCRM

Installs: 16

Dependents: 0

Suggesters: 0

Security: 0

Type:phpcodesniffer-standard

1.1.1 2022-06-27 14:49 UTC

README

This package defines CiviCRM coding standards.

The CiviCRM coding standards are based on Drupal's coding standards but with a few modifications and relaxations. See https://docs.civicrm.org/dev/en/latest/standards/php/ for more details.

Historically, CiviCRM's coding standards have been maintained in the 8.x-2.x-civi branch of a fork of Drupal's coding standard in this repository: https://github.com/civicrm/coder.

This just about works but has some drawbacks, one of which is that we are hijacking the Drupal coding standards 'namespace', i.e. you typically have to run something like phpcs --standard==Drupal CRM/Core/Action.php.

This package defines its own standard CiviCRM, so you can run phpcs --standard==CiviCRM CRM/Core/Action.php.

Installation

You can choose to install CiviCRM coding standards globally (e.g. with composer global require) or you can install it locally as part of a project.

Global installation

CiviCRM's coding standards can be installed globally with composer global require michaelmcandrew/civicrm-coding-standards.

Now - presuming that your composer global bin directory (e.g. $HOME/.config/composer/vendor/bin) is in your $PATH - you should now be able to run phpcs -i and see CiviCRM listed as an available standard.

You can quickly check that the standard is working correctly by running phpcs --standard=CiviCRM CRM/Core/Action.php on an up to date copy of CiviCRM. It should output nothing, indicating no code standard violations.

Local installation

CiviCRM's coding standards can be installed locally using a similar approach.

From your project directory, run composer require michaelmcandrew/civicrm-coding-standards.

You should now be able to run vendor/bin/phpcs -i and see CiviCRM listed as an available standard. Running vendor/bin/phpcs --standard=CiviCRM example.php will run the coding standard on that file.

Development installation

If you want to test develop the standard, you can take advantage of composer's 'path repositories' feature. Here is an example of a global composer config that does this:

{
  "$schema": "https://getcomposer.org/schema.json",
  "require": {
    "michaelmcandrew/civicrm-coding-standards": "^1.1.1"
  },
  "minimum-stability": "dev",
  "repositories": [
    {
      "type": "path",
      "url": "/home/michael/src/civicrm-coding-standards"
    }
  ]
}

Usage

phpcs --standard=CiviCRM example.php will check example.php against the CiviCRM coding standards.

You can also create a configuration file, e.g. .phpcs.xml to tell phpcs what standard you would like to use. phpcs checks the current directory and all parent directories for a configuration file to use for linting.

Here is an example of a file that applies the CiviCRM coding standards:

<?xml version="1.0"?>
<ruleset>
  <rule ref="CiviCRM" />
</ruleset>

Testing

The bin/analyse.php script is take json output from phpcs and generates a list of sniffs that failed sorted by the number of times that they failed. This might be useful in working out what we need to do to get the number of sniffs failing to 0.

Here's an example of how to use it (change paths as appropriate).

  1. From the root of a civicrm codebase phpcs --report=json --standard=CiviCRM . > ~/report.json
  2. cat ~/report.json | php ~/src/civicrm-coding-standards/bin/analyse.php

For example.

Array
(
    [Drupal.WhiteSpace.ScopeIndent.IncorrectExact] => 18213
    [Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction] => 2837
    [Drupal.Classes.ClassFileName.NoMatch] => 2279
    [Drupal.Commenting.VariableComment.Missing] => 1749
    [Generic.PHP.UpperCaseConstant.Found] => 1734
    [Drupal.Arrays.DisallowLongArraySyntax.Found] => 1140
    [SlevomatCodingStandard.PHP.ShortList.LongListUsed] => 613
    [Drupal.Commenting.ClassComment.Short] => 501
    [Drupal.Commenting.Deprecated.IncorrectTextLayout] => 455
    [Drupal.Commenting.Deprecated.DeprecatedMissingSeeTag] => 441
    [Drupal.Commenting.TodoComment.TodoFormat] => 427

    ...more failures here...

    [Squiz.WhiteSpace.SuperfluousWhitespace.StartFile] => 1
    [Squiz.PHP.NonExecutableCode.ReturnNotRequired] => 1
    [Generic.PHP.DeprecatedFunctions.Deprecated] => 1
    [PEAR.Files.IncludingFile.BracketsNotRequired] => 1
    [Squiz.Arrays.ArrayDeclaration.SpaceInEmptyArray] => 1
)