FreeToGenerate.com

Le circonflexe et le tilde ne figurent pas dans la spécification SemVer. Cherchez-y « caret », « tilde » ou « range » : rien. Cette syntaxe est celle de npm.

Cela change la façon dont la plage est construite, et pas seulement dont elle est testée : une plage partielle comme ^1 devient >=1.0.0-0 au lieu de >=1.0.0.

Refusée, et uniquement parce que c’est une préversion

Toutes les bornes sont respectées. Le refus vient de ce qu’une préversion n’entre dans une plage que si un comparateur nomme le même majeur.mineur.correctif — et aucun ne le fait ici. C’est la règle derrière « pourquoi ma bêta ne correspond pas ».

>=1.2.3 <2.0.0-0

Les plages sont développées en comparateurs simples avant toute comparaison. Les bornes supérieures portent -0 afin qu’une préversion de la version suivante ne puisse pas s’y glisser.

  • >=1.2.3vérifié
  • <2.0.0-0vérifié

La version, en morceaux

Majeur
1
Mineur
2
Correctif
4
Préversion
beta.1

Rien de cette syntaxe de plages ne figure dans la spécification SemVer

semver.org définit le format des versions et les règles disant laquelle est la plus récente, et s’arrête là : les mots « caret », « tilde » et « range » n’y apparaissent pas. La syntaxe ^ ~ || et les plages en x viennent de npm ; c’est une convention posée sur la norme, non une partie de celle-ci.

Aussi disponible en : English · Español · Português · العربية

Vérificateur semver

Si une version satisfait une plage, les comparateurs en lesquels cette plage se développe réellement, et une réponse nette quand une préversion est refusée.

Qu’est-ce que le versionnage sémantique ?

Le versionnage sémantique est la convention selon laquelle un numéro de version est fait de trois nombres porteurs de sens : majeur.mineur.correctif. On incrémente le correctif pour une réparation qui ne change rien d’autre, le mineur pour un ajout compatible, et le majeur lorsque du code existant va casser. Un tiret introduit une préversion — 2.0.0-rc.1 — et un plus introduit des métadonnées de compilation, entièrement ignorées lors des comparaisons.

La spécification de semver.org définit ce format et définit la précédence : laquelle de deux versions est la plus récente, y compris la règle voulant qu’une préversion se place toujours sous la version qu’elle précède. 1.0.0-alpha vient avant 1.0.0, et non après.

Ce que la spécification ne définit pas, ce sont les plages. Cherchez dans son texte « caret », « tilde » ou « range » : vous ne les trouverez pas. La syntaxe ^ ~ || et les plages en x dont tous les manifestes débordent viennent de npm, et cette page teste une version contre elle — en étant claire sur la moitié qui est la norme et celle qui est une convention posée par-dessus.

Comment s’en servir

  1. Mettez une version dans la première case et une plage dans la seconde. 1.2.4 contre ^1.2.3, ou une préversion comme 1.2.4-beta.1, ou une plage aussi compliquée que >=1.2.0 <2.0.0 || ^3.
  2. Lisez le développement, pas seulement le verdict. Toute plage devient des comparateurs simples avant la moindre comparaison, et chacun est accompagné de son résultat. Une réponse surprenante devient généralement évidente une fois les bornes écrites.
  3. Essayez la case des préversions si une bêta est refusée. Elle montre ce qui change — et elle change la plage elle-même, non la seule comparaison.

Le circonflexe veut dire trois choses différentes

On décrit le circonflexe comme « compatible avec », ce qui va très bien jusqu’à ce qu’on remarque qu’il se comporte différemment selon lequel des premiers nombres vaut zéro. ^1.2.3 autorise tout jusqu’à 2.0.0 exclu. ^0.2.3 n’autorise que des correctifs et s’arrête à 0.3.0. Et ^0.0.3 n’autorise absolument rien au-delà de 0.0.3 lui-même.

C’est délibéré : avant 1.0.0, la convention veut que tout puisse casser, alors le circonflexe se resserre pour compenser. La conséquence est de celles qu’on n’attend pas : en dessous de 1.0.0, ^0.2.3 et ~0.2.3 sont la même plage. La distinction sur laquelle tout le monde s’appuie, entre « autoriser les mises à jour mineures » et « autoriser les correctifs », disparaît purement et simplement, faute de mise à jour mineure que le circonflexe accepterait.

Un détail de plus, visible dans le développement ci-dessus : les bornes supérieures s’écrivent <2.0.0-0 et non <2.0.0. Sans ce -0 final, une préversion du majeur suivant — 2.0.0-rc.1 — se placerait sous 2.0.0 et se faufilerait dans une plage censée s’arrêter avant.

Pourquoi votre bêta ne correspond pas

C’est la question qui amène presque tout le monde sur un vérificateur semver, et l’explication habituelle n’est pas tout à fait juste. Une préversion est exclue d’une plage même lorsqu’elle se situe confortablement à l’intérieur des bornes : 1.2.4-beta.1 satisfait à la fois >=1.2.3 et <2.0.0-0, et ^1.2.3 la refuse malgré tout.

La règle est souvent énoncée comme « sauf si la plage mentionne elle-même une préversion », et c’est trop lâche. Ce qu’il faut, c’est qu’un comparateur de la plage porte le même majeur.mineur.correctif. Ainsi ^1.2.3-alpha refuse toujours 1.2.4-beta.1 : cette plage nomme bien une préversion, mais sur 1.2.3, alors que la version testée est 1.2.4. Passez la version à 1.2.3-beta.1 et elle est acceptée.

Le raisonnement est qu’une préversion de 1.2.4 n’a pas promis de se comporter comme 1.2.4 : accepter une plage ne devrait donc pas vous embarquer en silence du code non publié pour des versions que vous n’avez jamais nommées. Quand vous le voulez tout de même, la case des préversions est la porte de sortie — et il vaut la peine de savoir qu’elle change la construction de la plage et non la comparaison. Sous elle, ^1 devient >=1.0.0-0 tandis que ^1.0.0 reste >=1.0.0, car seule une borne remplie à partir d’une version partielle est abaissée.

Limites honnêtes

Ceci confronte des chaînes de version à des chaînes de plage, et rien d’autre. L’outil ignore ce qui est publié : il ne peut donc pas vous dire quelle version une plage installerait aujourd’hui, ni si une mise à jour cassera votre code — le versionnage sémantique est une promesse de celui qui publie, non une garantie que quiconque vérifie. Un majeur qui ne touche à rien de ce que vous utilisez est inoffensif ; un correctif peut malgré tout vous casser.

La grammaire de plages implémentée ici est celle de npm, de loin la plus répandue mais pas la seule. D’autres écosystèmes écrivent des idées voisines autrement, et une plage recopiée depuis l’un d’eux sera soit refusée ici, soit — pire — comprise différemment. Les plages agrémentées d’extras propres à npm qui sortent de la grammaire des versions — une URL git ou un chemin local à la place d’une version — ne sont pas des plages en ce sens et ne sont pas traitées.

Cette grammaire n’ayant pas de spécification, le critère de justesse est ici l’accord avec l’implémentation de référence plutôt que la conformité à un document. Le moteur est vérifié contre elle sur 1 680 couples version/plage sans le moindre désaccord, et séparément contre les règles de précédence de la spécification, qui, elles, existent.

Pourquoi est-ce gratuit ?

Parce que cela ne coûte rien à faire tourner. L’analyse et la comparaison ont lieu dans votre navigateur ; aucune version, plage ou manifeste n’est envoyé, et il n’y a pas de compte.

Les règles de précédence viennent de la spécification et la grammaire des plages de l’implémentation qui la définit en pratique, les tests étant conservés à côté du code.