Navigation

 

Artikel Kategorien

Your team set the rules for your common coding style but still the mess in your code is increasing and you need so called “formatting” commits once in a while?
You shouldn’t have this problem at all, forcing all developers to stick to the coding style is a crucial part for good code quality. The only way to ensure that the complete code and every new commit follows these rules is to only allow … code to be committed.

This post explains how to implement a automatic code check before every commit to a Git repository. It combines Git, composer and PHPCS to prevent malformed code to be committed. You have to do this only once. Every other team member will have this code check as well, after pulling your changes from the repository.

If you want to use that tutorial it is required that all team members use Git, composer and Linux/Mac machines.

Installation and Setup

First we need to install “PHP_CodeSniffer” that is responsible to search for possible coding style violations.

composer require "squizlabs/php_codesniffer"

Now we have to configure which coding style we want to use and which files should be checked. We can create a file called “phpcs.xml” in the directory of the project that contain these information. For symphony projects I use the following configuration:

<?xml version="1.0"?>
<ruleset name="Symfony2-coding-standards">
    <description>Apply Symfony coding standards. See http://symfony.com/doc/current/contributing/code/standards.html</description>

    <file>src/</file>
    <file>tests/</file>

    <rule ref="Symfony2" />
</ruleset>

The referred ruleset “Symfony2” is created by escapestudios and is publicly available on Packagist.

We can include this ruleset in our project with composer.

composer require escapestudios/symfony2-coding-standard

Now we have to configure phpcs to load the coding standard. We do it automatically on every composer install call so the developers don´t need to care about the configuration here. Just add the following line to your composer file.

{
...
"post-install-cmd": [
    ...
    "vendor/bin/phpcs --config-set installed_paths vendor/escapestudios/symfony2-coding-standard"
],
...
}

Our goal is to test for possible formatting issues during a commit and abort if there are violations to the rules. We can use git hooks to do so. First we create a php file that we can run to test the code under “dev/pre-commit.php” with the following content:

#!/usr/local/bin/php
<?php
const SEPERATOR = "-------------------------------------";

// Check if php is at least php 7.1
$current_version = phpversion();
if (version_compare($current_version, "7.1.0", "<")) { echo "This tool require php version >=7.1.0! You are using ${current_version}".PHP_EOL;
    exit(2);
}

// Get git commits
exec('git diff --name-status --cached --diff-filter=ACM', $files);
foreach ($files as $file) {
    $fileName = trim(substr($file, 1));

    if (pathinfo($fileName, PATHINFO_EXTENSION) == "php") {
        // Check for syntax errors
        $lint_output = [];
        $return = 0;
        exec(PHP_BINARY." -l " . escapeshellarg($fileName), $lint_output, $return);

        // Check for coding standard issues
        if ($return !== 0) {
            echo implode(PHP_EOL, $lint_output).PHP_EOL;
            exit(1);
        }

        // Check for dump function usage
        $lines = file($fileName);
        $output = [];
        foreach ($lines as $line_number => &$line) {
            if (strpos($line, 'du'.'mp(')) {
                $output = sprintf("%d %s".PHP_EOL, $line_number, trim($line));
            }
        }

        // print error if dump directives are found
        if (count($output) > 0) {
            printf("Dump found in file: %s".PHP_EOL, $fileName);
            print(SEPERATOR.PHP_EOL);
            print($output);
            print(SEPERATOR.PHP_EOL);
            exit(1);
        }
    }
}

$phpcs_output = [];
$phpcs_return = 0;
exec(__DIR__."/../vendor/bin/phpcs", $phpcs_output, $phpcs_return);

if ($phpcs_return !== 0) {
    echo implode(PHP_EOL, $phpcs_output);
    exit(1);
}

exit(0);

We don´t want that the developer need to install the script into his hooks manually so we add a line to the composer file that will ensure that the hook is installed after running “composer install”.

...
"post-install-cmd": [
...
   "if [ ! -d .git/hooks ]; then mkdir .git/hooks; fi",
   "if [ ! -f .git/hooks/pre-commit ]; then ln -s ../../dev/pre-commit.php .git/hooks/pre-commit;
],
...

We can now tell all developers to pull our changes from the repository and run “composer install”. They might be surprised while checking in new code from now on because commits are only accepted now if they stick to the coding guidelines.

Usage and automatic fixes

To manually check the code style without committing to git you can now run the following command to see all style violations:

phpcs

Pretty simple? But it get´s even better! Most of the style issues can be fixed autmaticly by running a tool called “phpcbf” that was installed with phpcs by running it like this:

phpcbf

 

Zuletzt aktualisiert am 17.09.2017