Il y a des tas de manières d’indiquer la version d’un logiciel.
Ubuntu utilise l’année et le mois, à l’envers : la 14.04 indique une version sortie en avril 2014.
Avant la 1.2, angular utilisait les versions paires pour signifier la stabilité, et impaire pour l’instabilité.
Quelques projets utilisent des numéros de branche Git ou Svn.
Certains utilisent des noms du genre “kangourou-cosmique” pour marquer le coup.
Et d’autres mélangent plusieurs techniques.
En Python, la méthode recommandée est nommée SemVer, pour Semantic Versioning.
Explications
Tout est basé sur la notion d’API publique. Si vous ne vous souvenez pas de ce qu’est une API publique, c’est par ici.
Une bibliothèque versionnée avec SemVer doit clairement documenter toute son API publique pour dire : voici les bouts de codes que vous pouvez utiliser sans risque.
Beaucoup de devs ne font pas, tout comme on fait souvent du REST non pur, on fait souvent du SemVer non pur, mais je vous le dis sinon des puristes viendront jouer de la moustache en commentaires.
Le principe est simple : votre versioning est noté x.y.z
, x
, y
et z
étant des entiers positifs. A moins que le nombre soit 0
, aucun nombre ne doit commencer par 0
.
Le x
représente une version majeure, qui introduit au moins un changement incompatible dans l’API publique.
Le y
représente une version mineure, qui introduit au moins une nouvelle fonctionnalité dans l’API publique.
Le z
représente une correction de bug ou un changement dans l’API privée.
Et c’est tout.
En pratique
Si vous réparez un bug, z
augmente de 1
.
Ex : 1.3.4
devient 1.3.5
Si vous introduisez un nouveau paramètre optionnel, une fonction outil indépendante, un nouvel attribut public, y
augmente de 1
, et z
est remis à 0 :
Ex : 1.3.4
devient 1.4.0
Si une fonction retourne maintenant ne serait-ce qu’un tuple au lieu de précédemment une liste, x
augmente de 1
, y
et z
sont remis à 0 :
Ex : 1.3.4
devient 2.0.0
FAQ
Le numéro de version va monter très vite non ?
On ne change le numéro de version que pour une version publiée. Si vous faites plein de petits changements mais que vous ne déclarez pas ce nouveau code comme la dernière version officielle, pas besoin de changer de version : vous êtes encore en développement.
N’oubliez pas aussi que c’est VOTRE job de vous assurez que votre programme reste compatible. Faites des adapters, des alias, introduisez les fonctionnalités de manière optionnelle, depréciation à l’avance… Il y a des moyens de faire ça proprement.
C’est quand même over chiant pour une lib qui vient de sortir et que personne n’utilise, non ?
Jusqu’à la version 1.0.0
, le SemVer ne s’applique pas. En 0.y.z
, on peut faire du freestyle.
Mais si je suis en beta ?
On peut signaler des informations supplémentaires en mettant un tiret après son versioning. Le style est libre mais la convention est généralement x.y.z-status
. Ex : 1.3.3-alpha
, 1.3.3-beta
, 1.3.3-rc1
, etc.
Attend, je fais une release parfaitement compatible, mais avec une fonction publique qui ne retourne plus 1
mais True
, je vais pas bumper pour ça quand même ?
Si. Si vous ne voulez pas le faire, mettez le dans une branche à part, et attendez une release plus grosse pour introduire ce changement.
J’ai une correction de bug qui introduit une changement incompatible dans l’API publique, je fais quoi ?
On bump. Ça n’arrive pas si souvent que ça qu’un bug change l’API publique, faut pas charrier.
Ouais, genre tu le fais…
Non, je ne fais pas du SemVer pur. Mais sur une lib qui est très utilisée, c’est un système indispensable. Si j’avais la responsabilité de pondre Django, ouais, je ferais du SemVer pur.
Ok, je l’ai fais mais j’ai pas l’impression d’y gagner quoi que ce soit.
Le bénéfice n’est pas pour l’auteur, mais pour les utilisateurs. Si un autre utilisateur à votre lib comme dépendance, il peut déclarer dans son fichier setup.py:
requires=['votrelib>=1.3.1<2.0.0'] |
Ainsi il est certain que ça ne pétera pas si vous faites votre boulot correctement car la lib installée par pip sera toujours dans une version entre la 1.3.1 qu’il sait compatible, jusqu’à la 2.0.0 qui sera incompatible.
Petite question : est-ce que ça vaut le coup de versionner des projets perso qui ne sont pas destinés à être rendus publics ?
Moi je le fais si j’ai un setup.py, sinon non.
Pour les numeros de version, il y a aussi la methode TeX:
“À partir de la version 3, TeX a utilisé un système idiosyncratique de numérotation de version, les mises à jour étant indiquées en ajoutant un chiffre supplémentaire après le point décimal, le numéro de version approchant ainsi asymptotiquement le nombre pi. La version actuelle de TeX est la 3.14159265, la dernière mise à jour datant du 12 janvier 2014″ (wikipedia)
Juste un truc que je trouve dommage: l’interdiction de mettre un “0” non significatif.
En effet, j’ai l’habitude de stocker différentes versions d’un logiciel (on va dire en général 2 ou 3), chaque version se trouvant archivée dans un beau “tgz” bien rangé dans son petit dossier associé au logiciel. Ainsi si par exemple je trouve la version 12.18 trop différente, ou qu’un truc qui me plaisait n’y est plus, ou toute autre raison (voire même bug parce que j’ai installé War Thunder et que le cas n’avait pas été prévu et que les deux sont incompatibles) ben je n’ai pas de soucis pour désinstaller et réinstaller la 12.17.
Mais c’est malheureux, quand je liste mon dossier, de voir que postgresql-9.1.10.tar.gz se trouve placé après postgresql-9.1.1.tar.gz et avant postgresql-9.1.2.tar.gz…
Alors bon, Chez-moi je mets au moins le chiffre “z” sur deux digits.Ainsi la version 9.1.01 se trouve listée avant la 9.1.02 et la 9.1.10 se trouve après la 9.1.09…
@Fred : si l’affichage des fichiers est fait dans une console, il y a l’option -v de
ls
qui permet de prendre les numéros de versions en compte :$ ls
postgresql-9.1.10.tar.gz postgresql-9.1.1.tar.gz postgresql-9.1.2.tar.gz
$ ls -v
postgresql-9.1.1.tar.gz postgresql-9.1.2.tar.gz postgresql-9.1.10.tar.gz
Dans nautilus (l’explorateur de fichier de Gnome), ça apparait dans cet ordre aussi (en tout cas, sur ma machine, là maintenant tout de suite).
Je ne connais pas le comportement sur d’autres systèmes (et ça ne m’intéresse pas vraiment).
Sur l’histoire des versions beta ou rc ou autre : 1.3.3-rc1 est donc une version inférieur à 1.3.3 ?
Oui.
sur le changement de version majeure suite à une rupture d’API, sais-tu s’il existe un outil permettant de documenter plus ou moins automatiquement l’API d’une librairie ? Lorsque un projet évolue, c’est pas forcément évident d’identifier si une API à bougé ou non, surtout si on développe à plusieurs ou sur une API de taille conséquente. T’as un truc pour t’y retrouver ?
Les test unitaires sont faits exactement pour ça.