FreeToGenerate.com

O circunflexo e o til não estão na especificação do SemVer. Procure lá por «caret», «tilde» ou «range» e não aparece nada — essa sintaxe é do npm.

Isto muda como o intervalo é construído, não só como é testado: um intervalo parcial como ^1 passa a ser >=1.0.0-0 em vez de >=1.0.0.

Recusada, e só por ser um pré-lançamento

Todos os limites se verificam. É recusada porque um pré-lançamento só entra num intervalo quando algum comparador nomeia o mesmo maior.menor.correção — e aqui nenhum o faz. É esta a regra por trás do «porque é que a minha beta não corresponde».

>=1.2.3 <2.0.0-0

Os intervalos são expandidos em comparadores simples antes de se comparar seja o que for. Os limites superiores levam -0 para que um pré-lançamento da versão seguinte não se infiltre.

  • >=1.2.3verifica-se
  • <2.0.0-0verifica-se

A versão, por partes

Maior
1
Menor
2
Correção
4
Pré-lançamento
beta.1

Nada desta sintaxe de intervalos está na especificação do SemVer

O semver.org define o formato da versão e as regras de qual versão é mais recente, e fica-se por aí — as palavras «caret», «tilde» e «range» não lá aparecem. A sintaxe ^ ~ || e os intervalos com x vêm do npm, e são uma convenção por cima da norma, não parte dela.

Também disponível em: English · Español · Français · العربية

Verificador de semver

Se uma versão cumpre um intervalo, os comparadores em que esse intervalo realmente se expande, e uma resposta direta quando um pré-lançamento é recusado.

O que é o versionamento semântico?

O versionamento semântico é a convenção de que um número de versão são três números com significado: maior.menor.correção. Sobe-se a correção para um arranjo que não muda mais nada, o menor para algo acrescentado de forma compatível, e o maior quando o código existente vai partir. Um hífen introduz um pré-lançamento — 2.0.0-rc.1 — e um sinal de mais introduz metadados de compilação que são completamente ignorados na comparação.

A especificação em semver.org define esse formato e define a precedência: qual de duas versões é mais recente, incluindo a regra de que um pré-lançamento fica sempre abaixo da versão que precede. O 1.0.0-alpha vem antes do 1.0.0, não depois.

O que a especificação não define são os intervalos. Procure no texto dela por «caret», «tilde» ou «range» e não os encontra. A sintaxe ^ ~ || e os intervalos com x de que todos os manifestos estão cheios vêm do npm, e esta página testa uma versão contra ela — deixando claro que metade é a norma e que metade é uma convenção por cima.

Como usar

  1. Ponha uma versão na primeira caixa e um intervalo na segunda. 1.2.4 contra ^1.2.3, ou um pré-lançamento como 1.2.4-beta.1, ou um intervalo tão complicado como >=1.2.0 <2.0.0 || ^3.
  2. Leia a expansão, não só o veredicto. Todo o intervalo vira comparadores simples antes de se comparar seja o que for, e de cada um diz-se se se verifica. Uma resposta surpreendente costuma tornar-se óbvia assim que os limites estão escritos.
  3. Experimente a caixa dos pré-lançamentos se uma beta estiver a ser recusada. Mostra o que muda — e muda o próprio intervalo, não apenas a comparação.

O circunflexo quer dizer três coisas diferentes

O circunflexo é descrito como «compatível com», o que serve até se reparar que se comporta de maneira diferente conforme qual dos números da frente seja zero. ^1.2.3 permite tudo até 2.0.0, exclusive. ^0.2.3 só permite versões de correção e pára em 0.3.0. E ^0.0.3 não permite absolutamente nada para lá do próprio 0.0.3.

É de propósito: antes de 1.0.0 a convenção é que qualquer coisa pode partir, portanto o circunflexo aperta para compensar. A consequência é uma que quase ninguém espera: abaixo de 1.0.0, ^0.2.3 e ~0.2.3 são o mesmo intervalo. A distinção em que toda a gente se apoia entre «permite atualizações menores» e «permite atualizações de correção» desaparece simplesmente, porque não há atualização menor que o circunflexo fosse permitir.

Mais um pormenor visível na expansão acima: os limites superiores escrevem-se <2.0.0-0 e não <2.0.0. Sem esse -0 final, um pré-lançamento da próxima versão maior — 2.0.0-rc.1 — ficaria abaixo de 2.0.0 e passaria por um intervalo que era suposto parar antes.

Porque a sua beta não corresponde

É esta a pergunta que traz quase toda a gente a um verificador de semver, e a explicação habitual não está bem certa. Um pré-lançamento fica excluído de um intervalo mesmo estando confortavelmente dentro dos limites: 1.2.4-beta.1 cumpre tanto >=1.2.3 como <2.0.0-0, e mesmo assim ^1.2.3 recusa-o.

A regra é muitas vezes enunciada como «a não ser que o próprio intervalo mencione um pré-lançamento», e isso é demasiado frouxo. O que é preciso é que algum comparador do intervalo leve o mesmo maior.menor.correção. Portanto ^1.2.3-alpha continua a recusar 1.2.4-beta.1 — esse intervalo nomeia mesmo um pré-lançamento, mas em 1.2.3, e a versão que está a ser testada é 1.2.4. Mude a versão para 1.2.3-beta.1 e é aceite.

O raciocínio por trás é que um pré-lançamento de 1.2.4 não prometeu comportar-se como 1.2.4, portanto aceitar um intervalo não devia meter-lhe em silêncio código por publicar de versões que nunca nomeou. Quando o quer mesmo, a caixa dos pré-lançamentos é a saída — e vale a pena saber que ela muda como o intervalo é construído e não como é comparado. Com ela, ^1 passa a >=1.0.0-0, enquanto ^1.0.0 fica em >=1.0.0, porque só é baixado um limite que tenha sido preenchido a partir de uma versão parcial.

Limites honestos

Isto testa cadeias de versão contra cadeias de intervalo e mais nada. Não sabe o que está publicado, portanto não lhe consegue dizer que versão um intervalo instalaria hoje, nem se uma atualização lhe vai partir o código — o versionamento semântico é uma promessa de quem publica, não uma garantia que alguém verifique. Uma versão maior que não mexe em nada do que usa é inofensiva; uma de correção pode parti-lo na mesma.

A gramática de intervalos aqui implementada é a do npm, de longe a mais comum mas não a única. Outros ecossistemas escrevem ideias parecidas de outra maneira, e um intervalo copiado de um deles ou é recusado aqui ou, pior, quer dizer outra coisa. Intervalos com extras próprios do npm que saem da gramática das versões — um URL de git ou um caminho local em vez de uma versão — não são intervalos neste sentido e não são tratados.

Como essa gramática não tem especificação, o critério de correção aqui é concordar com a implementação de referência e não conformar-se com um documento. O motor é verificado contra ela sobre 1680 pares de versão e intervalo sem uma única divergência, e à parte contra as regras de precedência da especificação, essas sim existentes.

Porque é grátis

Porque não custa nada manter. A análise e a comparação acontecem no seu navegador; nenhuma versão, intervalo ou manifesto é enviado, e não há conta nenhuma.

As regras de precedência saem da especificação e a gramática de intervalos da implementação que a define na prática, com os testes guardados ao lado do código.