Vérifier la syntaxe PHP à chaque commit
Afin d’automatiser et d’améliorer la qualité du code, il est possible de lancer certaines tâches lors de chaque commit avec Git. Des outils comme GrumPHP permettent de faire cela mais il peut arriver qu’il soit incompatible avec votre projet PHP (et puis c’est toujours intéressant de savoir le faire à la main).
Les hooks
Les hooks sont des petits scripts qui se lancent lors des différentes actions Git. Il en existe plusieurs et pour les connaitre il suffit de se rendre dans un dépot Git et de faire:
ls .git/hooks/
applypatch-msg.sample pre-applypatch.sample pre-commit.sample pre-push.sample update.sample
commit-msg.sample post-update.sample prepare-commit-msg.sample pre-rebase.sample
Les fichiers .sample sont des examples proposés par Git. Dans notre cas, on va partir de zéro en créant un script vide
touch .git/hooks/pre-commit
Le script
Nous allons donc commencer par afficher les fichiers contenu dans le commit. Pour cela on s’appuie sur la commande git diff --cached --name-only
qui affiche les uniquement le nom des fichiers modifié. On rajoute un petit grep
par dessus pour filtrer uniquement les fichiers PHP et on boucle dessus.
Voici le résultat:
#!/bin/bash
# .git/hooks/pre-commit
# loop on all commited PHP files
for file in $(git diff --cached --name-only | grep -E '.php$') ; do
echo "[x] $file"
done
Il faut ensuite faire le tri dans ses fichiers car Git nous remonte aussi ceux supprimés, il faut donc rajouter une condition:
#!/bin/bash
# .git/hooks/pre-commit
# loop on all commited PHP files
for file in $(git diff --cached --name-only | grep -E '.php$') ; do
# first we verify that file exists
if [ -f $file ]; then
echo "[x] $file"
fi
done
Et pour terminer on vérifie la syntaxe à l’aide de la commande php -l "$file"
et si on trouve une erreur, on stoppe l’execution avec un signal d’erreur à l’aide de la fonction exit 1
.
#!/bin/bash
# .git/hooks/pre-commit
# loop on all commited PHP files
for file in $(git diff --cached --name-only | grep -E '.php$') ; do
# first we verify that file exists
if [ -f $file ]; then
# check syntax & catch errors
if ($( php -l "$file" 1> /dev/null )); then
echo "[x] $file"
else
# file contains syntax error, so we'll stop programm & cancel commit
echo "[ ] $file"
exit 1
fi
fi
done
Le test
Notre script étant prêt, il nous reste plus qu’à tester. On ajoute un fichier PHP valide et on vérifie qu’il est accepté
echo '<?php echo "test";' > valid.php
git add valid.php
git commit -m "Add valid file"
Maintenant on teste avec un fichier PHP non valide
git reset --hard HEAD^ # on annule le précedent commit
echo '<?php echo "test;' > invalid.php
git add invalid.php
git commit -m "Add invalid file"
Le script coupe l’ajout du commit!
Axes d’améliorations
Nous avons vu à travers un exemple simple qu’il est possible d’automatiser les tâches les pluscourant. On pourrait aller plus loin et:
- Vérifier la syntaxe des fichier Ruby avec la commande
ruby -c file
- Formatter automatiquement les fichier commité
- Lancer les test unitaires