También disponible en: English · Português · Français · العربية
Comprobador de semver
Si una versión cumple un rango, los comparadores en los que ese rango se expande de verdad, y una respuesta clara cuando se rechaza un prelanzamiento.
¿Qué es el versionado semántico?
El versionado semántico es el convenio de que un número de versión son tres números con significado: mayor.menor.parche. Se sube el parche para un arreglo que no cambia nada más, el menor para algo añadido de forma compatible, y el mayor cuando el código existente se va a romper. Un guion introduce un prelanzamiento (2.0.0-rc.1) y un signo más introduce metadatos de compilación que se ignoran por completo al comparar.
La especificación de semver.org define ese formato y define la precedencia: cuál de dos versiones es más nueva, incluida la regla de que un prelanzamiento siempre va por debajo de la versión que precede. 1.0.0-alpha va antes de 1.0.0, no después.
Lo que la especificación no define son los rangos. Busca en su texto «caret», «tilde» o «range» y no los encontrarás. La sintaxis ^ ~ || y los rangos con x de los que están llenos todos los manifiestos vienen de npm, y esta página comprueba una versión contra ella, dejando claro qué mitad es el estándar y qué mitad es un convenio encima.
Cómo usarlo
- Pon una versión en la primera casilla y un rango en la segunda. 1.2.4 contra ^1.2.3, o un prelanzamiento como 1.2.4-beta.1, o un rango tan complicado como >=1.2.0 <2.0.0 || ^3.
- Lee la expansión, no solo el veredicto. Todo rango se convierte en comparadores simples antes de comparar nada, y de cada uno se indica si se cumple. Una respuesta sorprendente suele volverse obvia en cuanto los límites están escritos.
- Prueba la casilla de prelanzamientos si te rechaza una beta. Enseña qué cambia, y cambia el rango en sí, no solo la comparación.
El circunflejo significa tres cosas distintas
Al circunflejo se le describe como «compatible con», y va bien hasta que notas que se comporta distinto según qué número inicial sea cero. ^1.2.3 permite cualquier cosa hasta 2.0.0 sin incluirla. ^0.2.3 solo permite versiones de parche y se detiene en 0.3.0. Y ^0.0.3 no permite absolutamente nada más allá de 0.0.3.
Es deliberado: antes de 1.0.0 el convenio es que cualquier cosa puede romperse, así que el circunflejo se aprieta para compensar. La consecuencia es una que casi nadie espera: por debajo de 1.0.0, ^0.2.3 y ~0.2.3 son el mismo rango. La distinción en la que todo el mundo se apoya entre «permite actualizaciones menores» y «permite actualizaciones de parche» simplemente desaparece, porque no hay actualización menor que el circunflejo fuera a permitir.
Un detalle más que se ve en la expansión de arriba: los límites superiores se escriben <2.0.0-0 y no <2.0.0. Sin ese -0 final, un prelanzamiento de la siguiente versión mayor (2.0.0-rc.1) quedaría por debajo de 2.0.0 y se colaría en un rango que debía pararse antes.
Por qué tu beta no encaja
Esta es la pregunta que trae a casi todo el mundo a un comprobador de semver, y la explicación habitual no es del todo correcta. Un prelanzamiento queda excluido de un rango aunque esté cómodamente dentro de los límites: 1.2.4-beta.1 cumple tanto >=1.2.3 como <2.0.0-0, y aun así ^1.2.3 lo rechaza.
La regla se suele enunciar como «salvo que el propio rango mencione un prelanzamiento», y eso es demasiado laxo. Lo que hace falta es que algún comparador del rango lleve el mismo mayor.menor.parche. Así que ^1.2.3-alpha sigue rechazando 1.2.4-beta.1: ese rango sí nombra un prelanzamiento, pero sobre 1.2.3, y la versión que se comprueba es 1.2.4. Cambia la versión a 1.2.3-beta.1 y se acepta.
El razonamiento detrás es que un prelanzamiento de 1.2.4 no ha prometido comportarse como 1.2.4, así que aceptar un rango no debería meterte en silencio código sin publicar de versiones que nunca nombraste. Cuando sí lo quieres, la casilla de prelanzamientos es la salida, y conviene saber que cambia cómo se construye el rango y no cómo se compara. Con ella, ^1 pasa a ser >=1.0.0-0, mientras que ^1.0.0 se queda en >=1.0.0, porque solo se rebaja un límite que se hubiera rellenado a partir de una versión parcial.
Límites honestos
Esto comprueba cadenas de versión contra cadenas de rango y nada más. No sabe qué hay publicado, así que no puede decirte qué versión instalaría hoy un rango, ni si una actualización va a romperte el código: el versionado semántico es una promesa de quien publica, no una garantía que alguien verifique. Una versión mayor que no toca nada de lo que usas es inofensiva; una de parche te puede romper igual.
La gramática de rangos implementada aquí es la de npm, con diferencia la más común pero no la única. Otros ecosistemas escriben ideas parecidas de otra manera, y un rango copiado de uno de ellos o se rechaza aquí o, peor, significa otra cosa. Los rangos con añadidos propios de npm que se salen de la gramática de versiones (una URL de git o una ruta local en lugar de una versión) no son rangos en este sentido y no se tratan.
Como esa gramática no tiene especificación, el criterio de corrección aquí es coincidir con la implementación de referencia y no ajustarse a un documento. El motor se comprueba contra ella sobre 1.680 pares de versión y rango sin ninguna discrepancia, y aparte contra las reglas de precedencia de la especificación, que esas sí existen.
¿Por qué es gratis?
Porque no cuesta nada mantenerlo. El análisis y la comparación ocurren en tu navegador; no se sube ninguna versión, rango ni manifiesto, y no hay cuenta.
Las reglas de precedencia salen de la especificación y la gramática de rangos de la implementación que la define en la práctica, con las pruebas guardadas junto al código.