Utilisation de Ploticus pour la réalisation d'indicateurs logiciels



Introduction
L'automatisation est une saine pratique du développement logiciel. Nous avons tous bien plus confiance dans un "make all" que dans une procédure déroulée manuellement (en espérant au moins qu'il y en ait une). Cette pratique fait l'unanimité, que ce soit dans le monde traditionnel du logiciel libre ou dans l'industrie classique.
Pour XP et toutes les méthodes qui construisent et livrent souvent (potentiellement plusieurs fois par jour pour XP), c'est plus qu'une saine pratique : c'est une nécessité vitale.
En résumé, comme le dit un des bons conseils dans "The Pragmatic Programmers" : Don't Use Manual Procedures.

Toutefois, cette pratique est souvent limitée à la production de l'exécutable, des tests et de la documentation, et c'est déjà pas mal. Si on y ajoute l'automatisation de la gestion de configuration, de la production automatique de code quand c'est possible, du contrôle qualité, etc., c'est encore mieux.

Mais je me suis trouvé dans un contexte industriel dans la situation d'un développement parfaitement automatisé coté "technique", et moins bien automatisé coté management. Par ailleurs, l'hétérogénéité des plate formes (Unix pour le développement, Windows pour les indicateurs, compte-rendu, etc.) n'est pas confortable. Je me suis alors demandé si certains élément de ces compte-rendu et feuilles de calcul ne seraient pas générables dans le Makefile coté Unix plutôt que coté bureautique.
Le point dur principal étant les indicateurs, qui pour la plupart sont présentés sous forme de graphiques.

Une recherche sur le net m'a permit de découvrir Ploticus, un étonnant logiciel libre, disponible sur pratiquement toutes les plate-formes, qui permet de produire une gamme impressionnante de graphiques. Je vais illustrer dans cet article la création de quelques indicateurs graphiques sur le logiciel, en ligne de commande, facilement intégrable dans n'importe quel Makefile, et qui compléteront utilement la documentation générée par un quelconque Doxygen.

Je précise tout d'abord que les chiffres ci-après sont inventés de toute pièce.
Notez également que l'exécutable s'appelle ploticus et non pl sur Debian.

Premier exemple : répartition par langage

Commençons par un exemple simple. Je souhaite produire un diagramme "camembert" donnant la répartition par langage utilisé sur mon projet.
J'utilise sloccount, de David A. Wheeler pour cette mesure, comme ceci :
sloccount AWS | grep ".*: *[0-9]* " | tee sloccount.out
Le grep permet de sélectionner les lignes donnant le nombre d'instructions par langage, tous sous-répertoires confondus. ça donne quelque chose comme cela:
 
ada:      71953 (91.24%)
ansic:     6564 (8.32%)
sed:        134 (0.17%)
sh:         113 (0.14%)
java:        99 (0.13%)

Ensuite, me direz-vous, j'importe cela dans mon tableur favori?
Non, car c'est typiquement un fichier avec lequel  Ploticus va se régaler.
 

Voici la ligne de commande la plus simple possible :
pl -prefab pie data=sloccount.out labels=1 values=2
Quelques explications:
Et voici le résultat :
Diagramme Camembert 1

On peut améliorer l'ordinaire en ajoutant quelques options, au nom assez explicite :
pl -prefab pie data=sloccount.out labels=1 colors="blue red green
orange" explode=0.1 values=2 title="sloc par langage dans AWS"
Diagramme Camembert 2
Une fois la mise au point faite en interactif, il suffit d'ajouter -png (ou svg, ps, jpeg, ect.) aux commandes précédentes pour disposer d'une image de moins de 3K affichable n'importe ou.

Deuxième exemple : évolution du nombre de lignes par sous-système

Imaginons maintenant un fichier contenant la mesure mensuelle du nombre de ligne de code par mois des grandes parties du projet. Il pourait ressembler à ceci (la première colonne étant le numéro du mois):
3 1200  0    2005 560
4 4500  0    3110 653
5 9000  632  4012 854
6 17501 2690 5877 854
7 18200 5320 7104 854
8 21658 8960 7523 1960
9 22104 9852 8963 1975

Un diagramme de type "stack" nous permet de montrer la croissande en taille du code, en mettant en valeur les différentes parties du projet. Au plus simple :
pl -prefab stack data=code_size.log x=1 y=2 y2=3
y3=4 y4=5
Diagramme en pile 1
Ajoutons quelques options pour parfaire l'aspect :
pl -prefab stack
data=code_size.log x=1 y=2 y2=3 y3=4 y4=5 -xlbl=Mois name="Applicatif"
name2="Interface graphique" name3="Intergiciel" name4="Interface DB"
title="Taille en SLOC des sous-systèmes" legend="1.5 4"
Et voilà le résultat!
Diagramme en pile 2
Un dernier exemple : le taux de couverture du code par les tests

Immaginons que vous soyez responsable d'un logiciel libre qui reçoit un grand nombre de contributions (bravo!).
Vous aviez immédiatement mis en place des tests unitaires, en vous imposant une couverture mini de 70% des branches, vérifiée avec gcov.
Comment voir d'un simple coup d'oeil si cette contrainte est respectée dans le temps?
Avec un graphique, bien sur!

gcov sort (au moins les versions récentes) entre autre des résultats du type :

90.00% of 10 source lines executed in file tmp.c

80.00% of 5 branches executed in file tmp.c
80.00% of 5 branches taken at least once in file tmp.c
50.00% of 2 calls executed in file tmp.c

Avec un moulinettage trivial, on peut accumuler le critère qui nous intéresse, pour chaque source et pour chaque version.
Admettons que le fichier de log est ainsi fait : la première colonne donne le nom du source, et les colonnes suivantes donne les mesures par version :

Source     V0  V1
exp.adb    88  92
files.adb  75  75

imp.adb 79 100
import.adb 100 100
lsodbc.adb 100 95
odbc.adb   50  99
sql.adb    36  25
util.adb   55  100

Voyons sur quels sources notre attention doit se focaliser :
pl -prefab vbars data=coverage.log header=yes x=Source y=V0 y2=V1
yrange="20 100" cats=yes pointsym=none fill=red ylbl="%"
title="Couverture" ygrid=yes stubvert=yes barwidth=0.1 
On note ici que grace à l'option header, la première ligne du fichier de données peut-être utilisé pour nommer les colonnes dans la ligne de commande, et par défaut sur le graphique. x=Source est plus parlant que x=1, et en plus on peut changer l'organisation des données sans toucher à la commande ploticus.
Diagramme en barres verticales 1
Pour rendre la limite plus parlante, matérialisons la par l'option crossover=80.
Diagramme en barres verticales 2
Conclusion : la version V1 améliore grandement les choses pour odbc.adb et util.adb, mais visiblement il y a plus de contributions pour le code de sql.adb que pour ses tests! :-)

Mais, en y regardant bien, vous vous dites que certains sources méritent une plus grande attention :
introduisons une colonne donnant la couverture minimale requise, et mettons 90% pour les fichiers sensibles, 70% pour les autres :

Source     Min  V0   V1
exp.adb    70   88   92
files.adb  70   75   75
imp.adb    70   79  100
import.adb 70  100  100
lsodbc.adb 90  100   95
odbc.adb   90   50   99
sql.adb    90   36   25
util.adb   90   55  100

C'est l'occasion de conclure avec un exemple de "lines" :
pl -prefab lines data=coverage.log header=yes x=Source y=Min y2=V0
y3=V1 yrange="0 100" cats=yes pointsym=none fill=red name="Tests
insuffisants" xlbl=Sources ylbl="%" title="Couverture" ygrid=yes 
Diagramme en lignes 1
C'est bien plus simple de voir quel est le dernier fichier de la V1 dans la zone rouge, non?

(NB : stubvert=yes plante ploticus sur cet exemple chez moi, d'ou la pagaille sur l'axe y).

Conclusion

Je me suis limité ici à une illustration des possibilités avec une ligne de commande raisonnable. Si on utilise les scripts de Ploticus, il n'y pas vraiment de limite à ce que l'on peut faire, toujours de façon non interactive.

Voyez la galerie des exemples. Par exemple des plannings! Ca donne des idées, non?
 
J'espère que vous avoir convaincu ici qu'il est assez facile d'agrémenter vos make de graphiques utiles pour la conduite d'un développement, sans pour autant sortir l'artillerie bureautique habituelle.