Compare commits

..

No commits in common. "b0a21dc1e136c86c4ebc077bfeddba5f964dc92d" and "7ae54065489f01105e2902f8bb8ef412c175d347" have entirely different histories.

18 changed files with 35 additions and 671 deletions

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 12C14 14.7614 11.7614 17 9 17H7C4.23858 17 2 14.7614 2 12C2 9.23858 4.23858 7 7 7H7.5M10 12C10 9.23858 12.2386 7 15 7H17C19.7614 7 22 9.23858 22 12C22 14.7614 19.7614 17 17 17H16.5" stroke="#000000" stroke-width="2" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 484 B

View file

@ -1,98 +0,0 @@
Title: Lettre n°14 — 09 mars 2026
Date: 2026-03-09 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°14", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Mar 09 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Édito
Merci à toutes celles et ceux dentre vous qui ont répondu au sondage de la lettre n°12. Une large majorité (83%) apprécie les résumés détaillés, cest pourquoi je vais continuer à en faire. Pas systématiquement, ce sera en fonction de mon envie et de mon temps libre, et aussi parce que plusieurs personnes ont mentionné quelles appréciaient le mix des deux formats —et quelques-unes quelles préféraient les formats courts. Pour être honnête, je vois aussi mon propre intérêt dans lécriture de ces résumés&nbsp;: ils me demandent un effort intellectuel plus important, ce qui fait que je retiendrai plus de choses des articles concernés. Comme je le dis souvent, partager est un des meilleurs moyens dapprendre. Et cette semaine encore, jai beaucoup de choses à partager avec vous 😀.
Bonne lecture&nbsp;!
## Pourquoi Gleam est-il un langage enthousiasmant&nbsp;?
Gavin Bannerman explique [pourquoi il est enthousiasmé par Gleam](https://builders.perk.com/gleam-is-boring-so-i-went-to-a-conference-about-it-8f08a52c3de3)🇬🇧. Cela tourne principalement autour de la simplicité du langage, sa stabilité, et la bienveillance de la communauté. Il est persuadé que le système de types de Gleam améliorerait son expérience sur les gros projets, lui qui utilise TypeScript professionnellement. Par contre, il mentionne le manque de guides dans la documentation comme lun des points faibles. Léquipe qui développe le langage veut améliorer ce point cette année, car elle cherche à développer lusage de Gleam en entreprise. Enfin, il suggère de passer 10 minutes sur le [tour du langage](https://tour.gleam.run/)🇬🇧.
Je partage pleinement lenthousiasme de Gavin. Gleam présente presque toutes les qualités que jattends dun langage de programmation, notamment la simplicité et un typage rigoureux —il ne lui manquerait que de meilleures performances pour être parfait. Jattache de limportance à ce point, car cest une des clés pour diminuer limpact environnemental des applications, tout en procurant une bonne expérience utilisateur. La simplicité est une de mes valeurs favorites. Je considère que la complexité, quand elle nest pas intrinsèque au problème à résoudre, est le résultat dun manque de maîtrise. Avoir du code simple facilite la maintenance et améliore la productivité. Le fait de navoir quune seule façon de faire les choses, comme en Gleam, est lune des clés de cette simplicité.
## Simple made Easy
Dans son article sur Gleam, Gavin Bannerman mentionne [ce talk de Rich Hickey](https://www.youtube.com/watch?v=SxdOUGdseq4)🇬🇧. Rich est le créateur de Clojure, un langage inspiré de Lisp qui produit des exécutables pour la JVM, le CLR (la machine virtuelle .NET), les navigateurs et NodeJS.
Le principal point à retenir de cette présentation, cest la distinction entre simplicité et facilité dans le cadre du développement logiciel.
Quelque chose est facile parce que cest proche, physiquement, ou familier —autrement dit, proche de ce que lon connait. Ou encore proche de nos compétences. La facilité mène souvent à de la complexité cachée.
La simplicité vient dune absence dentrelacement avec dautres choses (concepts, responsabilités, fonctionnalités…). Cest un prérequis pour la fiabilité et la maintenabilité à long terme.
La facilité est une notion relative, tandis que la simplicité est absolue.
Rich ne le mentionne pas, mais la même distinction existe entre [complexe et compliqué](https://vitrinelinguistique.oqlf.gouv.qc.ca/22310/le-vocabulaire/nuances-semantiques/difference-entre-complique-et-complexe).
## Allocateurs de C à Zig
Anton Zhiyanov compare [lutilisation des allocateurs de mémoire dans différents langages](https://antonz.org/allocators/)🇬🇧&nbsp;: Rust, Zig, Odin, C3 et Hare, avant de montrer comment il est possible de définir un allocateur personnalisé en C.
Un allocateur est un outil qui permet à un langage de programmation de réserver puis libérer une zone mémoire, en général sur le tas, afin quun programme y stocke ses structures de données.
La réservation de mémoire à laide dun allocateur requiert en général deux paramètres&nbsp;: la taille de la zone mémoire à réserver, et son alignement. Lalignement contraint ladresse à laquelle la zone doit débuter, en fonction du type des données à stocker&nbsp;:
* pour des octets, lalignement vaut 1, il est possible de démarrer à nimporte quelle adresse mémoire&nbsp;;
* pour des valeurs stockées sur 32 bits, lalignement est de 4, cela veut dire que ladresse de début doit être un multiple de 4&nbsp;;
* pour des valeurs stockées sur 64 bits, lalignement est de 8, cela veut dire que ladresse de début doit être un multiple de 8.
Selon les langages, lallocateur à utiliser peut être défini globalement, ou passé en paramètre lors des appels de fonction&nbsp;; certains autorisent les deux façons de faire, dautre une seule.
Dans tous, la bibliothèque standard propose un ou plusieurs allocateurs prédéfinis, chacun étant prévu pour un cas dusage donné. Par exemple, un allocateur de type "arena" sert à allouer plusieurs zones mémoire qui seront libérées simultanément.
Si le sujet de lallocation de mémoire en C vous intéresse, Geo Carncross détaille des [techniques pour obtenir des gains de performances](https://geocar.sdf1.org/alloc.html)🇬🇧 importants.
## Architecture orientée événements
Dans [Event-Driven Architecture (EDA)&nbsp;: avantages et cas dusage](https://architecti.blog/articles/2025/013-event-driven-architecture---avantages-et-cas-dusage/)🇫🇷, Lucas Bories explique les
bases des architectures orientées événements, leurs avantages, et des patterns darchitecture qui peuvent être utilisés. Il décrit aussi les difficultés engendrées par ces architectures.
Dans [Event sourcing par lexemple](https://www.youtube.com/watch?v=l0c4oR4JPr4)🇫🇷, Loïc Knuchel montre que limplémentation nest pas très complexe. Jai bien aimé la seconde partie, dans laquelle il formule son retour dexpérience, et donne quelques conseils, après avoir expliqué comment ça peut simplémenter. Par contre, il a peu dexpérience sur ce sujet, et son cas dusage est simple, comme il le dit lui-même.
Dans [Les bombes à retardement de lEvent Sourcing / CQRS](https://www.youtube.com/watch?v=tj80_nCDr18) 🇫🇷
Thomas Brouillet, qui a plus de recul, explique les problèmes que lon peut rencontrer avec ce type darchitecture. Cest un bon complément de la présentation précédente.
## Les redirections en Bash
Si, comme moi, vous trouvez que `2>&1` nest pas très explicite, [les explications de Korben](https://korben.info/redirections-bash-qui-sauvent-ta-vie.html)🇫🇷 vous seront utiles.
## Le nombre de lignes de code est de retour, et cest pire quavant
Allan Macgregor constate que [le nombre de lignes de codes est redevenu une métrique populaire](https://www.thepragmaticcto.com/p/lines-of-code-are-back-and-its-worse)🇬🇧, alors quon sait depuis longtemps quelle nest pas pertinente. Il liste ensuite des métriques qui auraient plus dintérêt.
## Une base PostgreSQL qui grossit et ralentit&nbsp;? Ce nest pas un bug, cest une fonctionnalité
Votre base PostgreSQL prend de plus en plus despace disque, et ralentit, bien que le nombre de lignes reste à peu près constant&nbsp;? Roger Welin explique [pourquoi cest normal](https://rogerwelin.github.io/2026/02/11/postgresql-bloat-is-a-feature-not-a-bug/)🇬🇧.
Les données et métadonnées sont stockées sur disque par pages de 8 Ko. Pour retrouver une ligne, PostgreSQL charge lintégralité de la page qui la contient.
PostgreSQL fonctionne selon une logique "append only". Quand une requête modifie une ligne, une nouvelle version des données est écrite sur le disque, souvent dans une page différente. Lancienne version est marquée comme obsolète, mais pas supprimée. De même si une ligne est supprimée par une instruction DELETE, elle nest pas effacée sur le disque. Cest également vrai pour les index, qui contiennent des pointeurs vers les données "effacées", tant quon nexécute pas un REINDEX.
Cest pourquoi lespace disque requis va augmenter au fil du temps, même si le nombre de lignes dans la base naugmente pas.
VACUUM est le ramasse-miette de PostgreSQL. Il est déclenché par un process nommé autovacuum, et va marquer comme réutilisable lespace disque correspondant aux lignes obsolètes. Cependant, lespace occupé ne va pas diminuer.
Parfois, VACUUM ne libère pas lespace disque assez rapidement&nbsp;:
* si les mises à jour sont trop fréquentes&nbsp;;
* si des transactions sont trop longues —en particulier sil manque un COMMIT dans le code.
Cela peut se résoudre en faisant des transactions courtes dune part, et, dautre part, en changeant les valeurs des paramètres `autovacuum_vacuum_cost_delay` et `autovacuum_vacuum_scale_facto` pour les tables mises à jour fréquemment. Larticle se conclut sur des recommandations de configuration de ces paramètres.
## PgDog&nbsp;: scaling horizontal de Postgresql
[PgDog](https://github.com/pgdogdev/pgdog)🇬🇧 est un proxy open source qui gère de façon transparente un pool de connexions et la répartition des données entre plusieurs instances de Postgresql.
## Supprimer les branches Git fusionnées
Il existe de nombreuses commandes Git pour faire le ménage dans un dépôt. [Celle-ci](https://spencer.wtf/2026/02/20/cleaning-up-merged-git-branches-a-one-liner-from-the-cias-leaked-dev-docs.html)🇬🇧. a la particularité amusante de provenir dune fuite doutils de hacking et de documents internes de la CIA.
Il est utile de compléter cette commande par une seconde qui [supprime les références locales aux branches supprimées sur le dépôt distant](https://dev.to/ruqaiya_beguwala/day-1130-git-fetch-prune-clean-up-stale-remote-tracking-branches-1o8f).
## Hornbeam
Benoit Chesneau, le créateur de [Gunicorn](https://fr.wikipedia.org/wiki/Gunicorn)🇫🇷, a créé [Hornbeam](https://hornbeam.dev/)🇬🇧, qui permet de faire tourner des applications Python sur Beam, la machine virtuelle dErlang. Son objectif est de combiner le meilleur des deux mondes.

View file

@ -1,78 +0,0 @@
Title: Lettre n°15 — 16 mars 2026
Date: 2026-03-16 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°15", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Mar 16 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Pourquoi Web Assembly est-il un langage de seconde zone&nbsp;?
Daprès Ryan Hunt, [Web Assembly nest pas un langage de premier plan](https://hacks.mozilla.org/2026/02/making-webassembly-a-first-class-language-on-the-web/)🇬🇧, pour deux raisons&nbsp;:
* dabord, le chargement du code Web Assembly dans une page web nest pas aussi simple que celui du JavaScript&nbsp;; il existe plusieurs méthodes pour le faire, chacune avec des limitations&nbsp;;
* ensuite, Web Assembly ne peut accéder aux APIs Web quà travers JavaScript, et cela requiert un code assez compliqué.
Il explique comment les Web Assembly Components pourraient résoudre ces problèmes et procurer une meilleur expérience de développement.
## Unison
Beaucoup de nouveaux langages de programmation ne proposent que des évolutions incrémentales par rapport à lexistant. Ça ne veut pas dire quils soient dénués dintérêt, loin de là. Japprécie beaucoup Gleam, comme vous le savez si vous lisez régulièrement cette newsletter, mais il nest pas révolutionnaire&nbsp;: Louis Pilfold sest inspiré de ce quil appréciait dans Go, JavaScript, Ocaml, Rust, Erlang, Elixir, Elm et Alpaca, puis en a fait une synthèse, particulièrement réussie. Le seul concept un peu nouveau, il me semble, cest [le mot-clé `use`](https://gleam.run/news/v0.25-introducing-use-expressions/)🇬🇧, mais ce nest que du sucre syntaxique, qui évite le "callback hell".
[Unison](https://www.unison-lang.org/)🇬🇧 ne rentre pas dans cette catégorie&nbsp;: il propose une vraie innovation. Chaque fonction est référencée non pas par son nom, mais par le hash de son AST (Arbre Syntaxique Abstrait). Le nom nest quune métadonnée de la fonction. Ainsi, vous pouvez renommer une fonction sans que cela impacte le code qui lappelle. Cest utile quand vous le ne maîtrisez pas, par exemple si vous êtes lauteur dune librairie utilisée par des tiers.
Chaque fonction est compilée séparément, puis stockée dans une base de données spécialisée appelée Unison Code Manager —au lieu den stocker le code source dans Git ou un équivalent. De ce fait, les temps de compilation sont proches de 0. Cela permet également de faire cohabiter différentes versions dune fonction, pas seulement la dernière. UCM peut aussi détecter que limplémentation dune fonction que votre code utilise a changé, et vous en avertir.
[La présentation de Dejan Miličić](https://www.youtube.com/watch?v=mQHo2Csqs5w)🇬🇧 détaille les nombreuses conséquences de ces choix inhabituels et les possibilités quelles offrent.
Le revers de la médaille, cest que lusage à des fins commerciales de Unison est payant.
## Réduire la taille des binaires Go
Le compilateur du langage Go élimine le code mort… En général&nbsp;! Mais dans certaines conditions, il ne va pas le faire. Cela peut faire croître la taille dune application de façon injustifiée.
Sergio de Simone raconte comment des ingénieurs de chez Datadog ont réussi à [réduire la taille des binaires dune de leurs applications de 77%](https://www.infoq.com/news/2026/03/datadog-go-binary-optimization/)🇬🇧.
## State of Rust
Les résultats du sondage [State Of Rust 2025](https://blog.rust-lang.org/2026/03/02/2025-State-Of-Rust-Survey-results/)🇬🇧 sont disponibles. Je vous laisse les découvrir, je me contenterais de mettre laccent sur ce qui ma interpelé.
Le premier point concerne la complexité du langage. Sans surprise, elle est mentionnée comme un obstacle par un quart des 417 développeurs qui ont répondu au sondage, mais nutilisent pas Rust. Or les répondants au sondage ne sont pas représentatifs de la population des développeurs en général. Si lon faisait un sondage auprès dun public plus large, je soupçonne que ce pourcentage serait encore plus élevé —mais cest peut-être un biais de confirmation de ma part.
Le second point, ma plus surpris&nbsp;: la croissance de la complexité du langage dans les années à venir est lune des plus grandes craintes de 40% des répondants.
Cela me rappelle un article que jai cité dans [la lettre n°2](https://www.craftletter.fr/lettre-ndeg2-15-decembre-2025.html)🇫🇷, dans lequel Sinclair Target explique que ce qui rend Rust si difficile à apprendre, ce ne serait pas la gestion de la mémoire, mais la multiplicité des concepts du langage.
## State of Haskell
Hasard du calendrier, la Fondation Haskell vient de publier les résultats du sondage [State Of Haskell 2025](https://discourse.haskell.org/t/state-of-haskell-2025-results/13755)🇬🇧.
## Refonte de Curling IO
Dave Rapin détaille, dans une série de billets de blog, les choix techniques pour la [refonte du site Curling IO](https://curling.io/blog/the-next-version-of-curling-io)🇬🇧, principalement dédié à la gestion de clubs de curling (on ne rigole pas, cest un sport infiniment plus populaire au Canada quen France).
Il explique pourquoi ils abandonnent Rails, Elm et Postgresql au profit de Gleam et Sqlite&nbsp;; mais aussi les autres solutions considérées, et les gains attendus. Il mentionne également pourquoi ils passent dAWS à OVH pour lhébergement.
Dans les articles suivants, il détaille les choix darchitecture, les compromis et les limitations pour la localisation, lauthentification, la gestion des tâches asynchrones, la base de données, les tests… Il montre également comment le trio Beam (la machine virtuelle dErlang), Gleam, et Sqlite simplifie larchitecture, ce qui réduit significativement les coûts dhébergement et dexploitation.
## Software Delivery Stories
Le [podcast Software Delivery Stories](https://castbox.fm/channel/Software-Delivery-Stories-id5728025?country=fr)🇫🇷 propose à chaque épisode une interview dun expert qui parle de son expérience en déploiement de logiciels. Le fil conducteur de ce podcast, cest Accelerate. Lépisode 0 rappelle ce quest Accelerate.
Les épisodes durent entre une heure et une heure trente. Après un rythme mensuel au début, les épisodes se sont espacés.
## Générer automatiquement un changelog
[Git Cliff](https://github.com/orhun/git-cliff)🇬🇧 est un outil capable de générer automatiquement le changelog dun logiciel, à partir du moment où vous utilisez des messages de commits qui respectent le principe des [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)🇬🇧.
## Diff avec coloration syntaxique
[Deff](https://github.com/flamestro/deff)🇬🇧 est un outil de diff pour Git, qui fonctionne dans le terminal. Il supporte la coloration syntaxique, en se basant sur les fichiers de configuration de Sublime Text, quil faut copier dans un sous-répertoire du projet. Il affiche les fichiers modifiés dans leur intégralité, au sein dune interface qui utilise la totalité de la fenêtre, et dans laquelle on navigue avec des commandes similaires à celles de VI.
[Difftastic](https://difftastic.wilfred.me.uk/)🇬🇧 est aussi un outil de diff, qui utilise des LSP installés localement pour identifier et mettre en évidence les différences. Contrairement à Deff, il naffiche que les modifications et quelques lignes de contexte, comme Git diff, mais sur deux colonnes (par défaut). Il est compatible avec Jujutsu, Mercurial et Fossil.
## Créer des slides dans le terminal
[Ratride](https://amagi.dev/ratride/)🇬🇧 est un outil pour créer et afficher des slides à partir du terminal. Les slides sont décrits dans un fichier markdown.
[Presenterm](https://mfontanini.github.io/presenterm/introduction.html)🇬🇧 est un équivalent. Par rapport à Ratride, il propose des fonctionnalités comme lexécution dextraits de code, laffichage de diagrammes Mermaid, de diagrammes D2, et de formules Latex ou Typst. Il supporte également les notes du présentateur/de la présentatrice, quil affiche dans une seconde fenêtre.
Ratride se distingue de Presenterm par son support des animations et des transitions entre les slides, ainsi que sa capacité à afficher des titres en ASCII art dans diverses polices et couleurs.

View file

@ -1,63 +0,0 @@
Title: Lettre n°16 — 23 mars 2026
Date: 2026-03-23 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°16", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Mar 23 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Python 3.15 introduit les Imports paresseux
La prochaine version de Python apportera une nouveauté attendue plusieurs années&nbsp;: [le chargement des dépendances au moment où elles sont requises](https://techlife.blog/posts/the-story-of-pythons-lazy-imports-why-it-took-three-years-and-two-attempts/)🇬🇧 pour lexécution, et pas au lancement de lapplication. Cela peut améliorer significativement le temps de démarrage des applications. Pour comprendre à quel point cest important, je vous invite à relire larticle que je mentionnais dans la [Craft Letter n°6](https://www.craftletter.fr/lettre-ndeg6-12-janvier-2026.html)🇫🇷 dans "Les chiffres que devraient connaître les développeurs Python".
## Apprivoiser le ramasse-miette de Python
Le [comportement du ramasse-miettes de Python](https://making.close.com/posts/taming-the-python-gc/)🇬🇧 peut facilement être amélioré, et cela a des conséquences significatives sur les performances.
## Chaos Engineering
Adar Hilsenrat explique les bases du [Chaos Engineering](https://engineering.monday.com/chaos-engineering-practices-to-increase-confidence-and-reliability/)🇬🇧, cette pratique qui consiste à introduire volontairement des incidents sur une plateforme afin de vérifier comment elle se comporte dans ce cas.
## Apprendre le terminal avec WebTerm
[WebTerm](https://www.webterm.app/en/tutorials/beginner)🇬🇧 est un outil dinitiation à lutilisation dun émulateur de terminal. Il en simule un dans un navigateur. Il propose des tutoriels dinitiation aux commandes
## Gram Code Editor
[Gram](https://codeberg.org/GramEditor/gram)🇬🇧 est un fork de [Zed](https://zed.dev/)🇬🇧, un éditeur de code similaire à VSCode, mais réputé pour sa rapidité. Les auteurs du fork le justifient notamment par lincompatibilité des termes de la licence avec certains principes de lopen source. La version de base de Zed est gratuite, mais les fonctionnalités liées au IA génératives requièrent un abonnement.
Les auteurs du fork ont supprimé les fonctionnalités IA, les liens avec les serveurs de lentreprise qui développe Zed, et les restrictions dans les conditions dutilisation. Cest un hard fork, cest-à-dire que Gram nest pas compatible avec Zed.
À linverse, il offre quelques nouvelles fonctionnalités, comme la doc intégrée, le support de base pour Gleam, Zig et Odin, et une complétion inspirée du plugin Supertab de Vim.
Il ny a pas de binaire pour Windows téléchargeable pour linstant, seulement pour Linux et MacOs.
## Helix
Puisque je parle déditeur de code, je vais en profiter pour glisser un mot à propos de celui que jutilise depuis deux ans&nbsp;: [Helix](https://helix-editor.com/)🇬🇧.
Helix est un éditeur qui fonctionne dans le terminal, comme VIM. À limage de ce dernier, il fonctionne selon une logique modale, et repose sur lutilisation des raccourcis claviers —lusage de la souris est optionnel, et limité au déplacement du curseur et à la sélection de texte. Vous pouvez tout à fait vous en passer.
Un appui sur une touche permet de changer de mode&nbsp;: Normal, Selection, Window, GoTo, etc. Dans chacun, un ensemble de raccourcis clavier spécifique est disponible. Il y en a des dizaines, ce qui peut faire peur, mais cest là où Helix se distingue de certains de ses concurrents&nbsp;: pour les modes dit "mineurs", une fenêtre contextuelle indique les raccourcis clavier disponibles. Cela facilite grandement lapprentissage, qui se fait petit à petit.
De plus, il existe pour débuter un tutoriel intégré. Il suffit de lancer Helix avec le flag `--tutor`.
Ce tutoriel suffit pour apprendre les commandes indispensables à un usage minimal dHelix. les fenêtres daide intégrées, et la doc parfois, permettent de poursuivre cet apprentissage à votre rythme. En peu de temps, jai été bien plus à laise quavec VI/Vim, dont javais un usage basique depuis une vingtaine dannées —je ne lutilisais que lorsque jétais connecté à un environnement sur lequel il était le seul éditeur disponible.
Helix supporte [plusieurs dizaines de langages et frameworks](https://github.com/helix-editor/helix/wiki/Language-Server-Configurations)🇬🇧 grâce à leurs LSP et formateurs. Il est rapide, notamment parce quil est codé en Rust. Il nest pas encore extensible, mais il propose de base de nombreuses fonctionnalités qui requièrent des plugins et/ou de la configuration sur NeoVIM. Il est donc bien plus facile à mettre en oeuvre.
Helix a réussi à me faire passer dun éditeur graphique comme éditeur principal à un éditeur basé sur le clavier. Jutilise encore Pycharm pour lédition de code Python, quand jai une machine assez puissante pour cela, car il offre des fonctionnalités de refactoring bien plus puissantes que celles dun LSP. Mais pour tout le reste, mon premier réflexe cest dutiliser Helix.
## Ghostty 1.3 est sorti
[Ghostty](https://ghostty.org/)🇬🇧, cest cest émulateur de terminal créé par Mitchell Hashimoto (Fondateur de Hashicorp). Il est multiplateforme (Linux, MacOs et Windows), et utilise des composants graphiques natifs afin de mieux sintégrer à lOS. Il est écrit en Zig et utilise laccélération graphique matérielle pour procurer des performances optimales.
Et ça marche&nbsp;! Je trouvais iTerm2 lent, aussi je suis passé à Kitty. Cétait mieux, mais lui aussi souffrait de quelques lenteurs, ce que je ne ressens pas sous Ghostty.
De plus, japprécie particulièrement le fait de pouvoir passer chaque session en plein écran, puis sortir de ce mode avec le même raccourci clavier (CMD + SHIFT + Entrée sur Mac).
## JReleaser et GoReleaser
[JReleaser](https://jreleaser.org)🇬🇧 est un outil qui simplifie la distribution dapplications via différents canaux, pour Linux, Windows et MacOS. Il permet de préparer des packages pour Homebrew, Winget, Chocolatey, Scoop, Snapcraft et des images Docker par exemple. Il va générer préparer les fichiers requis, en fournissant des valeurs par défaut, puis les signer, ce qui va éliminer de nombreuses tâches manuelles et éviter de devoir se familiariser en détail avec chacun des outils. Malgré son nom, il nest pas limité à Java. Des exemples sont fournis pour Ballerina, Bun, C++, Crystal, C#, Deno, Elixir, F#, Go, Haskell, Nim, OCaml, Odin, Pascal, Perl, Rust, Swift et Zig.
Il est inspiré de [GoReleaser](https://goreleaser.com/)🇬🇧, dont il a repris la mauvaise idée dinclure le nom de la techno dans le nom du produit. Car les auteurs de GoReleaser sont eux aussi obligés dexpliquer quil ne se limite pas au packaging dapplications Go. GoReleaser supporte en effet Rust, TypeScript, Python et Zig, en plus de Go bien entendu.
## Revenir à Rails en 2026
Mark Dastmalchi Round raconte sa [redécouverte de Ruby On Rails](https://www.markround.com/blog/2026/03/05/returning-to-rails-in-2026/)🇬🇧, plus dune douzaine dannées après sen être éloigné. Il explique ce qui a fait que ce framework a connu un grand succès il y a 20 ans, et pourquoi il est encore utilisé aujourdhui, malgré une perte de popularité importante.
## Packager du TypeScript en 2026
Toujours à propos de packaging, François Best décrit les pratiques pour [packager du TypeScript en 2026](https://www.youtube.com/watch?v=h5TKlpRZPzI)🇫🇷. Qui ne seront sans doute plus valables en 2027 😉.

View file

@ -1,60 +0,0 @@
Title: Lettre n°17 — 30 mars 2026
Date: 2026-03-30 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°17", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Mar 30 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Ce que les développeurs fonctionnels nont pas compris à propos des systèmes
Ian Duncan pense que les développeurs qui utilisent des langages fonctionnels fortement typés ont tendance à [confondre la correction du code avec celle du système](https://www.iankduncan.com/engineering/2026-02-09-what-functional-programmers-get-wrong-about-systems/)🇬🇧. Les garanties apportées par ces langages éliminent des classes entières derreurs. Mais cela ne suffit pas à certifier que les programmes se comporteront correctement en production —en tout cas pas dans le cas des services Web, sur lesquels porte larticle. En effet, ce qui doit fonctionner cest le système complet, qui nest pas limité à un programme&nbsp;: il peut en comporter plusieurs instances, ainsi quune base de données, des serveurs divers, etc.
Les développeurs qui utilisent dautres langages souffrent du même travers, mais dans une moindre mesure, car ils ne peuvent pas avoir autant confiance dans le code vérifié par le compilateur.
## Pourquoi un thème clair est préférable à un thème sombre
Jben explique, de façon très détaillée, [pourquoi un thème clair est souvent préférable à un thème sombre](https://linuxfr.org/users/jben/journaux/je-hais-les-themes-sombres-et-je-peux-l-expliquer)🇫🇷. En bref&nbsp;: cest plus facile à lire par les personnes souffrant dastigmatisme ou de myopie, cest-à-dire une large partie de la population. Et ça ne concerne pas que nos IDE, mais aussi les présentations.
Un contre-exemple est cité dans les commentaires, mais il est marginal&nbsp;: cest celui dun écran de contrôle consulté de nuit par des personnes qui ne peuvent pas en régler la luminosité.
## Des palettes de couleurs pour les personnes qui ne les voient pas bien
Une personne sur vingt souffre dun problème de vision des couleurs. David Nichols met à disposition un outil simple qui permet de [sassurer que les couleurs que vous avez choisies sont distinguables](https://davidmathlogic.com/colorblind/)🇬🇧 par toutes les personnes qui visitent votre site. Il fournit aussi quelques exemples de palettes prédéfinies qui prennent en compte ces problèmes.
## Ces détails qui rendent les interfaces plus agréables
Jakub Krehel fournit une liste dastuces qui permettent de [peaufiner les IHM web](https://jakub.kr/writing/details-that-make-interfaces-feel-better)🇬🇧, avec des exemples interactifs.
La différence saute aux yeux pour certains exemples. Pour dautres, cest beaucoup plus subtil. À un point tel que je nai toujours pas compris lexemple danimation des icônes…
## Tansu
Peter Morgan a développé [Tansu](https://www.infoq.com/news/2026/03/tansu-stateless-kafka-compatible/)🇬🇧, un message broker alternatif à Kafka, qui en utilise le protocole, mais repose sur une architecture beaucoup plus simple. Tansu sappuie sur des back-ends existants pour le stockage et la résilience, plutôt que de chercher à développer des workers résilients comme ceux de Kafka. Ces back-ends peuvent être des systèmes compatibles S3, Postgresql ou Sqlite. Contrairement à Kafka, Tansu vérifie le format des messages, plutôt que de déléguer cette tâche aux clients.
Tansu ne semble pas être tout à fait prêt pour la production, mais cest un projet à suivre.
## Comment la Nasa conçoit des systèmes résilients
Lorsquon parle dun appareil qui quitte le sol de notre planète, parfois pour sen éloigner de plusieurs millions de kilomètres, [la gestion des défaillances matérielles et des erreurs logicielles](https://increment.com/software-architecture/in-space-no-one-can-hear-you-kernel-panic/)🇬🇧 prend une toute autre dimension. Surtout sil sagit dune navette ou autre fusée qui embarque des humains à son bord.
## Les fichiers magiques de Git
Au-delà du bien connu `.gitignore`, [Git lit plusieurs autres fichiers de configuration](https://nesbitt.io/2026/02/05/git-magic-files.html)🇬🇧.
Ce que ne mentionne pas Andrew Nessbit dans cet article, cest que vous pouvez avoir, en complétement de ces fichiers, des configurations personnelles, qui ne seront pas publiées sur le dépôt Git contrairement aux précédentes. Je les utilise pour ne pas polluer avec mes préférences les dépôts Git des projets auxquels je contribue.
Pour ignorer des fichiers dans tous vos projets suivis par Git, vous pouvez [définir un fichier .gitgnore global](https://gist.github.com/subfuzion/db7f57fff2fb6998a16c)🇬🇧. Je recommande dy déclarer les fichiers ou répertoires générés par votre IDE. Cela garantit que ce sera fait lorsque vous démarrer un nouveau projet&nbsp;; et cela évite dajouter dans `.gitignore` du contenu qui ne concerne quune personne dans léquipe, car il peut y avoir autant dIDEs que de contributeurs.
Pour ignorer du contenu spécifique à un clone dun projet, il suffit de le déclarer dans `.git/info/exclude`, avec la même syntaxe que dans `.gitignore`. Vous voyez ce fichier que vous devez penser à ne pas inclure, à chaque fois que vous créez un commit&nbsp;? Cest là quil faut le déclarer. Étant situé dans le dossier `.git`, le contenu du fichier `exclude` ne sera pas suivi par Git, contrairement à celui de `.gitignore`.
## Npmx
[Npmx](https://npmx.dev/blog/alpha-release)🇬🇧 est une nouvelle interface pour naviguer parmi les paquets NodeJS. Il sagit dune réponse aux frustrations de nombreux développeurs insatisfaits de leur expérience avec npm.
Npmx fournit des informations indisponibles sur Npm, sur les performances des modules par exemple. Npmx est encore en version alpha mais progresse rapidement.
## Écrire des extensions PHP en Rust
PHP suit la tendance mainstream en offrant la possibilité décrire des [extensions en Rust](https://github.com/extphprs/ext-php-rs)🇬🇧, et plus seulement en C.
## Paris Web 2026
Paris Web est un événement consacré, sans surprise, au développement Web. Lédition 2026 se tiendra du 24 au 26 septembre. [Lappel à sujets](https://www.paris-web.fr/actualites/appel-a-sujets-edition-2026-ouvert)🇫🇷 pour les conférences et les ateliers est ouvert jusquau 12 avril.

View file

@ -1,67 +0,0 @@
Title: Lettre n°18 — 06 avril 2026
Date: 2026-04-06 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°18", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Apr 06 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Chiffrement post-quantique
[Retyc](https://retyc.com/fr)🇫🇷 est une plateforme française qui propose des transferts de fichiers post-quantiques. Cela signifie que les données ne pourraient pas être déchiffrées, même avec un ordinateur quantique.
Je doute que des cybercriminels utilisent déjà des ordinateurs quantiques, même des groupes étatiques, mais il est intéressant de voir que lindustrie sy prépare. En effet, il devrait être possible de décoder, quand ces ordinateurs seront plus accessibles, des données chiffrées collectées avant leur disponibilité.
Retyc est en béta privée actuellement, mais a déjà publié ses tarifs, qui vont de 0 à 216 € par an et par utilisateur.
Ce nest pas le seul projet qui utilise des algorithmes post-quantiques. [OpenSSH le fait depuis plusieurs années](https://www.openssh.org/pq.html)🇬🇧, et cest même devenu le mode par défaut depuis 2022. Or OpenSSH fournit des [outils utilisés par beaucoup dentre nous](https://fr.wikipedia.org/wiki/OpenSSH)🇫🇷.
Une [conférence académique sur ce sujet](https://pqcrypto2026.irisa.fr/)🇬🇧 aura lieu à Saint-Malo mi-avril, mais si vous êtes dans la cible, vous êtes certainement déjà au courant.
## Full Circle
[Full Circle](https://fullcirclemagazine.org/)🇬🇧 est un magazine numérique, gratuit, de la communauté Ubuntu Linux. On y trouve de lactualité sur les logiciels disponibles sous Linux, des tutos, des billets dopinion, des critiques dapplications et de jeux… Il existe aussi des numéros spéciaux dédiés à un thème, en plus du mensuel.
Une [version française](https://www.fullcirclemag.fr/)🇫🇷 est publiée avec un décalage de quelques numéros sur la version anglaise.
## Une alternative au concept de dette logicielle
Thomas Pierrain propose une métaphore qui, daprès lui, serait plus convaincante que celle de la dette technique. Il suggère de [comparer le code à un réseau routier](https://medium.com/@tpierrain/une-alternative-au-concept-de-dette-logicielle-68bb1e16842c)🇫🇷, qui peut comporter des routes avec des ralentisseurs, ou qui sont barrées. Et, parfois, on y trouve des morceaux de verre qui vont vous faire crever un pneu, quil faudra réparer.
## Team Topologies expliqué à Ted Lasso
Toujours parmi les articles de Thomas Pierrain, jen ai découvert un qui explique, de façon succincte, [les quatre types déquipes décrits dans Team Topologies](https://medium.com/@tpierrain/team-topologies-et-football-1639cbd02e97)🇫🇷. Team Topologies est le titre dun ouvrage qui décrit un modèle dorganisation des équipes de développement logiciel, ainsi que leurs modes dinteraction. Ce modèle est orienté vers lefficacité.
Si, comme moi, les analogies avec les rôles dans une équipe de foot ne vous parlent pas, vous pouvez tous simplement les ignorer. Larticle se lit très bien sans ça.
## Rédiger des emails en markdown
Si vous avez eu loccasion denvoyer des emails au format HTML à partir dune application, vous savez que les webmails ne traitent pas le HTML aussi bien que les navigateurs. La mise en page se fait avec des tables, comme au début des années 2000, et le manque de standardisation rappelle aussi cette période.
Il existe des frameworks pour contourner ces limitations. [EmailMd](https://www.emailmd.dev/)🇬🇧 en est un, qui ajoute une couche dabstraction, de sorte que vous nayez à écrire que du Markdown.
## Formation à Rust, de débutant à expert
Microsoft a mis en ligne [sept livres pour lapprentissage de Rust](https://github.com/microsoft/RustTraining)🇬🇧, de la découverte à lapprofondissement. Les premiers sadressent à des développeurs qui viennent dun autre langage&nbsp;: C ou C++, C# ou Python. Les suivants sont consacrés à des points plus précis&nbsp;: asynchronisme, patterns, typage, pratiques dingéniérie.
## Property-Based Testing avec Hegel
[Hypothesis](https://hypothesis.works/) est un framework de property-based testing très populaire, écrit en Python.
Le property-based testing consiste à écrire des tests dans lesquels on sassure quune propriété est toujours vérifiée, quelles que soient les données dentrées. Par exemple, un test peut contrôler que le résultat de lappel à une fonction qui renvoie un nombre de jours est toujours un nombre entier strictement positif. Contrairement aux tests paramétrés, cest le framework qui va générer les données dentrées, de façon plus ou moins aléatoire. Cela permet de tester un bien plus grand nombre de cas, dont certains auquel le développeur/la développeuse naurait pas pensé.
Le créateur dHypothesis a rejoint Antithesis pour y développer [Hegel](https://antithesis.com/blog/2026/hegel/)🇬🇧, qui met à disposition Hypothesis dans dautres langages&nbsp;: Rust, Go, C++, OCaml, et TypeScript. Lapproche adoptée est amusante&nbsp;: au lieu de réécrire Hypothesis dans ces différents langages, ce qui aurait demandé un travail considérable, ils ont fait le choix de créer des décorateurs (*wrappers*) autour du paquet Python —exactement linverse de ce que lon fait habituellement, où Python encapsule un module écrit dans un langage plus performant.
## Amper
[Amper](https://amper.org/dev/)🇬🇧 est un outil créé par JetBrains, pour le build dapplications Java et Kotlin —langage dont ils sont aussi les créateurs. Il est encore à un stade expérimental. Il vise à packager des applications pour toutes les plateformes cibles de Kotlin&nbsp;: la JVM, Android, iOS, Linux, Windows, et macOS. Amper supporte également Swift et Objective-C, dans le cadre des applications iOS produites avec Kotlin MultiPlatform.
Javoue que ce projet me fait un peu peur. Les outils de build du monde Java sont complexes. La doc de Gradle, par exemple, représente plus de 1300 pages quand elle est exportée en PDF. Or, chez JetBrains, la simplicité nest pas une priorité&nbsp;; on peut le voir, entre autres, avec les concepts quils continuent dajouter à Kotlin au fil des versions. Je trouve cela regrettable, car cest ce qui aurait vraiment pu faire la différence avec les outils existants.
## Des outils de développement particulièrement indiscrets
Bien quil ne soit pas écrit par quelquun de neutre, [ce billet de blog](https://www.toolbox-kit.com/blog/i-audited-popular-dev-tools-privacy-results-are-scary)🇬🇧 reste intéressant, car il montre que des sites populaires comme jsonformatter.org, diffchecker.com, base64decode.org, et codebeautify.org ne sont pas respectueux de la vie privée —contrairement à regex101.com.
## Le fonctionnement interne de PostgreSql
Hironobu SUZUKI explique [comment fonctionne PostgreSQL](https://www.interdb.jp/pg/index.html)🇬🇧. Cest vraiment riche, prévoyez dy consacrer quelques heures si vous voulez tout lire et comprendre.
## Comment fonctionne le format JPEG
Dans un article court mais dense, Sophie explique [les astuces exploitées dans le format JPEG](https://www.sophielwang.com/blog/jpeg)🇬🇧, afin déliminer les informations auxquelles loeil humain est peu sensible, ce qui réduit la taille des fichiers.

View file

@ -1,76 +0,0 @@
Title: Lettre n°19 — 13 avril 2026
Date: 2026-04-13 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°19", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Apr 13 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Maestro
[Maestro](https://github.com/mobile-dev-inc/Maestro)🇬🇧 est un framework de tests E2E, pour les navigateurs et applications mobiles.
Il est open source, contrairement à lIDE visuel associé, qui peut servir à lécriture et lexécution des tests.
La description des tests se fait en YAML. Maestro attend la disponibilité des éléments dinterface utilisateur sans quon lui demande explicitement, et relance automatiquement les tests qui échouent.
Comme souvent avec ce genre doutil, une offre cloud payante est proposée.
## Passer de 40 à 4 minutes pour lexécution des tests
Ariel Juodziukynas explique comme son équipe a [divisé par 10 le temps dexécution dune suite de 10 000 tests](https://www.fastruby.io/blog/speed-up-tests-from-40-to-4-minutes.html)🇬🇧. Même sil parle de Ruby, la démarche générale serait valide avec un autre langage.
Ariel liste les impacts positifs de ces changements sur lexpérience développeur, ainsi que la réduction des coûts qui en a découlé. Il aurait pu mentionner limpact environnemental de ces améliorations.
La première étape a été la mise à jour de la version de Ruby&nbsp;; elle a été suivie par le changement du test runner. Ces points ont déjà apporté des améliorations pour un effort minime.
Ensuite, beaucoup de factories ont été remplacées par des fixtures, qui ont lavantage dêtre réutilisables dun test à lautre bien quelles comportent quelques limitations.
Létape suivante a consisté à identifier puis corriger les tests les plus lents.
Cest alors quils ont effectué le changement le plus compliqué&nbsp;: paralléliser lexécution des tests. Un prérequis à cela est de sassurer que les tests peuvent être exécutés dans un ordre aléatoire. Cest seulement si cette condition est remplie que lon peut activer la parallélisation, qui doit être gérée par le test runner.
Il leur a fallu alors gérer des problèmes daccès concurrents à des ressources, comme deux tests qui veulent modifier simultanément un même fichier. Cette étape a été la plus compliquée.
## Devenir un pro de Vim
[VIM_GYM](https://www.vimgym.app/)🇬🇧 est un jeu en ligne pour apprendre les raccourcis clavier de Vim. Il propose des challenges (modifier un extrait de code) à accomplir le plus rapidement possible, en solo ou contre des adversaires.
## Apache Superset
[Apache Superset](https://superset.apache.org)🇬🇧 est une plateforme de visualisation et dexploration de données. Il comporte un éditeur visuel pour créer des dashboards, alimentés par une base de données. Il fournit des drivers pour 80 sources de données différentes, mais les fonctionnalités supportées varient.
*Le bouton getting started dans la page daccueil est cassé, mais celui du haut fonctionne.*
Cet outil me rappelle [Metabase](https://www.metabase.com/)🇬🇧.
Un moyen de gagner du temps sur un projet est de rendre autonomes les équipes qui utilisent ces dashboards au quotidien. Elles peuvent créer leurs propres requêtes pour afficher les métriques qui les intéressent, sans passer par léquipe de développement, qui est soulagée de cette charge. Mais cela va introduire de la rigidité&nbsp;: les développeurs ne pourront plus faire évoluer le modèle de données sans impacter les requêtes écrites par les autres équipes. Si ce problème nest pas géré, la structure de la base de données peut devenir incohérente avec celles des données quelle stocke. Exemple vécu&nbsp;: pas moyen dajouter un état pour dire quun paiement est annulé, et le distinguer dun paiement qui a échoué.
## Les fonctionnalités de Sqlite dont vous ignorez (peut-être) lexistence
[Sqlite supporte des fonctionnalités](https://slicker.me/sqlite/features.htm)🇬🇧 comme le JSON, les colonnes générées, la recherche full-text, le typage strict, les logs Write Ahead (qui améliorent la concurrence et les performances), les expressions de table communes (CTE) et les fonctions de fenêtrage (window functions).
[Les CTE](https://learnsql.fr/blog/sql-ctes-une-vue-d-ensemble-complete-des-expressions-de-table-communes/)🇫🇷 sont une fonctionnalité récente de SQL, qui permet de décomposer les requêtes complexes sans stocker de données intermédiaires dans la base. Elles sont plus faciles à lire et interpréter que les sous-requêtes.
[Les fonctions de fenêtrage](https://learnsql.fr/blog/que-sont-les-fonctions-sql-window/)🇫🇷 sont des fonctions qui effectuent des calculs sur lensemble des lignes liées à la ligne courante.
## Utiliser PostgreSQL pour tout
Je vous parle régulièrement de PostgreSQL, car cette base open source est devenue au fil des ans la base relationnelle de référence. Cest, de mon point de vue, le choix par défaut à faire, à moins que votre projet ait un besoin spécifique, qui ne serait pas couvert par PostgreSQL.
Stephan Schmidt va plus loin que moi, puisquil propose d[utiliser PostgreSQL dans une vingtaine de cas](https://www.amazingcto.com/postgres-for-everything)🇬🇧 pour lesquels, habituellement, on utilise un autre service, tel que Redis, MongoDB, Kafka, Elastic Search, des webhooks, des cron jobs, etc. La plupart du temps, il suggère dutiliser une extension à la place.
## Common Expression Language
Le [Common Expression Language (CEL)](https://cel.dev/?hl=en)🇬🇧 est un langage simple pour décrire des règles ou des configurations, qui peuvent être appliquées, par exemple, à chaque appel dun endpoint dAPI, pour vérifier les droits de lutilisateur.
Cest un langage open source créé par Google. Il en existe des implémentations pour Java, C++, Go, Python, C#, Rust et Kotlin (je ne suis pas certain que cette liste soit exhaustive). Google met en avant la rapidité dexécution de CEL, et son système de types, basé sur celui de Protocol Buffer.
## Comment je suis devenu manager malgré moi
Axel raconte [comment il est passé du rôle de développeur à celui de manager](https://codeheroes.fr/blog/devenu-manager-malgre-moi/)🇫🇷, tout en continuant à coder. Il explique quelles pratiques il a adoptées initialement, et pourquoi elles nont pas été suffisantes pour redresser une situation dégradée par un environnement toxique. Il décrit ensuite comment il a pu restaurer la confiance de léquipe envers lentreprise, confiance dont la perte était le vrai problème.
Si vous nêtes pas manager, ou nenvisagez pas de le devenir, ce retour dexpérience peut vous être utile pour identifier ce que votre manager pourrait faire de mieux. Dautant plus que Axel mentionne, humblement, les erreurs quil a commises.
## TechWork
Le 18 juin 2026 aura lieu la conférence [TechWork](https://techwork.events/)🇫🇷, à Lyon. Ses centres dintérêts sont la Data, le Craft, le Cloud, lAgilité et le Networking. La billetterie est ouverte et la quasi-totalité du programme est déjà annoncée.
## Nantes Craft 2026
[Nantes Craft](https://www.nantes-craft.fr/)🇫🇷 sera de retour pour une seconde édition les 10 et 11 septembre prochains. La première, à laquelle jai participé, était très réussie, que ce soit au niveau du programme ou de lorganisation. Je vous recommande donc cet événement&nbsp;! Le CFP est ouvert.

View file

@ -1,49 +0,0 @@
Title: Lettre n°20 — 20 avril 2026
Date: 2026-04-20 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°20", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Apr 20 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Comment gérer un standup meeting à distance
Jake Worth explique quelques [principes quil applique aux standups / daily meetings](https://www.jakeworth.com/posts/how-i-run-a-software-engineering-standup/)🇬🇧, dont la plupart peuvent sappliquer en local comme à distance.
Pour ma part, jai adopté depuis quelques années une pratique mixte&nbsp;: savoir ce quont fait et ce que vont faire mes collègues est la partie la moins intéressante de ces réunions quotidiennes, et ne nécessite pas quon en discute, la plupart du temps. Cest pourquoi je demande à mes collègues de la faire par écrit, dans un canal dédié de la messagerie. La durée du daily meeting sen trouve souvent raccourcie, et son intérêt augmenté, car il est limité aux points qui nécessitent une discussion&nbsp;: une difficulté rencontrée, un éclaircissement requis sur le contenu dune User Story, une question sur un choix technique, etc. Jinsiste beaucoup sur le fait que le partage de lavancement nest en aucun cas une forme de surveillance, et demande à ce que ne soit évoqué que ce qui apporte de la valeur au projet. Ainsi, Il est inutile de poster un message pour dire "hier, jétais en formation ou en congés, je nai pas avancé sur le projet".
## Plus despace disque en production
Dans [un article digne dun thriller](https://alt-romes.github.io/posts/2026-04-01-running-out-of-disk-space-on-launch.html)🇬🇧, Rodriguo Mesquita raconte comment il a identifié puis résolu le problème qui remplissait lespace disque de son serveur web.
## Une nouvelle version de JJ
Il ny a pas de révolution dans [JJ v0.4.0](https://github.com/jj-vcs/jj/releases/tag/v0.40.0)🇬🇧, cet excellent outil de gestion de version compatible avec Git. Mais jai découvert à loccasion de cette release lexistence de la commande `jj arrange`, pour réordonner les commits, à linstar dun `git rebase` interactif.
## Parse, dont validate, en TypeScript
Christian Ekrem explique [comment appliquer le principe "Parse, dont validate" en TypeScript](https://cekrem.github.io/posts/parse-dont-validate-typescript/)🇬🇧, et quels bénéfice en tirer, malgré les limitations du langage.
## Apprendre Git en jouant
Anaïs Sparesotto a créé [GitQuest](https://www.gitquest.app/fr/)🇫🇷, une application mobile pour apprendre les concepts et lutilisation de Git de façon ludique. Il ne sagit pas dun jeu, mais plutôt dune formation avec quelques éléments de gamification pour entretenir la motivation.
## Auditer un projet avec Git
Ally Piechowski décrit les [cinq commandes Git](https://piechowski.io/post/git-commands-before-reading-code/)🇬🇧 quelle exécute en arrivant sur un projet, afin den apprendre plus sur la vie du projet et de léquipe, les principaux problèmes et risques.
## La proposition de valeur de Elm
Brian Dukes [synthétise les talks récents](https://engagesoftware.com/posts/elms-value-proposition/)🇬🇧 dEvan Czapliki, le créateur de Elm&nbsp;; il présente des arguments en faveur de lutilisation de langages fonctionnels en entreprise, et montre comment Elm répond aux objections souvent formulées contre leur usage.
## Comment faire pour que les développeurs lisent la documentation&nbsp;?
Ibrahim Diallo explique sa [méthode pour créer une documentation que vont lire les différents type de développeurs](https://idiallo.com/blog/how-do-we-get-developers-to-read-the-docs)🇬🇧 auxquels elle sadresse.
Pour aller plus loin dans lorganisation dune documentation, je vous suggère de vous intéresser à [Diataxis](https://silefort.github.io/structurer-sa-documentation-technique-grace-a-diataxis.html)🇫🇷. Ce framework définit comment structurer une documentation, afin quelle réponde aux besoins des lecteurs. Il est utilisé en particulier par Mozilla, pour le site MDN (Mozilla Developer Network). Les principes de Diataxis sont simples et faciles à mettre en oeuvre, et donnent une cohérence appréciable à la documentation. Ils aident à choisir quel format de doc écrire, et comment lorganiser.
## Rust au-delà de la gestion mémoire
Je me retrouve dans [les observations dAndy Brinkmeyer](https://www.infoq.com/articles/practical-robustness-going-beyond-memory-safety-rust/)🇬🇧&nbsp;: avant dapprécier Rust, il faut investir un temps significatif dans son apprentissage. Il explique ce qui, au-delà de la gestion sécurisée de la mémoire, fait que Rust est apprécié par nombre de développeurs et développeuses. On y trouve des concepts issus de la programmation fonctionnelle, comme les types algébriques, le pattern matching exhaustif et les types optionnels&nbsp;; mais aussi des concepts moins courants, comme la propriété des données et la gestion de leur cycle de vie. Andy décrit des patterns que ces particularités du langage rendent possibles, et qui permettent de détecter à la compilation des erreurs subtiles quon aurait découvertes quà lexécution avec un autre langage.
## État des lieux de la cryptographie post-quantique
Dans une conférence intitulée [transition post quantique&nbsp;: challenges et opportunités](https://www.youtube.com/live/LJR03NEcZI0?t=2512)🇫🇷, Ludovic Perret vulgarise létat de lart pour ce qui est de protéger les systèmes informatiques vis-à-vis des ordinateurs quantiques. Et pourquoi il faut le faire dès maintenant, même si les ordinateurs quantiques ne sont pas encore largement disponibles. Cest un expert de cette thématique&nbsp;; il y travaille depuis 25 ans, et est lauteur dune thèse sur le sujet, mais il le rend tout à fait abordable. Cela peut ressembler à un sujet de SF, mais en réalité il y a urgence à sen protéger.
*Merci à Pin qui ma fait découvrir cette vidéo&nbsp;!*

View file

@ -1,93 +0,0 @@
Title: Lettre n°21 — 27 avril 2026
Date: 2026-04-27 09:00
Category: Newsletter
JsonLD: <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "name": "Lettre n°21", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Apr 27 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } } </script>
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
## Édito
Vous avez pu remarquer un problème lors de la publication de la newsletter #19, qui a été envoyée un vendredi au lieu du lundi. Javais oublié de cliquer sur un bouton pour lenvoi, et ne men suis rendu compte que quelques jours plus tard. Cest un des rares points que je nai pas encore automatisés. Cest comme pour le développement, il y a toujours des améliorations à apporter au processus.
À propos daméliorations&nbsp;: sur [le site](https://www.craftletter.fr) sur lequel vous pouvez retrouver tous les numéros, il est dorénavant possible de créer des liens vers chacun des sujet évoqués. Merci à Luc, qui ma guidé vers la solution&nbsp;!
## Générer des cartes
Felix Turner explique comment [générer de superbes cartes](https://felixturner.github.io/hex-map-wfc/article/)🇬🇧 à base dhexagones, avec des routes, des étendues deau, des arbres, des bâtiments, du relief… Il ne rentre pas dans les détails très techniques, car le sujet est complexe, mais explique néanmoins les difficultés quil a rencontrées et comment il sen est sorti. Cliquez sur _Build All_ dans [la démo](https://felixturner.github.io/hex-map-wfc/)🇬🇧 pour voir le résultat.
## Une migration sans interruption de service qui divise par 6 la facture dhébergement
Isa Yeter décrit toutes les étapes que son équipe a suivies pour [migrer un service](https://isayeter.com/posts/digitalocean-to-hetzner-migration/)🇬🇧 comportant 30 bases de données MySQL, 34 serveurs Nginx, une version obsolète de Linux, un serveur Neo4J, des instances de Gitlab et Gearman —le tout sans interruption de service. En passant dun hébergeur US à un hébergeur européen, ils ont divisé leur facture par six.
## TruffleRuby, un Ruby plus performant
Ruby est un langage sympathique, mais dont les performances sont faibles en comparaison de celle des langages compilés. [TruffleRuby](https://github.com/truffleruby/truffleruby)🇬🇧 est une implémentation alternative de Ruby, basée sur GraalVM, qui améliore significativement la rapidité dexécution du code, tout en étant compatible avec Ruby 3.4.
## Comment mener 2000 développeurs vers du numérique responsable&nbsp;?
Tristan Nitot a imaginé la loi dEROOM, qui, à lopposé de la loi de MOORE, vise à optimiser les logiciels pour quils tirent un meilleur parti du matériel. Lobjectif de cette loi est de réduire le renouvellement incessant du matériel informatique et limpact environnemental considérable qui en découle.
Avec Romain Taillade, ils expliquent [comment cette démarche a été mise en oeuvre chez Décathlon](https://blog.octo.com/la-duck-conf-2026-comment-mener-2000-developpeurs-vers-du-numerique-plus-responsable)🇫🇷. La [vidéo de leur intervention](https://www.youtube.com/watch?v=3Xtvw8LdYWg&list=PLXlbmbYadKH4bFiVhW9-VEG6pC7rOyBic)🇫🇷 est également disponible.
## Les nouveautés de Git 2.54
[La version 2.54](https://github.blog/open-source/git/highlights-from-git-2-54/)🇬🇧 de Git introduit la commande `git history`, une alternative plus simple à `git rebase -i` pour corriger un commentaire ou diviser un commit en deux. Avec cette version, il devient aussi possible de configurer des hooks communs à tous vos projets.
## Code for Thought
Peter Schmidt anime [Code for Thought](https://pweschmidt.github.io/offerings/CodeForThought/)🇬🇧, un podcast dans lequel il reçoit des chercheurs ou chercheuses en développement logiciel. Il a la particularité dêtre trilingue&nbsp;: en fonction des invité·es, les épisodes sont en anglais, en allemand, ou en français.
## Ce quAsync promettait, et ce quil a délivré
Josh Segall compare des solutions que des designers de langages ont apporté au problème de lexécution concurrente de code&nbsp;: les threads, les callbacks, les promesses (*Promise/Future*), et Async / Await. Il montre comment [chacune de ces solutions simplifie lécriture par rapport à la précédente, mais introduit de nouveaux problèmes](https://causality.blog/essays/what-async-promised/)🇬🇧.
## Pourquoi je nenchaîne plus tout en JavaSscript
Math Smith trouve que les [enchaînements de fonction en JavaScript](https://allthingssmitty.com/2026/04/20/why-i-dont-chain-everything-in-javascript-anymore/) 🇬🇧 peuvent savérer contre-productifs dès quil y en a plus de deux. Il décrit les patterns quil emploie pour rendre le code plus compréhensible.
## Les lois de lingénierie logicielle
Milan Milanovic a compilé et détaillé [les lois](https://lawsofsoftwareengineering.com/) 🇬🇧 empiriques qui régissent le développement logiciel&nbsp;: loi de Conway, optimisation prématurée, théorème de CAP… Certaines lois se renforcent mutuellement, tandis que dautres se contredisent. Pour chacune, il résume ce quil faut en retenir, donne des exemples, rappelle son origine et fournit des pointeurs vers des lectures complémentaires.
Sur le même sujet, Stéphane Trebel, a donné [une conférence](https://www.youtube.com/watch?v=h3-5pjQaKz8)🇫🇷.
## Comment gérer la dette technique&nbsp;?
Milan Milanovic —encore lui&nbsp;!— revient sur le concept de [dette technique, explique pourquoi il est important de la traiter, et comment faire](https://newsletter.techworld-with-milan.com/p/how-to-deal-with-technical-debt)🇬🇧.
Laccumulation de dette technique ralentit les équipes de développement. Elle provoque frustration et burnouts parmi les développeurs, mais les équipes produit nen tiennent pas toujours compte.
Le principal problème cest que la dette technique est un concept abstrait. Il est donc nécessaire de la rendre explicite et visualisable. Et comme elle est inévitable, il faut mettre en place une stratégie pour la réduire.
### Les types de dette technique
Milan distingue huit catégories principales de dette technique&nbsp;:
* mauvaise **qualité du code**&nbsp;: pas clair, complexe, mal conçu, trop commenté&nbsp;;
* **tests** insuffisants ou ne respectant pas la pyramide des tests&nbsp;;
* **couplage** entre les modules&nbsp;;
* **dépendances et outils** obsolètes&nbsp;;
* **process manuels** (build, déploiement…);
* **architecture** inexistante ou inadaptée&nbsp;;
* manque de **documentation**&nbsp;;
* absence de **partage des connaissances**.
### Comment mesurer la dette technique&nbsp;?
Milan définit le ratio de dette technique comme le rapport entre le coût de la correction dune application et le coût de son développement. Sil est supérieur à 5%, le logiciel est en mauvais état. Au-delà de 50%, il faut se poser la question dune réécriture ou dun abandon du logiciel.
Les outils danalyse statique, les métriques DORA (Accelerate), la couverture de code par les tests fournissent des indicateurs sur le niveau de dette. Ils peuvent être complétés par des sondages réguliers de léquipe technique, à qui lon demande de la noter de 1 à 10. Comme souvent, cest la variation au fil du temps qui est intéressante, plus que la valeur absolue.
### Comment lutter contre la dette technique&nbsp;?
Il faut prioriser, parmi les problèmes identifiés par léquipe, ceux qui impactent des développements en cours ou à venir, et qui saggravent au fil du temps.
Milan Milanovic recommande la stratégie suivante&nbsp;:
1. rendre les problèmes visibles et compréhensibles par tous, notamment avec des graphiques&nbsp;;
2. identifier clairement les responsabilités&nbsp;;
3. prioriser les tâches en fonction de leur impact&nbsp;;
4. allouer du temps à la correction de la dette technique, en fonction de son importance. Cela va de la règle du boy scout, à la mise en place dune équipe, en passant par lallocation de journées dédiée&nbsp;;
5. mesurer les progrès à laide de métriques.
### Comment éviter la création de la dette technique&nbsp;?
La solution de Milan consiste à appliquer les pratiques de leXtreme Programming et du Software Craft, comme le refactoring permanent, le TDD, le pair-programming… et à choisir une architecture en fonction des résultats souhaités.

View file

@ -1,14 +1,14 @@
Title: Accueil
Date: 2026-04-27 09:00
Date: 2026-03-02 09:00
URL:
save_as: index.html
Category: Home
JsonLD: { "@context": "https://schema.org", "@type": "WebPage", "name": "Accueil", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Apr 27 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } }
JsonLD: { "@context": "https://schema.org", "@type": "WebPage", "name": "Accueil", "description": "Lettre de veille technologique en développement logiciel", "image": [ "https://www.craftletter.fr/images/craftletter.svg" ], "datePublished": "Mon Mar 02 2026 09:00:00 GMT+0200 (Coordinated Universal Time)", "author": { "@type": "Person", "name": "Pascal Le Merrer", "url": "https://www.linkedin.com/in/pascal-le-merrer/" } }
<img class="logo" alt="Logo Craft Letter" src="{static}/images/craftletter.svg">
# La [lettre n°21]({filename}/newsletter/craft-letter-21.md) est parue !
# La [lettre n°13]({filename}/newsletter/craft-letter-13.md) est parue !
La Craft Letter est une newsletter hebdomadaire dans laquelle je partage des articles
issus de ma veille technologique. Vous y trouverez des articles relatifs au développement logiciel d'une façon générale, qu'il soit front-end, back-end ou autre. Mais aussi des articles consacrés à l'architecture logicielle, la méthodologie, les outils, des projets open source, des conférences...
@ -37,14 +37,6 @@ Pour savoir qui je suis, ou pourquoi j'écris cette lettre, je vous invite à vo
# Archives
* [Lettre n°21]({filename}/newsletter/craft-letter-21.md)
* [Lettre n°20]({filename}/newsletter/craft-letter-20.md)
* [Lettre n°19]({filename}/newsletter/craft-letter-19.md)
* [Lettre n°18]({filename}/newsletter/craft-letter-18.md)
* [Lettre n°17]({filename}/newsletter/craft-letter-17.md)
* [Lettre n°16]({filename}/newsletter/craft-letter-16.md)
* [Lettre n°15]({filename}/newsletter/craft-letter-15.md)
* [Lettre n°14]({filename}/newsletter/craft-letter-14.md)
* [Lettre n°13]({filename}/newsletter/craft-letter-13.md)
* [Lettre n°12]({filename}/newsletter/craft-letter-12.md)
* [Lettre n°11]({filename}/newsletter/craft-letter-11.md)

View file

@ -40,8 +40,8 @@ devserver-global:
pelican -lr content -o output -s "{{CONFFILE}}" {{PELICANOPTS}} -b 0.0.0.0
# generate using production settings
publish:
just format
publish number:
just format {{number}}
pelican content -o output -s "{{PUBLISHCONF}}" {{PELICANOPTS}}
rsync -e ssh -av --delete-after /Users/pascal/Documents/craft-letter/output/ craftletter@ssh-craftletter.alwaysdata.net:/home/craftletter/www
@ -50,15 +50,15 @@ ssh:
ssh craftletter@ssh-craftletter.alwaysdata.net
# Create the skeleton for a new issue of the newsletter, and reference it into the home page
new:
PYTHONPATH=PWD venv/bin/python ./scripts/create_newsletter.py
new number:
PYTHONPATH=PWD venv/bin/python ./scripts/create_newsletter.py --number={{number}}
# generate HTML email
mail:
just format
PYTHONPATH=PWD venv/bin/python ./scripts/prepare_email.py
mail number:
just format {{number}}
PYTHONPATH=PWD venv/bin/python ./scripts/prepare_email.py --number={{number}}
# Format the content of a given newsletter
format:
PYTHONPATH=PWD venv/bin/python ./scripts/format.py
format number:
PYTHONPATH=PWD venv/bin/python ./scripts/format.py --number={{number}}

View file

@ -36,19 +36,10 @@
{{CONTENT}}
<hr style=" display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0;">
<!-- Signature -->
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="padding: 0;{{SIGNATURE_STYLE}}">
Voilà, cest tout pour cette semaine ! Si vous appréciez le contenu de la Craft Letter, parlez-en autour de vous 😉.
</td>
</tr>
<tr>
<td style="padding: 0;{{SIGNATURE_STYLE}}">
Merci à Benoît et Mickaël pour la relecture et leurs suggestions !
<td style="padding: 0; height: 20px; line-height: 20px; font-size: 20px; ">&nbsp;
</td>
</tr>
<tr>
@ -79,7 +70,7 @@
<tbody style="font-size: 13px; line-height: 1.5; color: #666666; padding: 0">
<tr>
<td align="center" style="padding: 20px 40px;">
<a href="https://www.craftletter.fr">Craft Letter</a> © 2025 {{YEAR}} par <a href="https://www.linkedin.com/in/pascal-le-merrer/">Pascal Le Merrer</a><br>est sous licence <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/">CC BY-NC-ND 4.0</a></p><div><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/nd.svg" style="max-width:1em;max-height:1em;margin-left:.2em">
<a href="https://www.craftletter.fr">Craft Letter</a> © 2025 - {{YEAR}} par <a href="https://www.linkedin.com/in/pascal-le-merrer/">Pascal Le Merrer</a><br>est sous licence <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/">CC BY-NC-ND 4.0</a></p><div><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" style="max-width:1em;max-height:1em;margin-left:.2em"><img alt="" src="https://mirrors.creativecommons.org/presskit/icons/nd.svg" style="max-width:1em;max-height:1em;margin-left:.2em">
</td>
</tr>
<tr>

View file

@ -38,13 +38,3 @@ JINJA_ENVIRONMENT = {
}
STATIC_PATHS = ["images", "robots.txt", "favicon.ico"]
MARKDOWN = {
"extension_configs": {
"markdown.extensions.codehilite": {"css_class": "highlight"},
"markdown.extensions.extra": {},
"markdown.extensions.meta": {},
"markdown.extensions.toc": {"anchorlink": True},
},
"output_format": "html5",
}

View file

@ -30,18 +30,17 @@ def set_publication_date_for_seo(text: str, publication_date: datetime) -> str:
return text.replace("{DATE_UTC}", date_utc)
# Find the number of the letter to create
destination_path = Path(f"./content/newsletter")
p = destination_path.glob("craft-letter-*.md")
files = [x for x in p if x.is_file()]
letter_number = len(files) + 1
# Parse the command line arguments
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", required=True, type=int, help="Newsletter number")
args = parser.parse_args()
# Load the newsletter template
template = Path("./template/newsletter.md")
content = template.read_text()
new_content = content.replace("{LETTER_NUMBER}", str(letter_number))
new_content = content.replace("{LETTER_NUMBER}", str(args.number))
today = datetime.today()
next_monday = get_next_weekday(today, MONDAY)
@ -53,11 +52,9 @@ new_content = set_publication_date_for_pelican(new_content, next_monday)
new_content = set_publication_date_for_seo(new_content, next_monday)
# Create the new file
destination = destination_path / f"craft-letter-{letter_number}.md"
destination = Path(f"./content/newsletter/craft-letter-{args.number}.md")
destination.write_text(new_content)
print(f"Created letter #{letter_number}: {destination}")
# Load the homepage template
template = Path("./template/index.md")
content = template.read_text()
@ -66,15 +63,15 @@ new_content = set_publication_date_for_pelican(content, next_monday)
new_content = set_publication_date_for_seo(new_content, next_monday)
link = f"[lettre n°{letter_number}]({{filename}}/newsletter/craft-letter-{letter_number}.md)"
link = (
f"[lettre n°{args.number}]({{filename}}/newsletter/craft-letter-{args.number}.md)"
)
new_content = new_content.replace("{LINK}", link)
for i in reversed(range(letter_number)):
for i in reversed(range(args.number)):
link = f"* [Lettre n°{i + 1}]({{filename}}/newsletter/craft-letter-{i + 1}.md)\n"
new_content += link
# Update the index page
destination = Path("./content/pages/index.md")
destination.write_text(new_content)
print(f"Updated index page: {destination}")

View file

@ -1,22 +1,19 @@
import argparse
from pathlib import Path
from util import get_latest_newsletter_number
REPLACEMENTS = {
" :": "&nbsp;:",
" ;": "&nbsp;;",
" !": "&nbsp;!",
" !": "&nbsp;!:",
" ?": "&nbsp;?",
"'": "",
"...": "",
}
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", required=True, type=int, help="Newsletter number")
args = parser.parse_args()
letter_number = get_latest_newsletter_number()
file = Path(f"./content/newsletter/craft-letter-{letter_number}.md")
print(f"Formatting letter #{letter_number}: {file}")
file = Path(f"./content/newsletter/craft-letter-{args.number}.md")
content = file.read_text()
for value, replacement in REPLACEMENTS.items():

View file

@ -9,15 +9,14 @@ import argparse
import re
from pathlib import Path
from util import get_latest_newsletter_number
MAIL_GENERATOR = "/opt/homebrew/bin/mdtosendy"
# Find the number of the letter to create
letter_number = get_latest_newsletter_number()
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--number", required=True, type=int, help="Newsletter number")
args = parser.parse_args()
source = Path(f"./content/newsletter/craft-letter-{letter_number}.md")
source = Path(f"./content/newsletter/craft-letter-{args.number}.md")
if not source.is_file():
print(f"ERROR: file not found {source}")
@ -36,7 +35,7 @@ destination.write_text(output)
subprocess.run([MAIL_GENERATOR, str(destination)])
generated_mail = Path("mail") / f"craft-letter-{letter_number}.html"
generated_mail = Path("mail") / f"craft-letter-{args.number}.html"
today = date.today()
mail_content = generated_mail.read_text()
mail_content = mail_content.replace("{{YEAR}}", str(today.year))

View file

@ -1,10 +0,0 @@
from pathlib import Path
def get_latest_newsletter_number():
# Find the number of the latest newsletter
destination_path = Path(f"./content/newsletter")
p = destination_path.glob("craft-letter-*.md")
files = [x for x in p if x.is_file()]
letter_number = len(files)
return letter_number

View file

@ -169,7 +169,7 @@ a {
}
a:hover {
box-shadow: inset 1000px 0 0 0 var(--link-background-color);
box-shadow: inset 800px 0 0 0 var(--link-background-color);
}
ul {
@ -204,10 +204,6 @@ h2 {
font-size: 1.7em;
}
h2 a {
text-decoration: none;
}
h3 {
font-size: 1.5em;
}