Package.json vs Go.mod: Para onde foi o campo de versão?
Se você migrar do JavaScript para o Go, uma coisa irá te surpreender.
Em um arquivo package.json, a versão está logo no topo. Você pode lê-la. Você pode alterá-la em um pull request. Você pode pesquisar por ela. É um fato que vive dentro do seu código.
Agora abra um arquivo go.mod. A versão não está lá.
Isso não é um erro. É uma escolha.
O Go não utiliza um campo de versão para o seu próprio módulo. Em vez disso, o Go utiliza git tags.
Para definir uma versão no Go, você faz o seguinte:
git tag v1.2.3git push origin v1.2.3
A git tag é a única fonte da verdade. Quando alguém executa go get, o Go consulta as tags do seu repositório para encontrar o commit correto.
Este design possui uma grande vantagem. Uma versão nunca pode apontar para o código errado. No npm, o código publicado e o código marcado com a tag podem divergir. No Go, eles são a mesma coisa, pois a versão é um ponteiro para um commit.
No entanto, isso altera seu fluxo de trabalho de diversas maneiras:
- Encontrar sua versão requer um comando. Você deve executar
git describe --tagsem vez de olhar para um arquivo. - Atualizações de versão (version bumps) não aparecem em revisões de código. Um push de tag não é uma alteração de código, portanto, não aparece em um pull request.
- Builds locais usam pseudo-versões. Até que você marque um commit com uma tag, você verá uma longa sequência de números e hashes em vez de uma versão limpa como
v1.2.3. - Versões major alteram seu caminho de importação. No npm, você altera o número da versão, mas mantém o nome do pacote. No Go, a v2 e versões superiores exigem uma mudança no caminho, como
/v2. Isso permite que um programa use a v1 e a v2 da mesma biblioteca ao mesmo tempo, sem conflitos.
A maioria dos outros ecossistemas mantém a versão em um arquivo:
- Node:
package.json - Rust:
Cargo.toml - Python:
pyproject.toml - Java:
pom.xml - .NET:
.csproj
O Go é diferente. Ele depende apenas de git tags.
Se você quiser que seu binário Go exiba uma versão limpa, você pode injetá-la durante o processo de build usando ldflags. Muitos desenvolvedores também utilizam ferramentas como o goreleaser para automatizar o processo de tags e releases.
Os dois modelos representam prioridades diferentes:
- Versões baseadas em arquivos são fáceis de ler e revisar. O risco é que o arquivo possa divergir do código real.
- Versões baseadas em tags são impossíveis de falsificar. O custo é que são mais difíceis de visualizar e gerenciar.
O Go escolheu o modelo de tags para garantir que o manifesto sempre corresponda ao código.
Para quem trabalha com código Go: Como o modelo baseado apenas em tags impacta o seu dia a dia? Você o mudaria?
Fonte: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301