Re-écrire un historique git
Contexte
Ça y est. Après des mois de travail appliqué, le projet est achevé: toutes les fonctionalités ont été implementées, la couverture de tests est satisfaisante, les scripts de déploiement vers les différents environnements fonctionnent.
Bref le client est satisfait et l’heure est venue de transmettre le projet. Cet fois-ci le client souhaite être autonome et continuer seul à exploiter et faire évoluer le logiciel. C’est son choix, c’est son droit, pas de problème.
Une dernière vérification sur le dépôt dévoile une petit souci: le script de déploiement, lors de la phase de construction du paquet, utilise un fichier auth.json
utilisé par composer afin d’accéder à des composants php sous licence. Et ce fichier est enregistré dans le dépôt. Donc si le projet est livré en l’état au client, celui-ci continuera à avoir accès aux dépôts privés.
Le problème
Après consultation du département des ventes, nous apprenons que nous devons distinguer plusieurs cas:
- il y a des composants pour lesquels le client a acquis les droits sur les mises à jour futures;
- pour d’autres logiciels, seule la version disponible au moment de la livraison devra rester accessible;
Pour les premiers composants, les identifiants peuvent rester dans le fichier auth.json
sans problème. Lorsque les futurs développeurs du projet lanceront la commande composer update
les dernières versions seront alors téléchargées. En revanche pour les autres composants (un seul en fait) il va falloir faire autrement.
La méthode va être la suivante:
- retirer les clefs d’accès au dépôt du composant en question du fichier
auth.json
- insérer «/en dur/» dans le dépôt git les sources du composant, et mettre à jour les fichiers
composer.json
etcomposer.lock
en conséquent.
Nous allons nous simplifier la tâche: la deuxième partie (copie du composant dans le dépôt) sera mise en œuvre dans un nouveau commit. C’est un peu de la triche parce que cela signifie que le projet livré ne tournera pas ou ne pourra pas être construit avec les commits précédents le dernier. Néanmoins:
- c’est contractuellement Ok;
- cela fera à peine un peu plus de travail pour les nouveaux développeurs lorsqu’ils voudront utiliser un git bisect.
Quant à la première partie du nettoyage de notre dépôt git, nous allons devoir utiliser un outil diabolique: git filter-branch.
La solution
Cet outil est tellement diabolique que la documentation officielle vous suggère d’utiliser une alternative plus sûre comme filter-repo. Après avoir attentivement lu la documentation des deux outils, j’ai préféré utiliser le plus dangereux des deux, filter-branch
. Pas par amour du risque, mais par besoin de simplicité.
Les deux outils permettent de re-écrire l’historique d’un dépôt git. Modifier l’historique d’un dépôt git n’est pas anodin. Une fois le serveur de référence mis à jour avec le nouvel historique, tous les développeurs devront re-cloner leur dépôt avant de pouvoir pousser à nouveau leurs modifications. Bien sûre, dans le cas décrit ici, cela n’est pas problématique, puisqu’il n’y aura que des nouveaux développeurs.
Alors que filter-repo permet essentiellement de modifier l’historique d’un dépôt git en supprimant, ajoutant ou modifiant des fichiers dans chaque commit, filter-branch
permet d’exécuter une commande avant chaque commit. Dans notre cas, nous allons écraser le fichier auth.json
avec la version contenant les clefs permises.
git filter-branch --tree-filter 'cp /tmp/auth.json src/auth.json' HEAD
Et voilà!
À noter:
- tous vos commits ont maintenant des identifiants différents;
- le fichier
src/auth.json
a été automatiquement ajouté au premier commit, même si cela n’était pas le cas avant.
Mon projet comportait quelques centaines de commits. La commande n’a pas mis plus de quelques minutes pour s’exécuter sur un ordinateur type desktop.
Encore une fois, la commande git filter-branch
est à utiliser avec parcimonie, et uniquement en dernier recours.
Astuces de printemps
Astuces de printemps / aka nouvelle fournée de Petits Tips
Supprimer le canal alpha des images
À cause d’un bug dans une librairie utilisée dans un projet, toutes les images avec un fond transparent apparaissaient avec un fond noir. En attendant une version corrigée de la librairie, il a été décidé de mettre un fond blanc aux images avec transparence. Voici la commande qui réalise cette transformation:
convert -resize 200 -background white -alpha remove pic-with-apha.png pic-with-white-bg.png
Docker
Lorsque l’hébergeur de votre site vous a mis à disposition une base de donnée dans un container, mais que le container n’est pas démarré automatiquement lorsque le serveur redémarre, il faut changer la configuration du container comme ci-dessous.
docker update --restart always mysql-server-container
Redirection de port à l’intérieur d’un container
Imaginons une application web dans un container, dont le port externe au
container 8092 est redirigé vers le port interne 80. Notre application est
configurée pour être appelée sur l’adresse 127.0.0.1:8092. Mais lorsque
l’application s’appelle elle-même depuis l’intérieur du container, le port
8092 n’est pas atteignable. Il faut donc créer une redirection en utilisant
socat
par exemple:
socat tcp-l:8092,fork,reuseaddr tcp:127.0.0.1:80
Convert mp4 into gif
Comme souvent une image veut mieux qu’un long discours, et en description de
bug, une vidéo vaut mieux qu’une image. Vokoscreen est donc votre ami pour les
déclarations de bug, cet outil vous permettant d’enregistrer ce que vous
faites à l’écran. Et lorsque vous avez enregistré votre bug mais que le
formulaire du service client pour ouvrir un ticket n’accepte que le format
gif
, alors ffmpeg
vient à la rescousse.
ffmpeg \ -i vokoscreenNG-2021-04-18_12-25-57.mp4 \ -r 15 \ -vf "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \ bug-live-test-credit-card.gif
Background dynamique
Vous n’arrivez pas à choisir votre fond d’écran? Ne choisissez pas, et changer le fond d’écran toutes les cinq minutes.
while true ; do for f in `ls *|sort -R` ; do feh --bg-max $f ; sleep 300 ; done; done
(n’a pas été testé avec autre chose qu’Awesome)
Tableau récapitulatif des bandes passantes
Contexte
Je suis en train de migrer progressivement toutes les mes mini-machines de mon réseau local de Raspberry 2 et 3 vers le Raspberry 4. J’utilise ces machines comme:
- Firewall
- NAS
- Pihole
Le passage de l’USB 2 des anciennes versions à l’USB 3 de la version du Raspberry 4, m’a poussé à chercher le bottelneck de mon infrastructure.
Le tableau magique
D’une page wikipedia, j’ai extrait les valeurs suivantes:
Connection | bit/s | MB/s |
---|---|---|
Fast Ethernet (100BASE-X) | 100 Mbit/s | 12.5 MB/s |
Gigabit Ethernet (1000BASE-X) | 1 Gbit/s | 125 MB/s |
2.5 Gigabit Ethernet (2.5GBASE-T) | 2.5 Gbit/s | 312.5 MB/s |
5 Gigabit Ethernet (5GBASE-T) | 5 Gbit/s | 625 MB/s |
10 Gigabit Ethernet (10GBASE-X) | 10 Gbit/s | 1.25 GB/s |
USB 2.0 | 480 Mbit/s | 60 MB/s |
USB 3.0 (aka USB 3.1 Gen 1) | 5 Gbit/s | 500 MB/s |
USB 3.1 (aka USB 3.1 Gen 2) | 10 Gbit/s | 1.212 GB/s |
USB 3.2 (aka USB 3.2 Gen 2×2) | 20 Gbit/s | 2.424 GB/s |
Conclusion: Pour profiter réellement de l’USB 3 du NAS il va falloir investir dans un switch 10 Gigabits.
Enregistrer des albums depuis youtube
Avant
Maintenant
Autres temps, autre mœurs. On trouve maintenant sur YouTube1 des albums entiers, qui n’attendent que la ligne de commande pour être téléchargé grâce à Youtube-dl.
Voici donc la fameuse ligne de commande:
youtube-dl -i -x -o "%(artist)s - %(album)s - %(playlist_index)02d - %(track)s.%(ext)s" \ url-de-la-playlist
Cela vous permet de récupérer toutes les pistes d’un album mis en ligne sous forme d‘une playlist. Les constituants des noms des chansons sont alors:
- Le nom de l’artiste
- Le nom de l’album
- L’index de la chanson (ce qui permet de jouer les chansons dans l’ordre)
- Le nom de la chanson
Parfois le nom de l’artiste n’est pas renseigné, il faut donc le remplacer:
for f in NA* ;do eval mv \"$f\" \"${f/NA/Nom de l’artiste}\" ; done
Pour d’autres morceaux, c’est le nom de l’album qui manque et qu’il faut remplacer:
for f in *NA* ;do eval mv \"$f\" \"${f/NA/Nom de l’album}\" ; done
Notes de bas de page:
Hélas, je n’ai pas trouvé l’équivallent sur des instances d’Individious