Ma première contribution !

Bonjour à tous,

Contribuer à un logiciel libre, c’est quelque chose que j’ai en tête depuis que j’étudie l’informatique. L’idée d’apporter mes connaissances et mes compétences à un logiciel, simplement pour le plaisir et la fierté d’avoir apporté sa pierre à l’édifice, est une idée qui me plaît beaucoup. Seulement, trouver comment contribuer et produire un bout de code à la hauteur des attentes du logiciel est loin d’être évident.

Mais ça y est ! C’est un peu un rêve de gosse qui devient réalité : mes premières lignes de code vont être publiées dans un logiciel open-source !

List.init, bientôt présente dans OCaml !

Tout d’abord, laissez-moi vous donner un peu de contexte. Bon, vous savez tous que j’adore OCaml. Jusque-là, rien de nouveau sous le soleil.

Lorsque vous installez OCaml, le langage est livré avec une suite logicielle complète : compilateurs, interpréteurs, générateur de documentation, gestionnaire de paquets, outil de build automatisé, et bibliothèque standard. Néanmoins, la bibliothèque standard d’OCaml (autrefois appelée Pervasives) est loin de faire l’unanimité au sein de la communauté. De ce fait, on trouve plusieurs projets d’extensions de la bibliothèque standard d’OCaml. À titre personnel, j’utilise la bibliothèque Core de JaneStreet, que je trouve vraiment complète et bien fichue.

L’une des (nombreuses) fonctionnalités présentes dans Core et absentes de Pervasives est la fonction List.init. Cette fonction permet d’initialiser une liste de taille n en mappant chaque élément avec une fonction donnée. Quelques examples :

List.init 10 (fun x -> x);;
- : int list = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
List.init 10 string_of_int;;
- : string list = ["0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"]

J’ai remarqué l’absence de cette fonction dans Pervasives en répondant à une question sur StackOverflow. Du coup, j’ai posé ma propre question pour avoir l’avis de personnes plus habituées que moi à Pervasives.

Quand on m’a répondu que ça n’existait pas, j’ai pensé

Ben, c’est vachement dommage. En plus, elle est facile comme tout comme fonction. Tiens, je vais la faire moi-même !

GitHub, l’outil idéal du contributeur

Aujourd’hui, interagir avec les développeurs de tel ou tel logiciel libre est vraiment devenu d’une simplicité déconcertante. Bon, une connaissance basique de Git est nécessaire, mais quel développeur peut ne pas connaître Git en 2017 ?

Bref, voici en gros mon implémentation initiale de List.init:

let init n f =
  if n < 0 then invalid_arg "List.init"
  else let rec init_aux acc i =
    if i >= n then acc
    else init_aux ((f i)::acc) (i+1)
  in rev (init_aux [] 0)

Je vous passe les détails techniques, mais en gros, la fonction… fonctionne. (Ba-dum tss !)

Le fork

Afin de proposer cette fonction aux mainteneurs officiels du projet OCaml, la première chose à faire est de forker leur dépôt GitHub. En gros, cela revient à créer une copie personnelle du dépôt, copie sur laquelle on peut faire ce que l’on veut sans affecter le dépôt original.

Vous pouvez forker n’importe quel dépôt en cliquant juste là.

Ensuite, vous pouvez cloner sur votre machine votre copie du dépôt avec Git :

$ git clone https://github.com/Richard-Degenne/ocaml

À partir de là, il vaut mieux créer une branche spécifique sur laquelle travailler :

$ git checkout -b list-init

Et voilà, tout est prêt pour implémenter la fonction !

La pull request

Une fois le codé poussé sur la branche de mon dépôt forké, la prochaine consiste en l’ouverture d’une pull request. Sur GitHub, une pull request permet de demander le merge d’une branche. Ici, je crée une pull request sur le dépôt officiel d’OCaml pour leur dire « Regardez ce que j’ai fait, est-ce que vous pouvez le merger dans le dépôt, s’il vous plait ? ».

Pour créer une nouvelle pull request, cliquez juste là.

Sélectionnez ensuite quelle branche vous souhaiter merger (dans notre cas, list-init, et ajoutez un message pour décrire de quoi il s’agit. La plupart des dépôts fournissent un ensemble de règles quant à la création de pull requests ; en général, on trouve ces informations dans le fichier README ou CONTRIBUTING du dépôt.

Vous pouvez retrouver ma pull request juste ici.

La review, ou le baptême du feu

Maintenant, la balle est dans le camp des mainteneurs du dépôt. C’est à eux d’aller jeter un œil à votre code pour vérifier s’il est apte à être intégré dans la base de code du logiciel. Dans un premier temps, les outils de Continuous Integration vérifient que les tests unitaires passent toujours. Ensuite, les mainteneurs vont faire des remarques ou poser des questions. Parfois, il s’agit simplement de mise en forme, et parfois, des questions plus compliquées sont soulevées.

Dans mon cas, deux problématiques sont apparues à la lumière des remarques faites sur mon code : la tail-recursiveness et l’ordre d’évaluation des termes. Les débats ont fini par décider, et je n’ai eu qu’à modifier le code sur mon dépôt pour que la pull request se mette à jour.

Oui, le débat a été assez long.

Et, finalement, ma pull request a été acceptée ! Ce qui signifie que, lorsque OCaml 4.05.0 sera publié, la fonction List.init que j’ai écrite sera disponible ! Et ça, c’est quand même la classe. 🙂

La suite

Cette première expérience marque, je l’espère, le début d’une longue série. Je me rends compte que mes connaissances et les outils qui sont à ma disposition me permettent de contribuer à construire des logiciels comme OCaml. La liste des choses à faire (que ce soit sur OCaml ou sur d’autres projets) est longue comme le bras, et je vais prendre le temps de participer aux discussions ainsi qu’aux développements autour de projets qui me tiennent à cœur.

Et peut-être qu’un jour, j’aurai le temps et les connaissances de lancer un projet comme ceux-là moi-même !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *