Empaquetez (facilement) votre projet avec upt

Magazine
Marque
GNU/Linux Magazine
Numéro
222
|
Mois de parution
janvier 2019
|
Domaines


Résumé
Les logiciels que nous utilisons sur nos distributions GNU/Linux et *BSD proviennent généralement des dépôts associés à ces dernières. Ils y sont présents, car les mainteneurs de notre OS préféré les ont empaquetés : cela nous évite de devoir recompiler les sources nous-mêmes, de résoudre les problèmes de dépendances ou de parfaire l'intégration avec le reste de notre système. Nous verrons dans cet article comment les empaqueteurs ont réussi à automatiser une partie de leur travail. Nous proposerons ensuite une solution logicielle permettant à toutes les distributions d'empaqueter facilement le code disponible sur des plateformes telles que PyPI, RubyGems ou CPAN.

Body


1. Le travail de l'empaqueteur

1.1 Convertir un paquet

Cet article concerne uniquement les logiciels disponibles sur des dépôts spécifiques à un langage particulier (tels que PyPI, RubyGems, CPAN) et généralement installables grâce aux gestionnaires de paquets associés (tels que pip, gem ou cpanm). Dans ce cas, le travail de l'empaqueteur consiste principalement à convertir un paquet upstream en un paquet downstream.

Prenons l'exemple de Python. La plateforme PyPI fournit, pour chaque projet qui s'y trouve, un tarball par version, ainsi que des métadonnées (numéro de version, description du paquet, etc.). Le mainteneur d'une distribution doit réorganiser le code et les métadonnées afin de se conformer au format utilisé par sa distribution. Ainsi, la bibliothèque requests nécessite, sous Fedora, la création des fichiers suivants :

python-requests/

├── dont-import-OrderedDict-from-urllib3.patch

├── Don-t-inject-pyopenssl-into-urllib3.patch

├── patch-requests-certs.py-to-use-the-system-CA-bundle.patch

├── python-requests.spec

├── Remove-tests-that-use-the-tarpit.patch

├── requests-2.12.4-tests_nonet.patch

└── sources

Fedora choisit de patcher le code, d'où la présence de nombreux patches. Les métadonnées, la liste des dépendances, les instructions spécifiques à l'installation, etc. sont présentes dans le fichier python-requests.spec. Enfin, le fichier sources contient le SHA512 du tarball utilisé.

Sous Debian, le format est différent, mais l'idée est similaire :

requests/debian/

├── changelog

├── clean

├── compat

├── control

├── copyright

├── docs

├── python3-requests.pyremove

├── python-requests.pyremove

├── rules

├── source

│   └── format

├── upstream

│   └── signing-key.asc

└── watch

Le code est ici aussi patché (les fichiers .pyremove listent des modules à supprimer), les dépendances sont spécifiées dans control, etc.

Un dernier exemple, avec les ports d'OpenBSD :

py-requests

├── distinfo

├── Makefile

├── pkg

│   ├── DESCR

│   └── PLIST

Ici, un simple Makefile décrit la procédure d'installation. On retrouve également des métadonnées (liste des fichiers dans PLIST, description du paquet dans DESCR, hachage cryptographique dans distinfo).

1.2 Difficultés

Empaqueter des logiciels est un travail plutôt long et quelque peu fastidieux. Voyons pourquoi.

1.2.1 De multiples sources

Il existe aujourd'hui de nombreux langages, généralement fournis avec un gestionnaire de paquets qui permet d'installer des paquets provenant d'une plateforme spécifique. Il est donc souvent nécessaire de connaître plusieurs environnements logiciels, similaires, mais différents.

1.2.2 De multiples cibles

Les développeurs procèdent rarement eux-mêmes à l'empaquetage de leur code : un développeur Python, par exemple, fera en sorte que sa production soit installable depuis PyPI, avec pip, mais déléguera l'empaquetage pour Debian/Fedora/OpenBSD à d'autres développeurs.

Un même logiciel est donc empaqueté de multiples fois, ce qui crée une grande quantité de travail. Il est toutefois à noter que certains paquets peuvent être partagés entre des distributions (un paquet Debian se porte relativement facilement sur Ubuntu, DragonflyBSD réutilise les ports FreeBSD…).

1.2.3 L'enfer des dépendances

La plupart des logiciels ne sont pas écrits « depuis zéro » : ils utilisent des bibliothèques. Empaqueter un logiciel nécessite donc d'empaqueter ses dépendances, et les dépendances de ses dépendances, etc. Un empaqueteur doit donc souvent créer plusieurs paquets d'un coup. Les bibliothèques requises peuvent déjà exister dans la distribution, mais dans une version trop ancienne : il faut alors les mettre à jour. On rencontre également des dépendances circulaires, qui sont un casse-tête.

1.2.4 Déverminage

Une fois que le paquet est écrit et installé, il se peut que le logiciel empaqueté ne se lance pas, ou présente des bugs. Il faut donc débugger le code, communiquer avec l'upstream et inclure des patches dans le paquet : il se peut qu'ils soient spécifiques à la distribution, ce qui veut dire qu'il faudra les maintenir à tout jamais, sans espoir de les voir inclus upstream.

2. Automatisation

De nombreuses étapes de la création d'un paquet semblent automatisables. Ainsi, créer un répertoire, créer des fichiers, noter la version du logiciel… ne sont pas des tâches passionnantes et sont souvent réalisées mécaniquement. Est-il possible pour les empaqueteurs d'automatiser ces étapes faciles et de se concentrer sur la gestion des dépendances et le débuggage ?

2.1 Disponibilité des métadonnées

Des plateformes telles que PyPI ou RubyGems montrent à leurs utilisateurs énormément de métadonnées sur des pages HTML. Mais elles sont également accessibles en JSON !

Pour les paquets Python, les informations sont disponibles à l'adresse https://pypi.org/pypi/<paquet>/json. Par exemple, pour la bibliothèque requests, on obtient cette sortie (tronquée par souci de lisibilité) :

{

   "info" : {

      "name" : "requests",

      "version" : "2.19.1",

      "summary" : "Python HTTP for Humans.",

      "home_page" : "http://python-requests.org",

      "license" : "Apache 2.0",

      "requires_dist" : [

         "PySocks (!=1.5.7,>=1.5.6); extra == 'socks'",

         "idna (>=2.0.0); extra == 'security'",

         "cryptography (>=1.3.4); extra == 'security'",

         "pyOpenSSL (>=0.14); extra == 'security'",

         "certifi (>=2017.4.17)",

         "urllib3 (<1.24,>=1.21.1)",

         "idna (<2.8,>=2.5)",

         "chardet (<3.1.0,>=3.0.2)"

      ],

   }

   ...

}

On voit ici qu'on retrouve des indications basiques sur le paquet (nom, version, description sommaire…) ainsi que des informations avancées : la liste des dépendances est donnée ! Certaines sont obligatoires (certifi, urllib3, idna et chardet), les autres sont optionnelles.

RubyGems fournit également du JSON (https://rubygems.org/api/v1/gems/<paquet>.json), ainsi que CPAN (https://fastapi.metacpan.org/v1/release/<paquet>). Le format est différent pour chaque outil, mais on y retrouve le même type de métadonnées.

On comprend alors qu'il est sans doute possible d'automatiser une partie non négligeable du travail d'un empaqueteur. Il n'est en effet pas très compliqué d'écrire un script qui prend en paramètre un nom de paquet, construit la bonne URL, récupère le JSON, le parcourt et réécrit les informations obtenues dans le format attendu par la distribution.

2.2 Les outils des distributions

De nombreux développeurs ont eu cette idée, et ils ont écrit plusieurs outils. En voici une liste non exhaustive :


Debian

Fedora

Guix

FreeBSD

OpenBSD

CPAN

dh-make-perl

cpan2rpm

guix import

?

PortGen

NPM

npm2deb

npm2rpm

N/A

?

?

PyPI

pypi2deb

pyp2rpm

guix import

pytoport

PortGen

Ruby

gem2deb

gem2rpm

guix import

?

PortGen

On remarque que Debian et Fedora ont chacun un outil par plateforme upstream. GNU Guix et OpenBSD ont chacun un outil unique, respectivement guix import et PortGen. Cette façon de faire a plusieurs avantages :

  • factoriser une partie du code ;
  • proposer à l'utilisateur une interface unifiée, alors que les outils Debian/Fedora ont tous des options différentes ;
  • proposer à l'utilisateur un comportement unifié : certains outils vont se contenter de créer la source du paquet, d'autres vont procéder à la compilation… Un utilisateur voulant utiliser plusieurs de ces logiciels risque de s'emmêler les pinceaux.

2.3 Le vrai besoin

Ne pourrait-on pas écrire un seul outil qui remplacerait tous ceux vus précédemment ? Voyons comment cela pourrait constituer une amélioration de l'existant.

2.3.1 Interface unique

Un développeur d'une distribution (par exemple Debian) souhaitant empaqueter deux logiciels venant de deux plateformes différentes (par exemple PyPI et RubyGems) doit utiliser deux logiciels différents pour l'aider dans son travail (ici, pypi2deb et gem2deb).

De même, un développeur Python qui voudrait empaqueter lui-même son logiciel pour deux distributions différentes devrait utiliser deux outils différents (pypi2deb et pyp2rpm, par exemple).

Utiliser plusieurs outils différents implique de mémoriser plusieurs lignes de commandes différentes, d'écrire éventuellement un fichier de configuration pour chaque outil, de se souvenir des particularités des uns et des autres… Il serait beaucoup plus simple d'avoir une seule interface qui pourrait gérer toutes les plateformes de distribution de code et toutes les distributions.

2.3.2 Comportement unifié

De la même façon, devoir jongler entre plusieurs outils impose de connaître leurs comportements : pour Debian, il est possible qu'un outil crée le dossier debian/, et pas un autre ; un outil va lancer la construction du .deb, et pas un autre ; etc.

Avoir un seul outil, capable de gérer tous les dépôts upstream et toutes les distributions, permettrait d'avoir toujours le même comportement.

2.3.3 Outil modulaire

Tous ces outils réimplémentent souvent des fonctionnalités identiques. Ainsi, tous les logiciels travaillant avec des paquets Python vont lire le JSON présenté plus haut afin de récupérer des métadonnées intéressantes. Ils vont aussi essayer de trouver les dépendances d'un paquet donné. Et c'est souvent beaucoup plus compliqué qu'il n'y paraît. Elles peuvent être données dans le JSON, mais ce n'est pas toujours le cas. Elles peuvent être trouvées dans le fichier .whl distribué sur PyPI (un fichier zip pouvant être installé par pip), mais pas forcément. Il n'est pas toujours évident de savoir quelles dépendances sont uniquement requises pour les tests, lesquelles sont optionnelles, etc. Cela s'explique par le fait que les pratiques concernant l'empaquetage et les métadonnées des paquets Python ont beaucoup évolué au cours des dernières années. Le lecteur désireux d'en savoir plus pourra visionner la conférence donnée par Joachim Jablon et Stéphane Angel lors de la PyCon FR 2017 [1], dont les slides sont disponibles en ligne [2]. Même récupérer la licence du paquet demande plus d'efforts que simplement lire une ligne du fichier JSON contenant les métadonnées.

De même, tous les outils créant des paquets pour une distribution spécifique vont devoir créer les mêmes dossiers, les mêmes fichiers, et produiront les mêmes bugs.

On pourrait donc éviter de dupliquer énormément de code en écrivant un logiciel modulaire : chaque plateforme upstream aurait son propre module, chaque distribution downstream aurait son propre module, et tous ces modules communiqueraient entre eux.

3. Un outil unique : upt (the Universal Packaging Tool)

3.1 Concept

upt

Fig. 1 : Architecture d'upt.

Comme on peut le voir en figure 1, les informations disponibles sur les plateformes upstream (PyPI, CPAN, RubyGems) sont lues par des modules frontend (upt-pypi, upt-cpan, upt-rubygems), qui les transmettent à upt. Ce dernier les fait ensuite parvenir aux modules backend (upt-fedora, upt-freebsd, upt-guix, upt-nix, upt-openbsd), qui génèrent du code downstream (un fichier .spec, un Makefile, du code Guile, ou un fichier default.nix).

Bien évidemment, il n'est pas nécessaire d'utiliser tous les modules : ainsi, pour empaqueter un logiciel écrit en Python pour Fedora, seuls upt-pypi, upt et upt-fedora sont nécessaires. De même, pour empaqueter un logiciel disponible sur CPAN pour OpenBSD, seuls upt-cpan, upt et upt-openbsd devront être installés.

Cette architecture n'est pas particulièrement originale : les compilateurs fonctionnent de la même façon. Leurs frontends savent parcourir le code d'un langage particulier (C ou C++ par exemple), le transformer en une représentation interne, qui est utilisée par leurs backends afin de générer du code assembleur pour une plateforme donnée (x86, x64, MIPS…). De même, pandoc [3] sait convertir des documents d'un langage de balisage à un autre grâce à une architecture similaire.

Terminons la présentation de l'architecture en notant que les modules upt ont chacun leur propre dépôt git. Il est ainsi possible de créer un nouveau module sans devoir le faire valider par l'upstream du projet upt.

3.2 Utilisation

Installer upt se fait facilement depuis PyPI :

$ pip install upt

On peut ensuite installer les modules dont nous avons besoin un par un :

$ pip install upt-pypi

$ pip install upt-fedora

...

On peut aussi installer upt et tous les frontends disponibles :

$ pip install upt[frontends]

Ou installer upt et tous les backends disponibles :

$ pip install upt[backends]

Ou encore upt et tous les modules disponibles :

$ pip install upt[frontends,backends]

Il est ensuite possible de vérifier quels modules sont disponibles :

$ upt list-frontends

cpan

pypi

rubygems

$ upt list-backends

fedora

freebsd

guix

nix

openbsd

Essayons maintenant d'empaqueter upt pour FreeBSD, depuis PyPI :

$ upt package --frontend pypi --backend freebsd -o /tmp/upt upt

[INFO ] [Backend] Creating /tmp/upt/py-upt

[INFO ] [Backend] Creating /tmp/upt/py-upt/Makefile

[INFO ] [Backend] Creating /tmp/upt/py-upt/pkg-descr

[INFO ] [Backend] Creating /tmp/upt/py-upt/distinfo

make: Entering directory '/tmp/upt/py-upt'

Makefile:20: *** missing separator. Stop.

make: Leaving directory '/tmp/upt/py-upt'

[WARNING ] [Backend] make makesum failed. Not generating /tmp/upt/py-upt/distinfo

$ tree /tmp/upt/py-upt/

/tmp/upt/py-upt/

├── Makefile

└── pkg-descr

0 directories, 2 files

On voit que le backend upt-freebsd a réussi à créer les fichiers Makefile et pkg-descr, mais qu'il n'a pas su générer distinfo. C'est normal : la création de ce fichier se fait via la commande make makesum, lancée depuis l'arbre des ports FreeBSD. Celle-ci échoue, car la commande est ici lancée sur Debian, mais fonctionnerait sur une machine FreeBSD.

$ cat /tmp/upt/py-upt/Makefile

# $FreeBSD$

PORTNAME= upt

DISTVERSION= 0.4.1

CATEGORIES= XXX python

MASTER_SITES= CHEESESHOP

PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}

MAINTAINER= python@FreeBSD.org

COMMENT= Package software from any package manager to any distribution

LICENSE= BSD3CLAUSE

LICENSE_FILE= ${WRKSRC}/XXX

RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}spdx-lookup>0:XXX/py-spdx-lookup@${FLAVOR}

USES= python

USE_PYTHON= autoplist distutils

.include <bsd.port.mk>

Le Makefile généré n'est pas prêt à être utilisé : certaines informations n'ont pas pu être obtenues par upt, qui a inséré la chaîne de caractères XXX afin de signifier au mainteneur ce qu'il doit corriger. Ainsi upt n'a pas su déterminer à quelle catégorie de ports ce paquet appartient, ni le fichier dans lequel est contenu la licence, ni la catégorie de l'unique dépendance de ce paquet.

Il reste donc un peu de travail au mainteneur, mais beaucoup moins que s'il avait dû tout écrire lui-même ! Les outils qu'upt entend remplacer ne sont en général pas non plus capables de générer un paquet complètement valide, qui ne nécessite aucune retouche.

3.3 Ajouter un module

Un des intérêts de l'architecture modulaire d'upt est de permettre d'ajouter (relativement) facilement de nouveaux frontends ou backends. Le projet met à disposition un modèle [4] au format cookiecutter [5]. Si nous voulions créer un backend pour Arch Linux, il serait recommandé de procéder comme suit :

$ cookiecutter https://framagit.org/upt/cookiecutter-upt

project_name []: upt-archlinux

project_slug [upt_archlinux]:

author []: John Doe

email []: john@doe.org

short_description []: Arch Linux backend for upt.

url [https://framagit.org/upt/upt-archlinux]:

Select license:

1 - BSD-3

2 - other

Choose from 1, 2 (1, 2) [1]: 1

Select kind:

1 - backend

2 - frontend

Choose from 1, 2 (1, 2) [1]: 1

entrypoint_name [archlinux]:

main_class_name [ArchlinuxBackend]:

Initialized empty Git repository in /tmp/upt-archlinux/.git/

[master (root-commit) 76b7a4f] Initial commit.

 12 files changed, 192 insertions(+)

 create mode 100644 .gitignore

 create mode 100644 CHANGELOG

 create mode 100644 LICENSE

 create mode 100644 MANIFEST.in

 create mode 100644 README.md

 create mode 100644 setup.cfg

 create mode 100644 setup.py

 create mode 100644 tox.ini

 create mode 100644 upt_archlinux/__init__.py

 create mode 100644 upt_archlinux/templates/base.tmpl

 create mode 100644 upt_archlinux/tests/__init__.py

 create mode 100644 upt_archlinux/upt_archlinux.py

Il suffit de répondre à quelques questions afin de créer automatiquement un dépôt git contenant un squelette de module. Il n'y a ensuite plus qu'à compléter le code du module. Le README du projet upt [6] contient des informations au sujet de l'API d'upt, que les lecteurs intéressés pourront consulter.

4. Une autre approche : fpm

L'auteur d'upt (qui est aussi le rédacteur de cet article) a bien entendu fait un état de l'art, et a découvert fpm [7] dont le concept est similaire à celui d'upt.

Cet exemple tiré de la documentation officielle montre comment utiliser fpm :

% fpm -s python -t rpm pyramid

Trying to download pyramid (using easy_install)

Searching for pyramid

Reading http://pypi.python.org/simple/pyramid/

Reading http://docs.pylonshq.com

Reading http://docs.pylonsproject.org

Best match: pyramid 1.0

...

Created /home/jls/python-pyramid-1.0.noarch.rpm

Notons que fpm, écrit en Ruby, supporte énormément d'options pour chacun de ses modules, afin de permettre aux utilisateurs de créer des paquets aux petits oignons.

Comme upt, fpm a une approche modulaire et sait même gérer plus de sources et de cibles qu'upt ! La principale différence est qu'il génère un paquet binaire plutôt qu'un paquet source. Par exemple, dans le cas de Fedora, il pourra créer un fichier RPM, mais ne créera pas le fichier .spec associé [8]. C'est donc un outil très utile pour créer un paquet installable par le gestionnaire de votre distribution, mais il ne permet pas vraiment de réaliser le travail d'un empaqueteur.

Conclusion

Nous avons présenté dans cet article le travail des empaqueteurs, et les outils qu'ils utilisent actuellement pour automatiser une partie de ce travail. Nous avons ensuite défendu l'idée qu'un outil modulaire pourrait avantageusement remplacer la pléthore d'outils spécifiques actuellement utilisés. Enfin, nous avons décrit l'architecture d'un tel outil, et présenté quelques exemples d'utilisation d'upt. De nombreux modules (backends comme frontends) restent cependant encore à écrire avant que ce logiciel puisse vraiment être un outil d'empaquetage universel. Si l'absence d'un module vous empêche d'utiliser upt, n'hésitez pas à venir en discuter sur #upt-packaging, sur Freenode.

Références

[1] Programme de la PyConFR, « Les aventuriers du packaging perdu » : https://www.pycon.fr/2017/programme.html#les-aventuriers-du-packaging-perdu

[2] Diapositives - « Les aventuriers du packaging perdu » : https://twidi.github.io/python-packaging-talk/fr.html

[3] Site officiel de pandoc : https://pandoc.org/

[4] Dépôt git de cookiecutter-upt : https://framagit.org/upt/cookiecutter-upt

[5] Documentation de cookiecutter : https://cookiecutter.readthedocs.io/en/latest/

[6] Fichier README d'upt : https://framagit.org/upt/upt/blob/master/README.md

[7] Site officiel de fmp : https://fpm.readthedocs.io/en/latest/

[8] Discussion au sujet du comportement de fpm : https://github.com/jordansissel/fpm/issues/1507#issuecomment-411390171


Sur le même sujet

Découvrir SQL avec SQLite

Magazine
Marque
Linux Pratique
Numéro
116
|
Mois de parution
novembre 2019
|
Domaines
Résumé

Grâce au langage SQL (Structured Query Language), il est aisé de rédiger des requêtes pour définir la structure d’une base de données et manipuler son contenu. Partons à la découverte de ces sujets à l’aide de SQLite, un moteur de base de données au nom trompeur, car s’il fait preuve de modestie, il constitue un produit performant et polyvalent.

Élévation de privilèges sur macOS avec CVE-2018-4193

Magazine
Marque
MISC
Numéro
106
|
Mois de parution
novembre 2019
|
Domaines
Résumé

Cet article explique comment exploiter la CVE-2018-4193, une élévation de privilèges affectant les versions de macOS inférieures à 10.13.5, en moins de 10 secondes. Les différents prérequis nécessaires à la compréhension de l’exploit seront détaillés de sorte qu’aucune connaissance préalable de macOS ne soit nécessaire, ce qui permet d’aborder l’exploitation de vulnérabilités dans les démons macOS en général.

AWX, une WebUI pour vos jobs Ansible

Magazine
Marque
Linux Pratique
Numéro
116
|
Mois de parution
novembre 2019
|
Domaines
Résumé

Ansible c’est cool [1], ça vous apporte rapidité de déploiement, une grande souplesse grâce à ses modèles et bien d’autres avantages. Seulement, vous ne pouvez pas le laisser entre toutes les mains, l'oubli d’une option lors d'un déploiement et c’est tout votre infra qui risque d'être impactée.Le moment tant redouté est-il arrivé ? Êtes-vous devenu le Single Point of Failure de toute l'infrastructure ? Allez-vous devoir vous charger de tous les déploiements, et ce, jusqu’à ce que mort s’ensuive ? Non, non, non et non ! Vous n'allez pas vous laisser faire ! Et quoi de mieux pour mettre le pied à l'étrier de tout le monde qu'une simple WebUI ?

Du Dev au Sysadmin : Apprenez à concevoir et distribuer vos applications sur plusieurs plateformes avec CMake

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
105
|
Mois de parution
novembre 2019
|
Domaines
Résumé

Vous avez souvent réalisé des applications que vous aimeriez tester et partager avec vos collègues, mais vous êtes toujours coincés au niveau de l’organisation des fichiers sources et du déploiement ? Vous tombez pile sur l'article qu’il faut pour résoudre ces problèmes.

Isolation de conteneurs : You Are NOT Safe

Magazine
Marque
GNU/Linux Magazine
Numéro
231
|
Mois de parution
novembre 2019
|
Domaines
Résumé

« We won’t be able to pretend that we can protect ourselves anymore. It’s a huge danger, a gigantic risk, but it’s worth it, if only we can learn to take care of each other, then this awesome destructive new connection won’t isolate us. It won’t leave us in the end so totally alone. »Cet extrait du manifeste « You are NOT safe » de Ryan Ray dans la série Halt and Catch Fire n'a jamais été autant d'actualité !

Par le même auteur

Empaquetez (facilement) votre projet avec upt

Magazine
Marque
GNU/Linux Magazine
Numéro
222
|
Mois de parution
janvier 2019
|
Domaines
Résumé
Les logiciels que nous utilisons sur nos distributions GNU/Linux et *BSD proviennent généralement des dépôts associés à ces dernières. Ils y sont présents, car les mainteneurs de notre OS préféré les ont empaquetés : cela nous évite de devoir recompiler les sources nous-mêmes, de résoudre les problèmes de dépendances ou de parfaire l'intégration avec le reste de notre système. Nous verrons dans cet article comment les empaqueteurs ont réussi à automatiser une partie de leur travail. Nous proposerons ensuite une solution logicielle permettant à toutes les distributions d'empaqueter facilement le code disponible sur des plateformes telles que PyPI, RubyGems ou CPAN.

Faut s’démener au FOSDEM !

Magazine
Marque
GNU/Linux Magazine
Numéro
213
|
Mois de parution
mars 2018
|
Résumé
Le FOSDEM (Free and OpenSource Developers European Meeting) est tellement incontournable qu’une part non négligeable des auteurs de GLMF s’y rend chaque année. De nombreuses mains et points de vue ont donc participé à ce compte-rendu, pour vous faire part du foisonnement de ce week-end intense.

Étendez Pandoc avec Lua

Magazine
Marque
GNU/Linux Magazine
Numéro
199
|
Mois de parution
décembre 2016
|
Domaines
Résumé
Il est parfois nécessaire de convertir un fichier d'un langage de balisage vers un autre : de Markdown vers du HTML, d'Org-mode vers LaTeX, etc. Pandoc est un outil permettant ce type de conversion, et il est capable de gérer un nombre impressionnant de formats différents. Que faire si l'on souhaite utiliser un format ésotérique inconnu de Pandoc ? Il est possible de l'étendre en Lua !

Filtrez vos courriels avec Python

Magazine
Marque
GNU/Linux Magazine
Numéro
195
|
Mois de parution
juillet 2016
|
Domaines
Résumé
Vous utilisez sans doute IMAP (Internet Message Access Protocol) pour lire votre courrier. N'avez -vous jamais eu envie d'écrire un script utilisant ce protocole afin d'effectuer des opérations courantes (marquer un fil de discussion comme lu, le déplacer, etc.) automatiquement ? C'est possible grâce à Python et son module imaplib, qui fait partie de la bibliothèque standard.