Bonjour à tout·e·s, aujourd’hui un petit billet de blog détaillant comment j’ai signalé puis corrigé un bug dans le paquet zsh-common de Debian. Je considère que c’est ma première contribution réussie au projet (et oui, il faut bien commencer quelque-part !).
Cette expérience peut vous être utile si vous aussi vous trouvez un bug dans la distribution pour savoir comment le remonter. Si vous avez les compétences techniques nécessaires, alors vous pouvez même proposer de le résoudre !
Une histoire d’autocomplétion
Tout commence lorsque j’étais en train de jouer avec tous les outils Debian pour pouvoir créer des paquets, car c’était là mon objectif initial.
Le shell que j’utilise sur mes machines est ZSH (Wikipedia), aussi connu sous le nom du Z-Shell. Celui-ci est notamment connu pour ses possibilités d’autocomplétion avancées et sa modularité en général, qui fait passer bash pour un ancien dinosaure que l’on réserve aux sessions root ou sur des serveurs.
C’est donc en jouant avec ces outils Debian que je fus positivement surpris de constater que l’autocomplétion fonctionnait très bien pour la plupart des outils. C’est plutôt pratique, surtout pour découvrir toutes les options possibles sans forcément aller lire la page de man complète (ce qui finira tout de même par arriver dans 80% des cas).
De la complétion pour tous les outils ? Et bien, tous sauf au moins un, puisque c’est lors de l’essai de l’appel à dscverify — une commande permettant de vérifier l’intégrité des paquets Debian (binaires, via les fichiers *.changes et sources, via les fichiers *.dsc) — que la complétion ne s’est pas présentée à moi malgré un appui frénétique sur la touche tabulation (provoquant normalement l’apparition des suggestions).
Il nous faut donc désormais trouver un coupable : qui fourni les complétions de tous les paquets Debian, mais a oublié de fournir celle de dscverify ?
Les fichiers de complétion sont recherchés dans les chemins présents dans la variable $fpath spécifique à ZSH, un peu comme les binaires sont recherchés dans la variable $PATH pour tous les shells.
$ echo $fpath
/home/microjoe/.zsh/completions
/home/microjoe/.oh-my-zsh/plugins/virtualenv
/home/microjoe/.oh-my-zsh/functions
/home/microjoe/.oh-my-zsh/completions
/usr/local/share/zsh/site-functions
/usr/share/zsh/vendor-functions
/usr/share/zsh/vendor-completions
/usr/share/zsh/functions/Calendar
/usr/share/zsh/functions/Chpwd
/usr/share/zsh/functions/Completion
/usr/share/zsh/functions/Completion/AIX
/usr/share/zsh/functions/Completion/BSD
/usr/share/zsh/functions/Completion/Base
/usr/share/zsh/functions/Completion/Cygwin
/usr/share/zsh/functions/Completion/Darwin
/usr/share/zsh/functions/Completion/Debian
/usr/share/zsh/functions/Completion/Linux
/usr/share/zsh/functions/Completion/Mandriva
/usr/share/zsh/functions/Completion/Redhat
/usr/share/zsh/functions/Completion/Solaris
/usr/share/zsh/functions/Completion/Unix
/usr/share/zsh/functions/Completion/X
/usr/share/zsh/functions/Completion/Zsh
/usr/share/zsh/functions/Completion/openSUSE
/usr/share/zsh/functions/Exceptions
/usr/share/zsh/functions/MIME
/usr/share/zsh/functions/Math
/usr/share/zsh/functions/Misc
/usr/share/zsh/functions/Newuser
/usr/share/zsh/functions/Prompts
/usr/share/zsh/functions/TCP
/usr/share/zsh/functions/VCS_Info
/usr/share/zsh/functions/VCS_Info/Backends
/usr/share/zsh/functions/Zftp
/usr/share/zsh/functions/Zle
On retrouve en tête de liste les complétions locales que j’utilise, qui concernent en réalité un très faible nombre de commandes dont la complétion n’existe pas. Puis on retrouve toutes les complétions du système dans /usr/share/zsh/ réparties dans plein de sous dossiers bien rangés. Une ligne attire particulièrement l’attention dans notre cas :
/usr/share/zsh/functions/Completion/Debian
Ce dossier a de bonnes chances de contenir des complétions spécifiques aux outils Debian, ce que nous pouvons vérifier rapidement :
$ ls /usr/share/zsh/functions/Completion/Debian | grep dpkg
_dpkg
_dpkg-buildpackage
_dpkg-cross
_dpkg-repack
_dpkg_source
C’est donc bien ici que ce situent toutes les complétions des outils de packaging de Debian. Il nous reste à savoir quel est le paquet qui fourni ces complétions afin de pouvoir passer à l’étape suivante :
$ dlocate /usr/share/zsh/functions/Completion/Debian/_dpkg-buildpackage
zsh-common: /usr/share/zsh/functions/Completion/Debian/_dpkg-buildpackage
C’est donc le paquet binaire [1] zsh-common qui fourni ces fichiers d’autocomplétion ZSH pour les outils Debian. Nous voici en possession de toutes les informations nécessaires pour pouvoir reporter un bug !
[1] | dans le sens Debian, c’est a dire un paquet final, pas un paquet source ; un paquet binaire peut très bien installer des fichiers texte, comme c’est le cas ici. |
Création du bug
On utilise pour cela la commande reportbug fournie par Debian et qui est dédiée à l’interaction avec le BTS (Bug Tracking System) de manière guidée et conviviale. Une interface graphique est disponible, mais après avoir eu quelques surprises je suis repassé par l’interface en ligne de commande (peut-être par habitude également).
L’outil va vous poser toutes les questions nécessaires afin de pouvoir ouvrir un bug dans les meilleures conditions pour vous mais aussi pour le mainteneur en face. Je n’ai plus la liste de tout ce que j’ai renseigné sous la main, mais la seule chose importante dont je me souviens est qu’il ne faut pas spécifier de serveur SMTP si on a pas de MTA de configuré correctement sur sa machine, de laisser le serveur SMTP par défaut de Debian et le bug (mail) pourra donc être envoyé sans encombre.
Voici ce que cela donne quand le bug a pu quitter votre machine pour rentrer dans le BTS :
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=953389
Alors oui, c’est pas spécialement beau, mais il faut savoir que tout se gérant par mail chez Debian, vous avez tout le loisir d’admirer votre bug dans votre client mail favori si l’interface web ne vous convient pas. Je la trouve pour ma part minimaliste et suffisamment lisible, aussi je ne commenterai pas plus ce point.
On remarque que l’outil reportbug ajoute des information supplémentaires en plus de me mon message initial, comme la version de zsh utilisée sur mon système ou bien la release Debian (ici testing).
Proposition de patch
Vous remarquez que mon bug va plus loin que la simple déclaration de sinistre, car en effet je propose également une complétion pour dscverify que j’ai écrite avant d’ouvrir le bug afin de réduire le boulot du mainteneur au strict minimum, ainsi que de me former à la complétion ZSH pour ma gouverne.
Il s’avère que ce patch n’était pas parfait, d’où les plusieurs échanges avec le mainteneur pour améliorer la proposition de complétion initiale. Voici la version finale sur laquelle nous nous sommes accordés, si vous voulez l’essayer chez vous :
diff -u -N --recursive ../zsh-5.8.orig/Completion/Debian/Command/_dscverify ./Completion/Debian/Command/_dscverify
--- ../zsh-5.8.orig/Completion/Debian/Command/_dscverify 1970-01-01 01:00:00.000000000 +0100
+++ ./Completion/Debian/Command/_dscverify 2020-03-09 15:36:16.206314783 +0100
@@ -0,0 +1,30 @@
+#compdef dscverify
+
+# $ dscverify --version
+# This is dscverify, from the Debian devscripts package, version 2.20.2
+# ...
+
+_dscverify() {
+ local all_opts=(
+ '--help[show the help message and exit]'
+ '--version[show the version + copyright and exit]'
+ '--no-default-keyrings[do not check against the default keyrings]'
+ '*--keyring[add keyring to the list of keyrings used]:keyring:_files -g "*.{kbx,gpg}(-.)"'
+ '(--nosigcheck --no-sig-check -u)'{--nosigcheck,--no-sig-check,-u}'[do not verify the GPG signature]'
+ '--verbose[do not suppress GPG output]'
+ '*:dsc file:_files -g "*.{changes,dsc,buildinfo}(-.)"'
+ )
+
+ local first_only=(
+ '(--no-conf --noconf)'{--no-conf,--noconf}'[do not read the devscripts config file]'
+ )
+
+ if (( CURRENT == 2 )); then
+ all_opts+=($first_only)
+ fi
+
+ _arguments \
+ "$all_opts[@]"
+}
+
+_dscverify "$@"
Une fois ce patch bien étoffé, le mainteneur me propose de le remonter à l’équipe ZSH par… mail (ça va revenir souvent le mail, j’adore le mail). C’est donc ce que je fais, et un temps plus tard voilà ma contribution intégrée à ZSH upstream, j’ai donc mon nom dans ZSH. \o/
Conclusion
Ce patch ne sera pas disponible avant un petit moment pour les autres utilisateurs Debian, car il faudra attendre la prochaine release upstream avec un nouveau numéro de version pour que ça puisse arriver dans unstable puis testing. Une solution proposée par le mainteneur en off serait de demander à ce que le patch soit intégré dans une nouvelle version Debian de ZSH, en augmentant la révision Debian de 1, afin de pouvoir faire profiter plus vite tout le monde de cette nouvelle complétion.
Cela demande un effort supplémentaire, et me connaissant je vais essayer de tout faire par moi-même avant en local pour essayer de comprendre comment ajouter un patch dans un paquet source Debian. Mais c’est un bon moyen d’apprendre ! Et puis de toute façon avec cette histoire de confinement c’est pas comme si on avait des trucs plus intéressants à faire.
Si ça se fait, je rajouterai un petit point ici pour vous en notifier.
Update 2020-06-26 : j’ai proposé au mainteneur de ZSH de mettre à jour le paquet en incluant la complétion en avance, étant donné que l’on ne savait pas trop quand cette complétion serait disponible dans une version upstream.
Le patch adapté pour le paquet Debian utilisant quilt est le suivant :
Description: Add completion for dscverify(1) from Debian's devscripts.
Author: Romain Porte <debian@microjoe.org>
Reviewed-by: Daniel Shahaf <danielsh@apache.org>
Bug-Debian: https://bugs.debian.org/953389
Forwarded: https://www.zsh.org/mla/workers/2020/msg00350.html
Applied-Upstream: master, https://sourceforge.net/p/zsh/code/ci/0d7f888945bd487d6458807684883b22dc3b31b8/#diff-1
Last-Update: 2020-03-21
--- a/Completion/Debian/Command/_dscverify
+++ b/Completion/Debian/Command/_dscverify
@@ -0,0 +1,30 @@
+#compdef dscverify
+
+# $ dscverify --version
+# This is dscverify, from the Debian devscripts package, version 2.20.2
+# ...
+
+_dscverify() {
+ local all_opts=(
+ '--help[show the help message and exit]'
+ '--version[show the version + copyright and exit]'
+ '--no-default-keyrings[do not check against the default keyrings]'
+ '*--keyring[add keyring to the list of keyrings used]:keyring:_files -g "*.{kbx,gpg}(-.)"'
+ '(--nosigcheck --no-sig-check -u)'{--nosigcheck,--no-sig-check,-u}'[do not verify the GPG signature]'
+ '--verbose[do not suppress GPG output]'
+ '*:dsc file:_files -g "*.{changes,dsc,buildinfo}(-.)"'
+ )
+
+ local first_only=(
+ '(--no-conf --noconf)'{--no-conf,--noconf}'[do not read the devscripts config file]'
+ )
+
+ if (( CURRENT == 2 )); then
+ all_opts+=($first_only)
+ fi
+
+ _arguments \
+ "$all_opts[@]"
+}
+
+_dscverify "$@"
Celui-ci a été accepté et s’est retrouvé dans la version ZSH 5.8-4, qui est désormais disponible dans testing (voir le tracker).
$ zcat /usr/share/doc/zsh/changelog.Debian.gz | head -n6
zsh (5.8-4) unstable; urgency=medium
[ Romain Porte ]
* Add completion for dscverify. (Closes: #953389)
-- Axel Beckert <abe@debian.org> Sun, 22 Mar 2020 16:12:25 +0100
Portez vous bien ! J’espère pouvoir publier plus souvent ici maintenant que l’on a un peu plus de temps pour soi.