Verifier la qualité de vos commits grâce à git-precommit-checks

Comme faire en sorte que nos commits ne contiennent pas n’importe quoi. Pour les fichiers non versionnables, on a déjà le fichier .gitignore. Mais qu’en est-il pour les fichiers qu’on souhaite versionner ? Comment empêcher l’ajout de contenus indésirables ?

C’est là qu’intervient git-precommit-checks et son exécution automatique au moment du commit grâce à husky.

1. Comment fonctionne git-precommit-checks

git-precommit-checks est un module npm à installer sur vos projets et à exécuter en pre-commit. Il analyse uniquement les ajouts et modifications des fichiers ajoutés en vue du commit (stagés suite à un git add …). Il nous permet soit de stopper le commit en cas de détection d’un contenu non souhaité, soit d’afficher une alerte sur la sortie standard, si on considère que certains contenus sont « tolérables » mais méritent d’être signalés.

Contrairement à un outil d’analyse statique (linter), il n’est pas limité à un langage source. C’est à nous de lui décrire les textes recherchés, éventuellement les motifs de fichiers concernés, et le message à afficher.

2. Mise en place

Pour installer git-precommit-checks, il suffit d'executer la commande ci-dessous :

npm i -g git-precommit-checks

pnpm add -D git-precommit-checks

ensuite, nous devons configurer le hook pre-commit de husky pour la prise en compte de l'outil :

npx husky add .husky/pre-commit "pnpm git-precommit-checks"

On configure dans le fichier package.json les differentes regles de verification à appliquer avant le commit en utilisant le block git-precommit-checks comme decrit ci-dessous :

{
  "git-precommit-checks": {
    "rules": [
      {
        "message": "Aurais-tu oublié de terminer certaines tâches ?",
        "nonBlocking": "true",
        "regex": "(?:FIXME|TODO)"
      },
      {
        "filter": "\\.js$",
        "nonBlocking": "true",
        "message": "You’ve got leftover `console.log`",
        "regex": "console\\.log"
      },
      {
        "message": "Tu as des marqueurs de conflits qui traînent",
        "regex": "/^[<>|=]{4,}/m"
      },
      {
        "message": "Arrêt du commit : tu as renseigné des choses qui ne doivent pas être commitées !",
        "regex": "/do not commit/i"
      }
      
    ]
  },
  "devDependencies": ...
}

Nous pouvons ensuite tester en faisant un commit :

git add .

git commit -m "chore: ajout de `git-precommit-checks`"

Nous pouvons etre confronter à l'erreur ci-dessous lors du commit

contents checks: there may be something to improve or fix!

=== Aurais-tu oublié de terminer certaines tâches ? ===
./package.json:29
./program.cs:13

contents checks: oops, something’s wrong!  😱

=== Arrêt du commit : tu as renseigné des choses qui ne doivent pas être commitées ! ===
./package.json:43

husky - pre-commit hook exited with code 1 (error)

Ceci est dû à la regle git-precommit-checks contenant l'expression reguliere "regex": "/do not commit/i" dans le fichier package.json

Pour contourner ce problème, il suffit de rajouter le flag --no-verify à la commande Git pour le commit

git commit --no-verify -m "chore: ajout de `git-precommit-checks`"

=== Arrêt du commit : tu as renseigné des choses qui ne doivent pas être commitées ! ===
./package.json:43

[2-code-formatting 22033cf] chore: ajout de contents checks: there may be something to improve or fix!
 4 files changed, 1014 insertions(+), 633 deletions(-)