Collaborer à plusieurs, c'est aussi du code bien formatté

De nombreux logiciels sont développés à plusieurs. Un des soucis majeurs, ce sont les divergences d’opinion sur le formattage du code ; c’est pourquoi, une des pratiques issue de l’Extreme Programming se nomme convention de code.

Malgré tout, même si une équipe s’est mise d’accord sur ses standards de code, selon les outils utilisés, certaines règles sont difficiles soit à suivre, soit à mettre en oeuvre de manière systématique. Ainsi chez Deepki, chacun utilise un IDE différent dans son travail quotidien (PyCharm, VS Code, emacs), chacun se règle différement, et rien n’a moins de valeur dans une séance de relecture du code de dire “ah bah ici tu ne respectes pas le standard”.

Des outils, habituellement nommés linter existent pour cela. Comme nous avons déjà une base de code conséquente, avec un grand nombre de branches en parallèle, l’option “bombe nucléaire” (on passe le linter sur toute la base de code) n’est pas possible : cela créerait trop de conflits sans valeur avec toutes les branches en cours ! Le plus pragmatique, c’est de le faire au fil de l’eau et de manière automatique. (Cela n’empêche pas chacun de configurer correctement son IDE)

L’outil le plus simple à mettre en place, c’est d’utiliser le hook de pre-commit git. Ce hook se déclenche au moment du commit. Par défaut il est désactivé (vous pouvez regarder dans n’importe quel repo git en votre possession le fichier .git/hooks/pre-commit.sample), mais on peut s’inspirer de l’exemple pour formatter correctement le code que l’on vient de modifier :

cp .git/hooks/pre-commit.sample .git/hooks/pre-commit

Chez Deepki, nous utilisons principalement 2 langages de programmation : python et javascript (avec le framework vuejs). L’idée est de détecter quels sont les fichiers modifiés par le commit et de passer le linter adapté dessus. Par exemple, pour détecter les fichiers .py concernés par le commit en court, on écrira :

touched_python_files=`git diff --cached --name-only |egrep '\.py$' || true`

Pour python, les 2 outils autopep8 et isort permettent respectivement de formatter le code selon la norme PEP8 et de trier correctement les imports dans un module. Pour cela, il suffit d’installer les packages autopep8 et isort dans votre environnement.

On peut ainsi ajouter à la fin du fichier .git/hooks/pre-commit :

touched_python_files=`git diff --cached --name-only |egrep '\.py$' || true`
if [ -n "$touched_python_files" ]; then
    autopep8 --in-place $touched_python_files
    isort $touched_python_files -rc
fi

Pour le javascript, nous utilisons eslint. On peut ajouter à la fin du fichier .git/hooks/pre-commit le code suivant :

touched_js_files=`git diff --cached --name-only |egrep '\.(vue|js)$' || true`
if [ -n "$touched_js_files" ]; then
    ./front/node_modules/.bin/eslint --fix $touched_js_files
fi

Enfin, pour avoir de jolis fichiers markdown, prettier fait le travail admirablement :

touched_md_files=`git diff --cached --name-only |egrep '\.md$' || true`
if [ -n "$touched_md_files" ]; then
    echo "$touched_md_files" | xargs prettier --write --prose-wrap=always --print-width=120
fi

Et voilà ! Avec ce hook, vous avez la garantie de formatter correctement les fichiers que vous touchez au fil de l’eau. De commit en commit, la base de code va s’améliorer toute seule et les conflits de formattage disparaitront d’eux-mêmes.