À tous ceux qui écrivent des scripts dans leur coin

Un collègue m’a annoncé qu’il avait écrit un petit script python pour se faciliter la vie sur une tâche assez complexe à faire manuellement, mais qui peut être automatisée facilement.

C’est très bien, beaucoup sont passés par là avant de se lancer dans des sujets plus complexes, et c’est toujours en pratiquant que l’on apprend. Moi aussi, j’ai commencé à me faciliter la vie au travail, en prenant le temps de coder quelque-chose qui a fini par me faire gagner du temps à force de l’utiliser. Avec le recul, je voudrais juste faire cet article sur une règle que je m’impose aujourd’hui systématiquement dès que je commence ce genre de script:

Règle d’or

Toujours écrire un fichier de configuration.

Je ne vais pas rentrer dans des consignes de codage, de documentation ou de couverture de test. Laissons ça aux développeurs pros qui passent leurs journées à ça, et doivent s’organiser pour travailler ensemble de manière efficace. Non, je parle d’autre chose: le fichier de configuration est ce qui permet de transformer un script bidouillé dans son coin en une application prévue pour durer. En séparant le code de sa logique d’utilisation, on entre dans une logique complètement différente, et c’est ce que je vais détailler ici.

Déjà pendant la phase de test de notre script, nous avons besoin de tester notre script avec un premier fichier, puis un autre. Si cela est mis en dur dans le code il est nécessaire de recompiler le code à chaque fois, ce qui nous empêche de se concentrer sur l’essentiel: le résultat que l’on veut obtenir.

Paramétrer son script

Une première solution est de passer les options au programme au lancement. C’est rapide à faire, les librairies pour gérer les arguments sont disponibles dans tous les langages. Par contre, cela change entièrement l’esprit du programme. Au lieu d’avoir

$ mon_script.py

on obtient:

$ mon_script.py fichier.txt --limit 42 --keep even

Déjà, nous rendons visible ce qui est pertinent pour notre application. Nous nommons les paramètres (éventuellement gérons des options par défaut), et nous offrons un avenir à notre application. Au lieu de rester cantonnée dans l’usage qui lui a été destinée initialement, elle s’ouvre à l’infinie combinaison des options possibles.

Dans le code, cela oblige à se poser des questions: ce comportement doit-il être rendu paramétrable ou cela fait-il partie du fonctionnement de base? Cette option doit-elle être obligatoire? Comment nommer ces paramètres? J’ai dit que je n’aborderai pas l’organisation du code, mais la source des problèmes est là : si l’ajout d’une nouvelle option impose de tout réécrire, alors votre script est mal pensé. Il n’est pas maintenable, et le temps passé dessus sera perdu.

Ici, l’application peut être partagée: nous l’ouvrons à d’autres usages, ou bien pour notre moi-futur, ou bien pour des collègues qui ont des besoins différents.

Configurer son application

Mais au bout d’un moment, cela n’est pas suffisant. Pour reproduire le même résultat à l’identique, il faut pouvoir retrouver les mêmes paramètres que ceux utilisés alors. L’historique du shell peut aider, mais si les paramètres sont trop nombreux, il devient fastidieux d’aller corriger l’option et relancer le traitement. D’où ma règle d’or édictée plus haut:

Toujours écrire un fichier de configuration.

Dans un fichier ini, json ou toml, peu importe. Mais dans un fichier à part. Et donner ce fichier en argument au programme. Cela pousse à aller plus loin que les arguments, mais offre une souplesse beaucoup plus importante: nous pouvons cette fois versionner la configuration d’un traitement particulier, nous pouvons modifier notre configuration avec un bloc-note, et ajouter des commentaires pour expliquer ce que l’on fait. Voire commenter certaines options le temps de trouver le paramétrage idéal qui nous convient.

La configuration peut rester technique, comme dans cet exemple qui me permet de définir comment représenter graphiquement des données, mais l’idée est de pouvoir modifier directement ce fichier plutôt que notre code.

{
 "level_0": {
  "shape": "circle",
  "fontsize":36,
  "colorScheme":["accent8", 8],
  "color":"lightgreen",
  "rank":7
 },
 "level_1": {
  "shape": "box",
  "fontsize":14,
  "colorScheme":["set28" , 8],
  "rank":10
 }
}

L’autre avantage est de pouvoir versionner notre fichier de configuration. En garder une copie qui nous savons fonctionner, et une version de travail sur laquelle nous faisons nos tests et que l’on peut casser à tout moment.

Ce n’est plus un script que nous avons fait pour répondre à un besoin particulier que nous avons entre les mains, nous avons créé un processus, qui peut être repris par d’autres que nous. Cette fois, nous avons définitivement fait sortir notre petit script qui avait codé dans un coin. C’est une application que nous avons écrite.