<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>automatisation - Tag - Jordan Chapuy - Blog d'un développeur passionné ❤️</title><link>https://jordanchapuy.com/tags/automatisation/</link><description>automatisation - Tag - Jordan Chapuy - Blog d'un développeur passionné ❤️</description><generator>Hugo -- gohugo.io</generator><language>fr</language><lastBuildDate>Sat, 11 Jul 2026 10:46:00 +0200</lastBuildDate><atom:link href="https://jordanchapuy.com/tags/automatisation/" rel="self" type="application/rss+xml"/><item><title>Mise : un outil pour les gouverner tous</title><link>https://jordanchapuy.com/posts/2026/07/mise-un-outil-pour-les-gouverner-tous/</link><pubDate>Sat, 11 Jul 2026 10:46:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2026/07/mise-un-outil-pour-les-gouverner-tous/</guid><description><![CDATA[<p>Il y a trois ans (wow, c&rsquo;est loin, je ne m&rsquo;y attendais pas), j&rsquo;écrivais sur les version managers comme <a href="https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/" rel="">un moyen de faire cohabiter plusieurs versions d&rsquo;un langage, SDK et framework</a>. C&rsquo;est encore d&rsquo;actualité, et je le recommande toujours. Là aujourd&rsquo;hui, j&rsquo;ai envie de m&rsquo;étendre un peu plus sur une possibilité que j&rsquo;avais discrètement glissée dans mon post sans aller plus loin : et s&rsquo;il existait <strong>un seul outil pour gérer tous les autres</strong> ?</p>
<p>La réponse est oui, et j&rsquo;en utilise un depuis bientôt deux ans maintenant. Il s&rsquo;appelle <a href="https://mise.jdx.dev/" target="_blank" rel="noopener noreffer"><strong>mise-en-place</strong></a>, ou <code>mise</code> pour les intimes. Au départ, je l&rsquo;ai adopté pour une raison très simple : j&rsquo;en avais marre de chercher un nouveau version manager pour chaque écosystème.</p>
<p><code>nvm</code> pour Node.js. <code>pyenv</code> pour Python. <code>fvm</code> pour Flutter. <code>rustup</code> pour Rust. <code>chruby</code> pour Ruby. Un autre pour je ne sais quel SDK qui arrive sur un projet. Vous avez la musique. Chaque outil est souvent très bien dans son coin, mais l&rsquo;ensemble finit par créer une petite fatigue. Rien de dramatique, on va s&rsquo;en remettre, mais le genre de friction qui revient souvent.</p>
<p>Installer. Mettre à jour. Changer de version. Expliquer à un collègue quoi installer. Retrouver où la version est déclarée. Se souvenir si cette commande s&rsquo;applique globalement ou seulement dans le projet. La promesse de <code>mise</code> est assez agréable : <strong>apprendre une seule façon de faire, puis l&rsquo;appliquer aux autres d&rsquo;outils</strong>.</p>
<h2 id="un-version-manager-généraliste">Un version manager généraliste</h2>
<p><code>mise</code> se place dans la famille des gestionnaires de versions généralistes, comme <code>asdf</code> ou <code>vfox</code>. L&rsquo;idée n&rsquo;est donc pas de gérer uniquement Node.js, Ruby ou Python, mais de fournir <strong>une interface commune pour tout un ensemble de langages, runtimes, SDK et outils de développement</strong>.</p>
<p>Dans un projet, je peux vouloir Python 3.12, Node.js 22, Flutter 3.32, Terraform, Bun, ou encore un outil CLI dont l&rsquo;équipe a besoin. Plutôt que d&rsquo;empiler les gestionnaires spécialisés, je peux demander à <code>mise</code> de s&rsquo;en occuper. Derrière, il sait s&rsquo;appuyer sur plusieurs sources et backends selon les outils. Honnêtement, au quotidien, je n&rsquo;ai pas besoin d&rsquo;y penser. Et c&rsquo;est plutôt bon signe.</p>
<p>Ce n&rsquo;est pas le seul outil capable de faire ça. J&rsquo;avais déjà repéré <code>asdf</code> dans <a href="%28/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/%29" rel="">mon ancien article sur les version manager</a>, et <code>vfox</code> existe aussi dans le même esprit. Pourquoi j&rsquo;ai choisi <code>mise</code> ? Parce qu&rsquo;il m&rsquo;a semblé rapide, actif côté communauté, très fourni en outils supportés, et parce qu&rsquo;il ne s&rsquo;arrête pas au simple rôle de version manager. Je reviendrais dessus juste après.</p>
<p>Mais avant, commençons par le commencement. Installer mise. (Vérifiez tout de même le <a href="https://mise.jdx.dev/" target="_blank" rel="noopener noreffer">site officiel</a> si la méthode a changé entre temps) :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl https://mise.run <span class="p">|</span> sh
</span></span></code></pre></div><p>Si je veux installer Node.js globalement (tout mon PC), la commande ressemble à ça :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mise use -g node@26
</span></span></code></pre></div><p>Si je veux installer Python pour un projet (un dossier et ses enfants) :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mise use python@3.13
</span></span></code></pre></div><p>À partir de là, quand j&rsquo;entre dans le dossier du projet, <code>python</code> pointe vers la bonne version. Je tape <code>python</code>, pas <code>mise python</code>, pas <code>pyenv exec python</code>, pas une commande enveloppée avec un préfixe qui me sort du geste naturel. C&rsquo;est un détail, mais je trouve que ça compte. Quand je lance <code>flutter test</code>, j&rsquo;ai envie d&rsquo;écrire <code>flutter test</code>, pas de me rappeler que sur ce projet précis je dois écrire <code>fvm flutter test</code>.</p>
<h2 id="le-fichier-misetoml">Le fichier <code>mise.toml</code></h2>
<p>Là où <code>mise</code> devient vraiment intéressant, c&rsquo;est avec le fichier <code>mise.toml</code>.</p>
<p>Au début, on peut le voir comme un simple équivalent plus généraliste des fichiers <code>.ruby-version</code>, <code>.node-version</code>, <code>.tool-versions</code>, etc. On déclare les outils et les versions attendues par le projet, puis on versionne ce fichier avec le code. Comme ça, <strong>toute l&rsquo;équipe partage la même configuration</strong>.</p>
<p>Un exemple très simple pourrait ressembler à ça :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tools</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">node</span> <span class="p">=</span> <span class="s2">&#34;26&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">python</span> <span class="p">=</span> <span class="s2">&#34;3.13&#34;</span>
</span></span></code></pre></div><p>Ce n&rsquo;est pas spectaculaire, mais c&rsquo;est très pratique. Le projet dit explicitement &ldquo;pour travailler ici, voici les outils et versions attendues&rdquo;. Le nouveau collègue qui arrive, la machine fraîchement réinstallée, le runner de CI, le moi du futur qui aura tout oublié&hellip; tout le monde lit la même chose.</p>
<p>C&rsquo;est la fin des discussions du style :</p>
<blockquote>
<ul>
<li>Tu es sur quelle version de Node ?</li>
<li>Attends, je croyais qu&rsquo;on était passé en 26 ?</li>
<li>Ah non, sur cette branche il faut encore la version 25.</li>
<li>Pourquoi ça marche chez toi et pas chez moi ?</li>
</ul>
</blockquote>
<p>Bon, je m&rsquo;emballe, cette dernière question ne disparaît jamais totalement malheureusement. Ce serait trop beau. Mais on passe tout de même <strong>d&rsquo;un réglage individuel en un élément de projet versionnée</strong>.</p>
<h2 id="bien-plus-quun-version-manager">Bien plus qu&rsquo;un version manager</h2>
<p>La surprise, pour moi, c&rsquo;est que le fichier <code>mise.toml</code> ne s&rsquo;arrête pas aux outils. On peut aussi y déclarer des variables d&rsquo;environnement, et même des tâches. C&rsquo;est là que <code>mise</code> a commencé à dépasser, chez moi, le rôle du &ldquo;truc qui gère les versions&rdquo; et où je me suis dis que j&rsquo;allais le garder.</p>
<p>Les <strong>variables d&rsquo;environnement</strong>, c&rsquo;est le genre de chose qui finit souvent dans un <code>.env</code>, parfois un fichier différent par outils, ou pire dans une note. Avec <code>mise</code>, on peut les ajouter dans la configuration du projet. Pas les secrets, évidemment. Mais les valeurs non sensibles, les chemins, les réglages utiles au développement, oui.</p>
<p>Et puis il y a les <strong>tâches</strong>. On peut définir des commandes nommées, un peu comme on le ferait avec un <code>Makefile</code> ou des scripts maison. Sauf qu&rsquo;elles vivent dans le même fichier que la déclaration des outils.</p>
<p>Par exemple :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">setup</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">run</span> <span class="p">=</span> <span class="s2">&#34;mise install &amp;&amp; npm install&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">test</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">run</span> <span class="p">=</span> <span class="s2">&#34;npm test&#34;</span>
</span></span></code></pre></div><p>Je simplifie volontairement, mais l&rsquo;idée est là. Sur un projet, il suffit de taper <code>mise setup</code> et cette commande prépare ce qu&rsquo;il faut. Elle installe les outils attendus et prépare le terrain. C&rsquo;est le genre de petite attention qui rend un projet plus accueillant. (et encore une fois, plus &ldquo;future-proof&rdquo; avec notre mémoire)</p>
<p>J&rsquo;ai commencé à le faire sur tout mes nouveaux projets. Je crée un <code>mise.toml</code>, je le source, et petit à petit j&rsquo;y mets les commandes que je rejoue souvent. Pas besoin de se demander si c&rsquo;est <code>make init</code>, <code>npm run setup</code>, <code>./scripts/bootstrap.sh</code> ou autre chose. Pour moi, de plus en plus, c&rsquo;est <code>mise run setup</code>.</p>
<p>Même pour ce blog, j&rsquo;ai une tâche <code>new</code> pour préparer un nouveau post. Créer le dossier, créer un fichier avec un template de post, mettre la date, puis l&rsquo;ouvrir dans VS Code. Rien de révolutionnaire, mais j&rsquo;aime beaucoup écrire de petits scripts pour éviter de répéter les mêmes opérations - <a href="https://jordanchapuy.com/posts/2020/10/soyez-flemmard-ecrivez-des-scripts/" rel="">je suis un flemmard</a>.</p>
<p>Je vous ai parlé des <strong>alias</strong> ? Je peux faire encore plus court en tapant seulement <code>setup</code> ou <code>new</code>. Et ça marche pour tout, pas seulement pour les tâches - ce sont simplement des alias après tout.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">shell_alias</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">new</span> <span class="p">=</span> <span class="s2">&#34;mise run new&#34;</span>
</span></span></code></pre></div><p>Attendez, ce n&rsquo;est pas fini. On peut aller plus loin avec des <strong>hooks</strong> : des commandes qui se lanceront à chaque fois qu&rsquo;on entre/sort du projet, avant ou après une installation, ou même faire du <em>watch</em> ! Quand je vous disais que cet outil allait les gouverner tous. <em>Mon précieux, mon mise</em>.</p>
<h2 id="ce-qui-se-passe-derrière">Ce qui se passe derrière</h2>
<p>Sans rentrer dans un tutoriel complet, ça vaut le coup de comprendre grossièrement comment <code>mise</code> s&rsquo;intègre au terminal.</p>
<p>Le principe de base est assez classique : <code>mise</code> installe les outils dans un de ses dossiers, puis modifie dynamiquement le contenu du <code>PATH</code>. Quand je suis dans un dossier avec un <code>mise.toml</code>, l&rsquo;environnement actif change, et la commande <code>node</code>, <code>python</code> ou <code>flutter</code> pointe vers la version déclarée.</p>
<p>C&rsquo;est aussi pour ça que l&rsquo;expérience reste <strong>très rapide</strong>. En fait, elle est même inchangée. On ne lance pas un gros proxy à chaque commande. Le shell sait directement où chercher les exécutables.</p>
<p>Il existe aussi un mode avec des <em>shims</em> si on en a besoin, c&rsquo;est-à-dire des petits exécutables intermédiaires qui redirigent vers la bonne version. Selon les environnements ou IDE, ça peut être utile. J&rsquo;ai dû passer par les <em>shims</em> pour l&rsquo;extension Flutter de VS Code par exemple.</p>
<p>Je trouve cette partie intéressante parce qu&rsquo;elle répond à une inquiétude que j&rsquo;avais avec certains version managers : est-ce que je vais ralentir mon terminal ? C&rsquo;était par exemple le cas avec <a href="https://jordanchapuy.com/posts/2023/12/mon-terminal-et-zsh-sont-long-a-demarrer-blame-nvm/" rel="">nvm qui est long à démarrer</a>, même si on ne l&rsquo;utilise pas.</p>
<h2 id="bref">Bref</h2>
<p>Au départ, je cherchais surtout un version manager généraliste. Je voulais arrêter d&rsquo;accumuler un outil par langage. <code>mise</code> m&rsquo;a donné ça : une manière commune d&rsquo;installer, mettre à jour et changer de version. Et il est même allé là où je ne l&rsquo;attendais pas avec les variables d&rsquo;environnement et les tâches.</p>
<p>Aujourd&rsquo;hui, je n&rsquo;installe quasiment plus de langage ou de SDK à la main. Flutter ? Via <code>mise</code>. Python ? Via <code>mise</code>. Les outils autour d&rsquo;<a href="https://jordanchapuy.com/posts/2026/06/maintenir-et-reinstaller-son-homelab-proxmox-avec-ansible-sans-tout-refaire-a-la-main/" rel="">Ansible</a> dont je parlais récemment ? Via <code>mise</code> aussi.</p>
<p>Quand je démarre un projet, mon premier réflexe est de créer et compléter le <code>mise.toml</code> au fur et à mesure pour réduire les frictions. À force, ça devient moins un outil de gestion de versions qu&rsquo;un petit <strong>chef d&rsquo;orchestre</strong> pour mon environnement de développement.</p>
]]></description></item><item><title>Des Version Manager pour faire cohabiter plusieurs versions d’un langage, SDK et framework</title><link>https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/</link><pubDate>Mon, 29 May 2023 19:10:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2023/05/des-version-manager-pour-faire-cohabiter-plusieurs-versions-dun-langage-sdk-et-framework/</guid><description><![CDATA[<p>Ruby, Python, Rust, Node.js, Flutter, &hellip; Comme tout objet dans le monde, les langages, frameworks et outils sont amenés à changer avec le temps. Version mineur par-ci, version majeure par-là. Comment jongler facilement entre les versions ?</p>
<p>Quand on est développeur, on utilise tout un tas d’outils et de SDK. Parfois sur plusieurs projets, qui utilisent des versions différentes bien évidemment. Je peux avoir besoin de Node.js 19 pour le front web et de Node.js 16 pour le backend. Je peux travailler à la fois sur une app Flutter en Dart 2 et une autre en Dart 3. J&rsquo;ai peut-être besoin d&rsquo;une version différente de Python sur mon poste et sur la CI.</p>
<p>Ou parfois sur le même projet avec des branches différentes. Je commence à migrer vers Dart 3 sur une branche, j’ai un bug de prod à corriger il faut que je retourne sur la branche principale qui elle est sous Dart 2.</p>
<p>Si on installe des versions spécifiques à la main, à quoi ressemble notre acrobatie ?</p>
<p>On désinstalle la version X. On télécharge et installe la version Y. On joue avec. On désinstalle la version Y. On télécharge et réinstalle la version X. À chaque étape, c’est un peu de temps perdu. Certains outils sont en plus lourds à télécharger et installer, on se retrouve vite à ouvrir son navigateur ou téléphone et sortir de notre flow :)</p>
<p>C’est là qu’interviennent les outils de gestion de versions.</p>
<h2 id="principe-général">Principe général</h2>
<p>L&rsquo;idée est simple. Plutôt que d’installer directement la toolchain d’un langage par exemple, on va installer l’outil de gestion de version dédié à tel ou tel langage. Chaque langage a son propre gestionnaire, et ce sont souvent des projets open-source. Ils se reconnaissent facilement à leur nom :  ils sont souvent suffixés par <code>Version Manager</code> ou <code>Version Management</code>.</p>
<p>C’est ensuite via le Version Manager que l’on va installer la ou les versions du langage dont on a besoin. Les différentes versions seront installées dans un sous-dossier de l’outil et ne vont pas venir directement s’écraser entre elles dans le dossier <code>/bin</code> (comme ce pourrait être le cas avec une installation classique). On peut ainsi en avoir <strong>plusieurs téléchargées et installées</strong> sur un poste, directement <strong>prêtes à l’emploi</strong>.</p>
<p>Une fois qu’on a installé les versions qui nous intéressent, il n’y a plus qu’à indiquer la version par défaut via <strong>une simple commande</strong>. Et quand on veut changer ? Une commande et c’est opérationnel dans la même seconde. On jongle très facilement avec de multiples versions, branches, projets.</p>
<h2 id="switch-automatique">Switch automatique</h2>
<p>Mieux encore. On peut aller un cran plus loin avec certains Version Manager : <strong>la version utilisée change automatiquement en fonction du projet que l’on ouvre</strong>. C’est le cas avec Ruby par exemple. Il suffit de créer un fichier <code>.ruby-version</code>, d’y écrire le numéro de la version (<code>3.2.2</code>), et de le placer dans le dossier racine du projet. Simple, basique.</p>
<p>L’outil de Version Manager détectera ce fichier et changera la version de Ruby utilisée de manière transparente et automatique. On jongle entre des projets et des branches sans aucune adhérence. On voit encore plus la puissance de ces outils ici.</p>
<p>L&rsquo;intérêt de tels fichiers se retrouve aussi dans le travail en équipe. Le fichier est versionné au sein du projet, ce qui permet à <strong>tous les développeurs d&rsquo;utiliser systématiquement les mêmes versions</strong>.</p>
<h2 id="quelques-exemples">Quelques exemples</h2>
<p>Vous en connaissez probablement déjà quelques uns, voire les utilisez. En voici quelques-uns que j&rsquo;utilise :</p>
<ul>
<li>Si vous travaillez sur des projets web, vous jouez peut-être avec Node.js. Et si vous avez envie de jongler, allez voir du côté de <a href="https://github.com/nvm-sh/nvm" target="_blank" rel="noopener noreffer">nvm (Node Version Manager)</a>.</li>
<li>Des applications mobiles avec Flutter ? <a href="https://github.com/fluttertools/fvm" target="_blank" rel="noopener noreffer">fvm (Flutter Version Management)</a> est là pour nous aider. Il gère aussi le langage Dart.</li>
<li><a href="https://github.com/postmodern/chruby" target="_blank" rel="noopener noreffer">chruby</a>. Il en existe d&rsquo;autres pour Ruby (rvm et rbenv), mais j&rsquo;ai préféré celui-ci car il est léger et il bidouille moins le système (rvm et rbenv surchargent la commande <code>cd</code> par exemple).</li>
<li><a href="https://github.com/pyenv/pyenv" target="_blank" rel="noopener noreffer">pyenv (Python Version Management)</a>.</li>
<li><a href="https://github.com/rust-lang/rustup" target="_blank" rel="noopener noreffer">Rustup (Rust toolchain installer)</a>.</li>
</ul>
<p>La question que vous vous posez peut-être maintenant, c&rsquo;est <em>est-ce qu&rsquo;il en existe un seul pour les gouverner tous</em> ? Jusqu&rsquo;à maintenant, je n&rsquo;avais pas connaissance d&rsquo;un Version Manager qui gérait de multiples runtimes. Mais pendant l&rsquo;écriture de cet article, j&rsquo;ai effectué de rapides recherches et j&rsquo;ai découvert des outils. C&rsquo;est aussi pour ça que j&rsquo;aime écrire, ça me permet de prendre du recul, de chercher davantage, de trouver de nouvelles choses.</p>
<p>En voici deux : <a href="https://github.com/asdf-vm/asdf" target="_blank" rel="noopener noreffer">asdf</a> et <a href="https://github.com/jdxcode/rtx" target="_blank" rel="noopener noreffer">rtx</a>. Je n&rsquo;ai fait aucun test pour le moment, mais je compte bien essayer et vous en parler à l&rsquo;occasion. Si vous avez des retours d&rsquo;expérience avec ces outils, ou d&rsquo;autres, je suis preneur.</p>
<h2 id="contre-parties">Contre-parties</h2>
<p>Il peut y avoir un peu plus de configs et d’étapes à la première installation d&rsquo;un Version Manager, versus installer directement le langage/SDK. Pour autant, cela reste relativement court et facile.</p>
<p>Autre effet de bord pour certains Version Manager, il faut parfois exécuter le langage/SDK via l’outil - ils agissent comme un proxy. Par exemple, on tapera la commande <code>fvm flutter test</code> au lieu de <code>flutter test</code>.</p>
<p>De mon point de vue, j&rsquo;accepte pleinement ces deux points. Je trouve ces inconvénients largement acceptables et plus faibles que les avantages qu’ils apportent - <strong>je peux facilement jongler entre des versions, voire le rendre automatique entre mes projets et mes collègues</strong>.</p>
<p>Mais, il reste une question en suspens. Qui manage les versions des gestionnaires de versions ? 🙃</p>
<p>Une ouverture parfaite pour vous quitter. J&rsquo;y réponds quand même avant de ranger ma plume. A priori, le besoin de jongler à ce niveau n’existe pas. Je les ai installés via <a href="https://brew.sh/" target="_blank" rel="noopener noreffer">Homebrew</a>, le gestionnaire de paquet pour macOS, et c&rsquo;est très bien ainsi.</p>
]]></description></item><item><title>Soyez flemmard, écrivez des scripts</title><link>https://jordanchapuy.com/posts/2020/10/soyez-flemmard-ecrivez-des-scripts/</link><pubDate>Tue, 06 Oct 2020 09:00:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2020/10/soyez-flemmard-ecrivez-des-scripts/</guid><description><![CDATA[<p>Avoir la flemme, ça a aussi du bon. Et quand on est développeur, on peut s’en servir. On a une arme redoutable : la capacité de créer des programmes. On peut facilement automatiser une tâche.</p>
<p>C’était mon cas récemment. Je devais mettre à jour un référentiel dans l’application. On m’a expliqué la procédure habituelle (récupérer un gros fichier de données puis faire une multitude de modifications manuelles), et ça ne me donnait pas terriblement envie.</p>
<p>Faire le robot, en exécutant une série d’actions sans réfléchir, ne me motive pas trop. On n’a pas vraiment de valeur ajoutée. Par contre, faire un script qui le fera à ma place, ça c’était plaisant. Et j’ai même appris des choses au passage.</p>
<hr>
<h1 id="automatisez">Automatisez</h1>
<p>La mise à jour du référentiel se prêtait parfaitement à l’exercice. C’est une tâche simple — il faut télécharger un fichier, faire des traitements de données, et exporter. Et c’est une tâche récurrente — on nous demande régulièrement de le faire sur ce projet. Toutes les conditions sont réunies pour écrire un script.</p>
<p>J’ai sorti mon petit Python pour l’occasion. J’aime bien scripter avec ce langage, notamment lorsqu’il y a du traitement de données. Je trouve que le Python est adapté pour ce besoin, et il est très puissant. C’est aussi plus élégant et parfois plus simple qu’un script bash.</p>
<p>C’était ma préférence sur ce moment-là, mais on peut utiliser ce que l’on veut. Parfois j’utilise Python, parfois un script bash. Vous pouvez utiliser autre chose. Peu importe. Il faut juste faire attention à ne pas créer une usine à gaz, et à ce que ce soit très facilement utilisable.</p>
<p>Je trouve qu’il y a un petit côté créatif à écrire un script. On conçoit quelque chose plutôt que d’être un simple exécutant. On cherche comment automatiser. On réfléchit. On code. C’est au final plus proche de notre métier. On a de la valeur ajoutée.</p>
<p>La création du script m’aura pris un peu moins d’une heure. Ce temps passé est négligeable dans la vie du produit. Sachant que l’on doit régulièrement mettre à jour le référentiel, ce sera un grand <strong>gain de temps</strong>. En effet, cette tâche ne prend maintenant que quelques secondes. Il suffit de lancer le script. Tout est géré.</p>
<p>Et je peux même aller plus loin. Maintenant que le script est créé, on peut envisager d’<strong>automatiser à 100% la tâche</strong>. Plutôt que de prendre du temps à un développeur et même à un Product Owner (créer, tester et suivre un ticket), l’action pourrait être déclenchée automatiquement. À chaque merge ou release par exemple, avec l’aide de l’<strong>intégration continue</strong>.</p>
<h2 id="et-appréciez">Et appréciez</h2>
<p>La productivité n’est pas le seul aspect positif. J’ai pris du <strong>plaisir</strong> à travailler sur ce sujet, en créant un script. Et j’ai même <strong>appris</strong> quelque chose. J’ai eu un problème de conversion de float en string. La manière dont Python tronquait par défaut ne convenait pas. J’ai découvert comment indiquer au parser le format que je souhaitais.</p>
<p>L’utilisation d’un script limite également les erreurs. Qui n’a jamais loupé un chercher / remplacer, ou oublié de modifier une ligne perdue au milieu de milliers d’autres ? Moi, ça m’est déjà arrivé. Lorsque l’on répète bêtement les mêmes actions des dizaines de fois, on peut facilement introduire une erreur. <strong>Le script ne se trompera pas</strong>, et on peut ajouter un filet de sécurité avec des tests unitaires.</p>
<hr>
<h2 id="bref">Bref</h2>
<p>Tous ces points positifs me font dire que la création d’un script est une idée intéressante dans ce genre de situation (une tâche récurrente, du traitement de données, une multitude d’actions à répéter, …).</p>
<p>Je ne dis pas qu’il faut y passer une semaine pour gagner quelques secondes, mais challengez l’idée, et essayez. Mettez-vous une timebox si vous avez peur d’y passer trop de temps. Commencez par quelque chose de simple.</p>
<p>Et vous, sur vos dernières itérations, quelles tâches pourriez-vous automatiser ? Qu’avez-vous déjà automatisé ?</p>
]]></description></item><item><title>Automatically run tests when a change occurs</title><link>https://jordanchapuy.com/posts/2020/06/automatically-run-tests-when-a-change-occurs/</link><pubDate>Thu, 04 Jun 2020 09:00:00 +0200</pubDate><author>Auteur</author><guid>https://jordanchapuy.com/posts/2020/06/automatically-run-tests-when-a-change-occurs/</guid><description><![CDATA[<p>I would like to talk to you about unit tests and how you can automatically run them as soon as you modify code. I regularly use the Test-Driven Development approach when I write code for a project or when doing a code kata. Sometimes I write a little bit too much before running tests again, and when tests turn red, I’m telling myself “Oh! But since when was I wrong?”.</p>
<p>I am jealous of the experience Visual Studio offers with C# and the <a href="https://docs.microsoft.com/en-us/visualstudio/test/live-unit-testing" target="_blank" rel="noopener noreffer">Live Unit Testing</a> feature. Each line of the code is decorated with a symbol indicating if it is covered by passing tests or failing tests, in real-time. Awesome. I need something like that.</p>
<p>I started by searching a similar tool for the languages I use. Then I created a simple script, which runs a command after each file change. Finally, I found a really nice tool for file change monitoring. It is powerful, cross-platform, and open-source. And that’s what I want to talk to you about.</p>
<figure>
</figure>

<hr>
<h1 id="watch-my-changes-">Watch my changes! 🔍</h1>
<p>One way to improve the feedback given by our tests is to know immediately if a change breaks a test. To achieve this goal, we have to continually run tests. The more often we run the tests, the smaller the failing piece of code will be. Ideally, tests should be run after each change. But we can easily forget, or it can be cumbersome.</p>
<p>So we need a way to monitor files and automatically execute a command if there is a change. Some languages and tools offer a built-in way to do that. For example:</p>
<ul>
<li>Kotlin through Gradle &gt; <code>gradle test —-continuous</code></li>
<li>Elm with elm-test &gt; <code>elm-test --watch</code></li>
</ul>
<p>But what if the programming language and tool we are using do not have a watch option? This is where <em>fswatch</em> comes in.</p>
<hr>
<h1 id="fswatch-">fswatch 📡</h1>
<p>Open-source and cross-platform, <em>fswatch</em> is a great tool to monitor file change. It provides recursive directory monitoring, filtering, and supports many OS-specific APIs such as <em>kevent</em>, <em>inotify</em>, and <em>FSEvents</em>.</p>
<p>By using these low-level APIs, <em>fswatch</em> is able to detect any changes in your specified paths and to send informations to another command. The tool is good enough to throttle the execution of the command: it will wait for the user to stop editing the code.</p>
<p>For more information about features or how to install it, please take a look at the GitHub repository.</p>
<p><a href="https://github.com/emcrisostomo/fswatch" target="_blank" rel="noopener noreffer">https://github.com/emcrisostomo/fswatch</a></p>
<h2 id="usage">Usage</h2>
<p>In most cases, you simply want to fire a command as soon as a change is detected in a folder. It’s as simple as this line:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Bash" data-lang="Bash"><span class="line"><span class="cl">fswatch -or YOUR_PATHS <span class="p">|</span> xargs -n1 -I<span class="o">{}</span> YOUR_COMMAND
</span></span></code></pre></div><p><em>fswatch</em> accepts a list of paths to monitor. The <code>o</code> option asks the tool to group changes by batch, and the <code>r</code> option stands for watching subdirectories recursively. Events are then sent through <code>xargs</code> to your command. Here is an example for swift, observing one folder:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Bash" data-lang="Bash"><span class="line"><span class="cl">fswatch -or ./Project <span class="p">|</span> xargs -n1 -I<span class="o">{}</span> swift <span class="nb">test</span>
</span></span></code></pre></div><p>Note that <em>fswatch</em> will run until you stop it, by pressing <code>Control + Z</code> on macOS or <code>Control + C</code> on Linux for example. But that’s what we want, run indefinitely regardless of the test results.</p>
<figure><figcaption>
            <p><em>Screenshot from a terminal executing fswatch.</em></p>
        </figcaption>
</figure>

<hr>
<h1 id="going-further-">Going further 🚀</h1>
<p>So, you got the basics. Now we will see how to improve it.</p>
<h2 id="choose-carefully-the-files-to-monitor">Choose carefully the files to monitor</h2>
<p>You may want to not run your tests for every kind of file changed. A change in an image or in a <em>temp</em> folder probably does not interest you. Observing the right files allows you to run tests only if an impacting change occurs. It can also prevent you from going into an infinite loop.</p>
<p>I had a case where build files were generated after each test, so that triggered the watch, and run tests again, and changes appear, and… this story will never end. The easiest solution for me was to specify multiple sub-directories as input to fswatch` instead of the whole project folder. Remember that you can set multiple paths.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Bash" data-lang="Bash"><span class="line"><span class="cl">fswatch -or ./Sources ./Tests <span class="p">|</span> xargs -n1 -I<span class="o">{}</span> swift <span class="nb">test</span>
</span></span></code></pre></div><p>The other way is to include or exclude paths matching a regex. According to the <em>fswatch</em> manual, you can set options like <code>-i, --include</code> and <code>-e, --exclude</code> for that.</p>
<h2 id="create-a-script">Create a script</h2>
<p>Sometimes, the command you want to fire for each change is long and requires a lot of parameters. It may even be composed of multiple commands. In that case, I recommend you to decompose this step and to create a script to run your tests.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Bash" data-lang="Bash"><span class="line"><span class="cl">fswatch -or ./Sources ./Tests <span class="p">|</span> xargs -n1 -I<span class="o">{}</span> run-tests.sh
</span></span></code></pre></div><p>Better, isn’t it? But we can still improve that. We can avoid typing that long line every time we start working. You see me coming, we’ll make a second script that will do it.</p>
<p><code>live-tests.sh</code></p>
<h2 id="keep-it-visible">Keep it visible</h2>
<p>Now that we have a real-time feedback, we want to see it. It would be a shame to have it hidden in the background. Good news, it is quite easy to keep a terminal in the foreground. Perhaps your favorite editor has already a panel with a terminal, and you just have to show it. Visual Studio Code, for instance.</p>
<p>Some editors like Sublime Text do not have a terminal panel by default, but you can add it with a plugin or extension. And if that’s not possible, you still have the option to put the terminal on a second screen, if you have one, or to reduce your editor window and put a terminal at the left, right, or bottom of it.</p>
<figure><figcaption>
            <p><em>Screenshot from Visual Studio Code with a terminal panel at the bottom.</em></p>
        </figcaption>
</figure>

<hr>
<p>You have everything you need to get started. Monitoring files is at your hands. Enjoy the continuous and real-time feedback of your unit tests.</p>
]]></description></item></channel></rss>