Go modules: versionamento semântico e replace
1. Fundamentos do Versionamento Semântico em Go Modules
1.1 O formato vMAJOR.MINOR.PATCH e sua aplicação no ecossistema Go
O versionamento semântico (SemVer) é a espinha dorsal do sistema de módulos do Go. Cada versão de módulo segue o formato vMAJOR.MINOR.PATCH, onde:
- MAJOR: incrementado quando há mudanças incompatíveis na API
- MINOR: incrementado quando novas funcionalidades são adicionadas de forma compatível
- PATCH: incrementado para correções de bugs compatíveis
// Exemplo de declaração de versão no go.mod
module github.com/meuprojeto/calculadora
go 1.21
require github.com/sirupsen/logrus v1.9.3
1.2 Regras de compatibilidade
O Go é rigoroso quanto à compatibilidade semântica. Se você possui uma função Soma(a, b int) int e altera sua assinatura para Soma(a, b, c int) int, isso exige um incremento major. Adicionar uma nova função Multiplica sem alterar as existentes exige apenas um incremento minor.
// v1.0.0 - versão inicial
package calculadora
func Soma(a, b int) int {
return a + b
}
// v1.1.0 - adição compatível
func Subtracao(a, b int) int {
return a - b
}
// v2.0.0 - quebra de compatibilidade
func Soma(a, b, c int) int { // Assinatura alterada!
return a + b + c
}
1.3 A tag go no go.mod
A diretiva go no go.mod indica a versão mínima do compilador Go necessária para compilar o módulo, não a versão do módulo em si.
module github.com/exemplo/meumodulo
go 1.21 // Requer Go 1.21 ou superior
2. Declarando e Gerenciando Dependências com Versões
2.1 Sintaxe require
A diretiva require especifica dependências e suas versões:
require (
github.com/gorilla/mux v1.8.1
github.com/lib/pq v1.10.9
golang.org/x/sync v0.5.0
)
2.2 Comandos go get
# Adicionar ou atualizar dependência
go get github.com/gorilla/mux@v1.8.1
# Atualizar para última versão minor/patch
go get -u github.com/gorilla/mux
# Remover dependência
go get github.com/gorilla/mux@none
2.3 Arquivo go.sum
O go.sum contém hashes criptográficos que garantem a integridade das dependências:
github.com/gorilla/mux v1.8.1 h1:TuMoUvkRETdXqU+3a8mHkR0g7A6J30IJb2qA0...
github.com/gorilla/mux v1.8.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8...
3. Versões Major e Módulos com Caminhos Diferentes
3.1 A regra de importação para v2+
Para versões major 2 ou superiores, o Go exige que o caminho do módulo inclua a versão major:
// Estrutura de diretórios
meuprojeto/
├── go.mod (module github.com/exemplo/meuprojeto/v2)
├── calculadora.go
└── main.go
// go.mod
module github.com/exemplo/meuprojeto/v2
go 1.21
// main.go
package main
import (
"fmt"
"github.com/exemplo/meuprojeto/v2/calculadora"
)
func main() {
fmt.Println(calculadora.Soma(1, 2, 3))
}
3.2 Criando uma nova versão major
# Criar branch para v2
git checkout -b v2
# Alterar go.mod
module github.com/exemplo/meuprojeto/v2
# Taggear
git tag v2.0.0
git push origin v2.0.0
3.3 Convivência de múltiplas versões major
import (
"github.com/exemplo/meuprojeto/v1/calculadora" // v1
v2calc "github.com/exemplo/meuprojeto/v2/calculadora" // v2
)
func main() {
fmt.Println(calculadora.Soma(1, 2)) // v1 - 2 parâmetros
fmt.Println(v2calc.Soma(1, 2, 3)) // v2 - 3 parâmetros
}
4. Versões Pré-lançamento e Pseudoversões
4.1 Identificadores de pré-lançamento
// Exemplos de versões pré-lançamento
v1.0.0-alpha
v1.0.0-beta.1
v1.0.0-rc.1
4.2 Pseudoversões
Pseudoversões são geradas automaticamente para commits sem tag:
v1.0.0-20240101120000-abc123def456
# Usar pseudoversão
go get github.com/exemplo/meumodulo@abc123def456
4.3 Limitações
Pseudoversões não devem ser usadas em produção, pois não seguem SemVer e podem causar builds não reproduzíveis.
5. A Diretiva replace no go.mod
5.1 Sintaxe e casos de uso
module github.com/meuprojeto/api
go 1.21
require github.com/meuprojeto/utils v1.0.0
replace github.com/meuprojeto/utils => ../utils-local
5.2 Cenários práticos
Desenvolvimento local de dependências:
replace github.com/meuprojeto/database => /home/user/projetos/database
Patches temporários com fork:
replace github.com/gorilla/mux => github.com/meuuser/mux v1.8.2-patched
5.3 Impactos no build
replace só funciona no módulo raiz. Módulos que dependem do seu módulo não herdam diretivas replace.
// Isto NÃO funciona em dependências transitivas
// Apenas no módulo raiz
replace example.com/foo => example.com/foo v1.0.1
6. Boas Práticas com replace e Versionamento
6.1 Caminhos relativos
replace github.com/meuprojeto/utils => ./utils-local
6.2 replace vs go.work
go.work (Go 1.18+) é mais adequado para múltiplos módulos:
// go.work
go 1.21
use (
./api
./utils
./database
)
6.3 Removendo replace antes do commit
# Script para verificar replace antes do commit
#!/bin/bash
if grep -q "replace" go.mod; then
echo "ERRO: go.mod contém diretivas replace!"
exit 1
fi
7. Ferramentas e Comandos Essenciais
7.1 go mod tidy
# Limpa dependências não usadas e adiciona as faltantes
go mod tidy
7.2 go mod vendor
# Cria diretório vendor com dependências
go mod vendor
# Build usando vendor
go build -mod=vendor
7.3 go list -m all
# Lista todas as dependências e versões resolvidas
go list -m all
# Versão específica
go list -m -versions github.com/gorilla/mux
8. Resolução de Conflitos e Casos Complexos
8.1 Mínima Versão Selecionada (MVS)
O Go utiliza MVS para resolver dependências conflitantes:
// Módulo A requer B v1.0.0
// Módulo C requer B v1.2.0
// Resultado: B v1.2.0 (maior versão compatível)
8.2 Dependências indiretas com replace
// go.mod
require (
github.com/exemplo/a v1.0.0
)
// github.com/exemplo/a depende de github.com/exemplo/b v1.0.0
// Podemos substituir b mesmo sendo dependência indireta
replace github.com/exemplo/b => github.com/meuuser/b v1.0.1-fork
8.3 Migrando de dep/glide
# Inicializar módulos
go mod init github.com/meuprojeto/novo
# Converter dependências
go mod tidy
# Verificar diferenças
go mod verify
Referências
- Documentação Oficial: Go Modules Reference — Guia completo sobre gerenciamento de dependências com módulos Go
- Semantic Import Versioning no Go — Artigo técnico de Russ Cox explicando o versionamento semântico no contexto do Go
- Go Blog: Using Go Modules — Série oficial sobre como usar módulos Go, incluindo versionamento e replace
- Go Modules: replace directive — Tutorial prático da DigitalOcean sobre a diretiva replace
- Go Workspaces (go.work) — Documentação oficial sobre workspaces como alternativa ao replace em projetos multimódulo
- Mastering Go Modules: The replace directive — Artigo de Alex Edwards com exemplos práticos de replace
- Go Modules: v2+ Major Version — Guia oficial para criação e publicação de versões major