Dans tous les projets informatiques on retrouve un problème récurrent : la gestion des versions des librairies utilisées dans le projet. Deux principaux points posent problèmes :

  • La montée de version d’une librairie
  • La gestion des conflits avec les dépendances transitives

Avec ces deux points on a déjà fait le tour de la question.

Quels sont les problèmes posés ici?

Dans le premier cas, on a toujours des difficultés à maintenir à jour les versions de nos librairies. En effet, l’exercice de monter de version peut s’avérer (dans certain cas) fastidieuse. Lire le change log de la dépendance en question ne suffit pas toujours. Une dépendance transitive peut rentrer en conflit avec une autre version d’une dépendance directe (ou indirecte).

Vous me direz, en fait c’est facile, tu recompiles ton projet et si ça passe c’est que tout va bien :).

Eh bien non, ce n’est pas aussi simple que cela, car le conflit peut se situer entre deux dépendances transitives… et le problème ici c’est que l’erreur ne se verra qu’au Runtime avec une erreur de type :

“No ClassDefFound” ou “No such method error”

À partir de là commence l’enquête minutieuse de comprendre qui a tiré une version de dépendance qui serait utilisée par une autre dépendance … Bref c’est pénible, risqué et pas très efficace.

La solution adoptée dans 80 % des cas, c’est on garde la version courante et on fera la mise à jour lorsque l’on aura le temps.. :).. oui le TEMPS.

Et c’est comme ça que l’on retrouve des projets très conservateur avec des versions datant de l’age de pierre.

Pour endiguer ce phénomène et rentre cette tâche plus facile, il existe le plugin : sbt-missinglink.

Ce plugin, pour SBT, sorti des labos du Scalacenter est une adaptation pour le monde Scala du plugin Maven du même nom, créé par Spotify.

 

Que va faire ce plugin ?

Au lancement de la task :

missinglinkCheck

Le plugin va parcourir l’ensemble des dépendances directes et indirectes du projet et comparer les versions. Cette comparaison se fait sur la base de code en analysant les signatures (de classe et méthodes) et fera la liste des différences entre les versions.

Ci-dessous un exemple :

// Foo v2.0.0 void Foo.bar(String s, int i); // Foo v3.0.0 void Foo.bar(String s, boolean b);

À l’aide de cette liste, on pourra facilement faire évoluer notre base de code afin d’éliminer ces conflits.

L’objectif de ce plugin est d’être intégré ai CI pour détecter les potentiels conflits introduit par une montée de version sauvage. Pour optimiser cette phase, il est possible d’ajouter des options (filtrage, warning vs error, etc..)

À l’aide de cet outil, le maintien à jour des dépendances deviendra un jeu d’enfant 🙂