Comment se lancer dans une démarche de Clean Code ?

 Dans Clean code

Introduction

 

La qualité du code source a un rôle capital dans la vie d’un projet. Si celle-ci est dégradée, la maintenance peut devenir lourde et compliquée. L’entreprise va alors sortir moins d’évolutions et se faire dépasser par la concurrence. Le code source peut faire la différence entre une entreprise qui reste toujours à la pointe et gagne des parts de marché, et une autre qui n’arrive plus à se maintenir au niveau et souffre à chaque évolution. Alors qu’elle joue un rôle incontournable dans la vie d’une entreprise, la gestion de la qualité du code est souvent négligée ou traitée avec un investissement qui n’est pas celui qu’elle mérite.

Il y a deux questions à se poser si l’on cherche à obtenir un résultat durable :

  • Comment analyser la qualité du code d’un projet ?
  • Comment mettre en place une gestion efficace de la qualité du code par l’équipe ?

Pour la réponse à la première question, il faut d’abord définir ce qu’est la « qualité du code ». Pour simplifier et utiliser un référentiel quantifiable, nous définirons un code de qualité par : « un code correspondant à un référentiel de règles de programmation définis par l’équipe ».

Un moyen simple d’identifier si notre code respecte un référentiel de règles est d’utiliser un linter. Les linters servent à analyser automatiquement un code source et à identifier des parties de celui-ci ne respectant pas certaines règles de programmation.

Pour la seconde question, la réponse est moins évidente. Une bonne gestion de la qualité passe par la mise en place d’un suivi sur celle-ci, un engagement de la part des équipes de développement et la mise en place de stratégies efficaces.

Dans un premier temps, nous allons voir quels sont les avantages d’intégrer un linter au sein de son projet et comment intégrer et configurer un linter au sein d’un projet web.

 

Linters : pourquoi faire ?

 

Avoir un linter au sein d’un projet offre plusieurs bénéfices, même si le gain n’est pas forcément visible à court terme. Celui-ci peut faire la différence entre un projet qui reste compétitif, et un autre qui n’est plus maintenable et coûte plus qu’il ne rapporte.

 

Uniformité du code

Une grande parties des règles des linters sont liées au style d’écriture ou à de la mise en forme.

Chaque développeur a sa propre manière d’écrire du code. Il est probable que dans certains cas, une manière de l’écrire ne soit pas meilleure qu’une autre. Pour autant, il est préférable que l’ensemble du code d’un projet suive la même charte, afin que celui-ci soit facilement compréhensible par n’importe quelle personne.

Les règles des linters vont évidemment nous aider à écrire du code de telle sorte qu’il soit facile à lire ou à modifier, pour cela, les règles vont nous pousser à :

  • éviter les constructions complexes ;
  • limiter la taille des fonctions et des fichiers ;
  • aérer le code.

L’objectif de cette démarche est d’obtenir un code uniforme sur l’ensemble du projet. Les modifications à effectuer dans n’importe quelle partie du code pourront alors être effectuées par n’importe quel membre de l’équipe, sans que du temps soit perdu en compréhension du code.

La liste des règles ESLint concernant le style de codage est disponible ici.

Pour exemple, voici deux manières d’écrire la même chose :

 

 

 

Éviter les défauts de programmation

Ces erreurs proviennent d’une mauvaise utilisation d’un langage de programmation, comme par exemple un attribut dupliqué dans un objet Javascipt.

Elles sont critiques, car elle peuvent entraîner de véritables bugs dans le logiciel.

La liste des règles ESLint concernant les erreurs liées au langage est disponible à cet endroit.

 

Rester à jour sur les technologies

Un linter va également nous permettre de rester à jour sur les technologies qu’on utilise, et donc, d’être compétitif. Prenons le cas d’un projet existant constitué de 100 KLOC écrit en ECMAScript 5, nous souhaitons maintenant utiliser ECMAScript 6 pour utiliser les nouvelles fonctionnalités que possède cette version.

Une très mauvaise idée serait de stopper les développements sur ce projet et de le modifier entièrement, afin que le code passe entièrement en ECMAScript 6. Cela prendrait un temps considérable, pendant lequel l’entreprise ne pourrait pas effectuer de nouvelles évolutions sur le logiciel. La migration peut cependant être effectuée petit à petit, le linter va alors ici nous permettre de faire en sorte que chaque nouveau développement soit écrit en ECMAScript 6. Imaginons que le code du projet soit modifié de 10% chaque mois, en moins d’une année, presque l’ensemble du projet sera à jour sans qu’aucun temps de développement spécifique n’ait été attribué à cette migration.

 

Intégration d’un linter

 

Installation

La première étape consiste à choisir un linter pour notre projet. Il en existe en général plusieurs pour chaque langage. Pour avoir un aperçu des principaux linters open source, rendez-vous sur notre article consacré aux linters.

Dans notre cas, nous allons intégrer une gestion de la qualité du code dans un projet web existant. Ce projet utilisera les technologies :

  • Javascript (Angular 1.5)
  • Scss
  • Html
  • Node.js

Pour un projet web avec les frameworks Angular et Node, nous avons choisi le linter ESLint pour la partie JavaScript (ce choix a été fait pour l’ensemble des règles qu’il contient, autant que pour sa popularité et la fréquence de ses évolutions).

Pour que la démarche de clean code (amélioration de la qualité du code du projet) soit efficace, l’analyse de la qualité du code doit avoir lieu à deux endroits :

  • Dans l‘environnement de développement du développeur (au sein de son éditeur),  pour que les développeurs puissent voir les défauts dans leur code au moment où ils développent.
  • Dans l’intégration continue, pour faire un suivi centralisé de la qualité globale du projet et pour suivre l’évolution de la qualité et se fixer des objectifs.

L’intégration dans l’IDE se fait de manière simple.

Il est possible de lire le rapport fournit par ESLint directement avec Jenkins.

Afin que toute l’équipe suive le même référentiel de règles, il est obligatoire que l’ensemble des développeurs ait le même linter dans leur IDE.

Configuration

Une fois que l’intégration est effectuée, nous passons dans la phase de la configuration.

Un linter comme ESLint possède un nombre important de règles, qui ne correspondent pas forcément aux besoins de votre projet. Il est alors nécessaire de faire un tri dans ces règles, afin d’aboutir à une configuration qui correspond au mieux à ce que vous souhaitez.

Vous pouvez tout d’abord ignorer les dossiers et fichiers que vous ne souhaitez pas analyser à l’aide d’un fichier .eslintignore. De cette manière, ignorez les bibliothèques externes qui sont utilisées sur votre projet, ainsi que les dossiers générés. Maintenant, nous allons définir la liste des règles d’ESLint qui vont être utilisées sur notre projet avec un fichier .eslintrc situé à la racine du projet.

Note : Il est possible de définir des fichiers .eslintrc supplémentaires dans des sous-dossiers, afin d’avoir une configuration spécifique à chaque dossier (utile pour des spécificités clients ou serveurs).

De l’information sur les fichiers de configurations d’ESLint se trouve ici.

Afin d’obtenir la meilleure configuration pour notre projet, nous allons activer l’ensemble des règles d’ESLint avec la configuration eslint:all.

De cette manière, nous allons pouvoir identifier l’ensemble des règles ESLint qui sont violées dans notre projet et faire un tri, pour ne garder que celles que nous jugerons utiles.

Une fois cette configuration activée, l’ensemble des fichiers du projet se retrouve surchargé d’erreurs.

C’est tout à fait normal et il ne faut pas prendre peur. En réalité, il s’agit la plupart du temps de quelques règles de mise en forme, qui ne sont pas respectées à chaque ligne.

 

Maintenant, la prochaine étape consiste à désactiver ou à modifier les règles se retrouvant le plus souvent sur vos fichiers. Pour cela, le plus simple est de choisir un fichier avec beaucoup de contenu et d’identifier les règles qui ne suivent pas les conventions de votre projet. Sur l’exemple de code précédent, on retrouve 4 violations de la règle « Blocks must be padded by blank lines » qui nous demande actuellement d’ajouter une ligne vide au début et à la fin de chaque bloc d’instruction. Cette règle n’est visiblement pas celle qui est actuellement appliquée sur le projet, car il n’existe pas de lignes vides entre les blocs. Nous allons identifier quelles options cette règle  « padded-blocks » possède sur le site d’ESLint.

Dans la documentation, on identifie la configuration correspondant au choix effectué dans notre projet (qui est de ne jamais ajouter de ligne vide entre les blocs). Il s’agit de l’option « never ». Nous allons alors modifier le fichier .eslintrc à la racine de notre projet afin d’ajouter la ligne  « padded-block » : « never ».

Si une règle n’a pas d’importance pour vous, vous pouvez la désactiver en ajoutant une ligne dans le fichier de configurations « <identifiant_de_la_règle>: 0 ».

Exemple de fichier .eslintrc :

Au bout de quelques règles modifiées, les fichiers du projet retrouvent rapidement un nombre réduit de violations. En utilisant un seul fichier de notre projet comme base pour configurer ce linter, nous avons pu identifier les principales règles affectant notre projet mais certaines n’apparaîtront que plus tard dans le développement, ou se trouvent sur des fichiers qui ne sont plus modifiés depuis un long moment. Nous allons donc affiner notre configuration au cours du développement du projet lorsque de nouvelles violations apparaîtront.

Après cette première configuration « gros grain », la prochaine étape est de définir un processus avec l’équipe pour affiner la configuration d’ESLint. Pour cela, chaque développeur doit noter l’identifiant d’une règle lorsqu’il pense qu’elle n’a pas d’importance dans le projet ou qu’elle ne suit pas les conventions définies par l’équipe.

Ainsi, à la fin de chaque semaine, un point est effectué avec l’équipe de développeurs où sont exposées les règles identifiées. L’équipe au complet peut alors définir ce qu’il va advenir de ces règles. C’est un bon moyen de sensibiliser l’ensemble de l’équipe à la démarche de clean code et ça permet d’échanger sur les conventions de code définies sur le projet.

Au bout de quelques semaines, l’ensemble des règles ayant un impact sur le projet devraient être traitées. La configuration d’ESLint correspond donc au plus près aux conventions définies sur le projet. De nouvelles conventions ont également pu être adoptées par l’équipe.

 

Un suivi collectif pour palier les limites des linters

 

Engagement

La gestion de la qualité est un équilibre fragile entre les bons outils, bien paramétrés, l’émergence et l’entretien d’une culture de la qualité. L’étape la plus importante est donc celle de la gestion de la qualité.

L’installation et la configuration d’un linter au sein du projet sont des étapes obligatoires mais ne sont pas efficaces si aucun suivi de la qualité n’est effectué avec l’équipe. Le linter peut alors être totalement délaissé par l’équipe.

L’équipe doit s’organiser afin d’intégrer ce suivi au sein de leurs process.

Celui-ci va prendre plusieurs formes :

  • Un suivi quotidien effectué par chaque développeur sur ses propres actions pour une formation continue. En début de journée, chaque développeur va prendre quelques minutes pour identifier les dernières actions qu’il a effectuées. Si il identifie des règles de programmations qu’il n’a pas respectées, il est préférable qu’il aille effectuer des corrections rapidement pendant que le code qu’il a modifié est encore frais dans sa tête.
    Ce suivi quotidien permet au développeur de se former en continu sur le référentiel de règles de programmation utilisé par l’ensemble de l’équipe.
  • Un suivi hebdomadaire avec l’équipe pour plus d’engagement. Lors d’un point avec l’équipe (au cours d’un daily meeting du vendredi par exemple), le sujet de la qualité doit être abordé pour que l’équipe ait une vision d’ensemble de l’avancée des objectifs de qualité. Cela permet également de créer une émulation entre les développeurs et d’impliquer tout le monde dans la démarche.
  • Un système de périodes pour se donner un rythme. Pour ne pas avoir l’impression de creuser dans un puit sans fond, il est important de donner un rythme à l’équipe afin de planifier des objectifs sur chaque période. Un point est alors à effectuer avec l’équipe en fin de période, afin d’identifier les objectifs atteints ou échoués, et d’en préparer de nouveaux pour la prochaine.
    La dette technique existante va alors être réduite petit à petit tout en évitant que de nouvelles violations soient ajoutées lors des nouveaux développements.

Lors de ces points, les violations de règles doivent être mises en avant, afin que l’ensemble de l’équipe les comprenne et puisse réagir au plus vite lorsque de nouvelles erreurs apparaissent.

Un linter est un outil qui nous donne des indications sur la qualité du code source de nos projets et son rôle se limite à ça.

 

Conclusion

Dans une démarche de qualité, mettre en place un linter sur un projet est obligatoire mais il ne couvre qu’une petite partie de celle-ci. Il reste d’autres points cruciaux à réaliser, qui doivent être effectués directement par l’équipe. Cela implique des modifications organisationnelles, comme la mise en place de rituels liés à la qualité du code, une motivation permanente de l’équipe, une réelle stratégie de correction et un suivi de l’impact de cette démarche.

Ce qui est vrai pour la qualité du code, est aussi vrai pour la stratégie de tests. Les mêmes mécanismes peuvent être activés pour effectuer une gestion pragmatique de la couverture de tests. Et vous, comment gérez vous votre qualité logicielle ? Avez-vous d’autres bonnes pratiques et retours d’expérience qui fonctionnent à nous partager ?

Articles suggérés
Showing 3 comments
pingbacks / trackbacks
  • […] conseillons d’adopter un linter par langage utilisé, et d’utiliser pour commencer une configuration par défaut. Vous pourrez par la suite vous l’approprier pour définir votre propre […]

  • […] autre exemple consiste à réunir l’équipe pour paramétrer les linters utilisés pour identifier les défauts dans le code. Qu’y fait-on précisément ? On regarde la […]

  • […] La version 8.9 de Node.js, sortie cet automne, est la première version LTS (long time support) incluant le support de ECMAScript 2017. C’est l’occasion de simplifier l’usage des promesses grâce aux fonctions asynchrones et aux mots-clés async  et await  : votre code sera plus simple, lisible et maintenable. En bref : clean. […]

Laisser un commentaire