Comment ne plus penser à PHP CS Fixer

Par @jbnahan69

Cette procédure est valable pour l'utilisation d'une seule version de PHP CS Fixer sur votre ordinateur.

PHP CS Fixer c'est quoi ? A quoi sert PHP CS Fixer ?

PHP CS Fixer est un outil permettant de vérifier et corriger le formatage du code PHP selon le code style défini dans la configuration du projet (fichier .php_cs.dist ou .php_cs pour la version 2 et .php-cs-fixer.dist.php ou .php-cs-fixer.php pour la version 3).

Le style code est une convention qui définit comment doit être écrit le code. Par exemple l'emplacement des accolades des structures de contrôle, des classes, des fonctions, les espaces autour d'un signe égal, etc.

Cela permet de faciliter la lecture du code pour tout le monde.

Le PHP-FIG a défini plusieurs conventions dont la dernière en date est la PSR-12. Il existe également des conventions plus spécifiques comme le Coding Standards de Symfony.

Pourquoi ne plus y penser ?

Le style de code est une nécessité, mais très franchement c'est frustrant quand l'intégration continue échoue à cause du style code.

Tout comme voir des messages de commit tels que fix style code, fix cs ou cs ou bien d'autre encore.

Il existe une solution pour ne plus y penser et l'appliquer tout de même, le hook (crochet) GIT pre-commit.

Un hook (crochet en français) est un point d'extension d'une application permettant à l'utilisateur d'exécuter des actions qu'il a lui-même définies. En général, ce sont des scripts Shell.

Pré requis

Cette procédure a été écrite pour les systèmes GNU/Linux. La compatibilité pour les Mac est quasi assurée. Pour Windows, il est nécessaire d'adapter la procédure au système.

PHP 7 et PHP CS Fixer doivent être installé sur le poste qui exécute les commandes GIT. Si PHP CS Fixer n'est pas installé, suivre la procédure d'installation globale manuelle.

Pour ce blog post, PHP CS Fixer est installé à cet emplacement /usr/local/bin/php-cs-fixer. Pour connaitre l'emplacement du binaire exécuter la commande type php-cs-fixer.

Le projet sur lequel vous choisissez de définir ce hook contient déjà une configuration pour PHP CS Fixer (fichier .php_cs.dist ou .php_cs).

Ajout d'un hook sur un dépôt

Pour ne pas perturber les projets qui ne dispose pas de configuration ou qui n'ont pas de fichier PHP, le hook vérifie la présence d'un fichier de configuration et n'appliquera les modifications que sur les fichiers PHP inclus dans le commit.

Pour l'ajouter, se placer dans le dossier de votre projet puis ouvrir le fichier .git/hooks/pre-commit (il peut déjà exister ou devra être ajouté).

Puis coller le contenu du script suivant :

#!/bin/sh

ROOT=$(dirname "$0")
ROOT=$(dirname "$ROOT")
ROOT=$(dirname "$ROOT")

echo "php-cs-fixer pre commit hook start"

# Modifier le chemin de PHP CS Fixer ici si votre binaire n'est pas installé au même endroit :
PHP_CS_FIXER="/usr/local/bin/php-cs-fixer"

HAS_PHP_CS_FIXER=false

if [ -x  "$PHP_CS_FIXER" ]; then
    HAS_PHP_CS_FIXER=true
else
    echo "PHP CS Fixer not installed into $PHP_CS_FIXER"
fi

#PHP_CS_CONFIG=

for file in .php_cs.dist .php_cs .php-cs-fixer.dist.php .php-cs-fixer.php
do
    if [ -f "$ROOT/$file" ]; then
        echo PHP CS Fixer config file found in projet at $file
        PHP_CS_CONFIG=$file
    fi
done

if [ "x$PHP_CS_CONFIG" = "x" ]; then
    echo "No PHP CS Fixer config file found !"
    HAS_PHP_CS_FIXER=false
fi

if $HAS_PHP_CS_FIXER; then
    git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do
        $PHP_CS_FIXER fix --config=$ROOT/$PHP_CS_CONFIG --verbose "$line";
        git add "$line";
    done
else
    echo ""
    echo "Please install php-cs-fixer, see:"
    echo ""
    echo "  https://github.com/FriendsOfPHP/PHP-CS-Fixer#installation"
    echo ""
fi

echo "php-cs-fixer pre commit hook finish"

Il est nécessaire de s'assurer que ce fichier est exécutable grâce à cette commande : chmod u+x .git/hooks/pre-commit.

Exécuter la commande dans un terminal après s'être placé dans le dossier de votre projet.

Pour tester son efficacité, modifier le placement d'accolade dans un fichier PHP du projet puis ajouter un commit.

PHP CS Fixer est exécuté sur chaque fichier modifié pour corriger le style code avant le commit.

Ajout d'un hook pour tous les dépôts

Maintenant que notre hook fonctionne, nous pouvons l'ajouter au modèle de dépôt GIT. Ainsi tout nouveau dépôt disposera du hook.

La première étape consiste à définir un dossier de template pour les nouveaux dépôts GIT.

Exécuter la commande git config --global init.templatedir '~/.git-templates'

Le dossier n'existant pas, nous allons l'ajouter à notre dossier utilisateur avec cette commande mkdir -p ~/.git-templates/hooks

Toujours depuis le dossier du projet où le hook a été ajouté exécuter la commande suivante pour copier le hook cp .git/hooks/pre-commit ~/.git-templates/hooks/

Cette fois, nous allons nous assurer que tout le monde peut l'exécuter avec cette commande : chmod a+x ~/.git-templates/hooks/pre-commit.

Ajouter le hook sur un dépôt existant

Maintenant que le hook est dans le template de GIT, il est possible de l'ajouter à un projet existant en exécutant la commande : git init dans le dossier du projet.

Pour les dépôts ayant déjà un hook pre-commit, il ne sera pas modifié.

Besoin d'aide pour mettre en place cette solution ? Contactez-moi !

Il est nécessaire de s'assurer que ce fichier est exécutable grâce à cette commande : chmod u+x .git/hooks/pre-commit.

Exécuter la commande dans un terminal après s'être placé dans le dossier de votre projet.

Pour tester son efficacité, modifier le placement d'accolade dans un fichier PHP du projet puis ajouter un commit.

PHP CS Fixer est exécuté sur chaque fichier modifié pour corriger le style code avant le commit.

Allez plus loin en ajoutant un fichier de configuration GIT pour ignorer globalement certain fichier.

Author avatar
Jean-Baptiste Nahan

Consultant Expert Web, j'aide les entreprises ayant des difficultés avec leur projet Web (PHP, Symfony, Sylius).

@jbnahan69 | Macintoshplus | Linkedin | JB Dev Labs