Go Modules
Esta aula aborda Go Modules, o sistema oficial de gerenciamento de dependências do Go. Você aprenderá a estrutura dos arquivos go.mod e go.sum, como usar go get, versionamento semântico e gerenciamento de dependências.
Go Modules é o sistema oficial de gerenciamento de dependências introduzido no Go 1.11 e tornado padrão a partir do Go 1.16. Ele substituiu o antigo GOPATH, permitindo que projetos sejam desenvolvidos fora dele e tenham suas dependências versionadas de forma precisa e reproduzível.
Nesta aula, vamos explorar os componentes fundamentais do sistema de módulos: os arquivos go.mod e go.sum, o comando go get, o versionamento semântico e as boas práticas para gerenciar dependências.
go.mod e go.sum
O arquivo go.mod é o coração de um módulo Go. Ele define o nome do módulo, a versão do Go utilizada e as dependências do projeto, incluindo suas versões exatas. Quando você cria um novo módulo com go mod init <module-path>, um arquivo go.mod é gerado.
O arquivo go.sum contém hashes criptográficos (SHA-256) de cada versão de dependência baixada. Ele garante a integridade e a reprodutibilidade das builds, pois qualquer alteração nas dependências resultará em hashes diferentes. Ambos os arquivos devem ser versionados no controle de versão.
// Exemplo de go.mod
module github.com/meuprojeto/exemplo
go 1.21
require (
github.com/gorilla/mux v1.8.1
golang.org/x/text v0.14.0
)// Exemplo de go.sum (parcial)
github.com/gorilla/mux v1.8.1 h1:TuMoUvkRETdXqU+3a6mhFfYEBJv5c6G=Q0fRZib5x0=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
...go get
O comando go get é usado para adicionar, atualizar ou remover dependências. Ele baixa o pacote especificado, atualiza o arquivo go.mod e adiciona os hashes ao go.sum. A partir do Go 1.18, go get por padrão apenas adiciona dependências; para atualizar, use go get -u.
// Adicionar uma dependência na versão mais recente
go get github.com/gorilla/mux
// Adicionar uma versão específica
go get github.com/gorilla/mux@v1.8.1
// Atualizar todas as dependências para a versão mais recente (compatível)
go get -u ./...
// Remover dependências não utilizadas
go mod tidyO comando go mod tidy é essencial para limpar o go.mod e go.sum, removendo dependências não utilizadas e adicionando as que estão faltando.
Versionamento
Go Modules adota o versionamento semântico (semver) no formato vMAJOR.MINOR.PATCH. Versões estáveis começam com v1 ou superior. Para versões principais (major) diferentes, o Go permite que múltiplas versões principais coexistam, pois o caminho do módulo inclui o sufixo /v2, /v3, etc.
Versões pré-lançamento (ex: v1.0.0-beta1) e pseudo-versões (ex: v0.0.0-20230101123456-abcdef123456) também são suportadas. Pseudo-versões são úteis para testar commits específicos que ainda não foram taggeados.
// Exemplo de módulo com versão principal v2
module github.com/usuario/projeto/v2
go 1.21
require (
github.com/usuario/projeto/v2 v2.0.0
)Para atualizar a versão major, utilize go get com o novo caminho: go get github.com/usuario/projeto/v2@v2.0.0.
Dependências
As dependências são gerenciadas de forma descentralizada: o Go baixa os módulos diretamente dos repositórios de origem (como GitHub) ou através de proxies como proxy.golang.org. O arquivo go.sum garante que as versões baixadas correspondam exatamente às esperadas.
Para verificar dependências, use go mod verify. Para listar dependências, go list -m all. Para entender a árvore de dependências, go mod graph. É importante manter as dependências atualizadas e evitar dependências desnecessárias.
// Listar todas as dependências
go list -m all
// Verificar integridade do go.sum
go mod verify
// Mostrar grafo de dependências
go mod graphBoas práticas: sempre execute go mod tidy antes de commitar, mantenha o go.mod e go.sum no repositório, e evite depender de versões v0 ou pré-lançamento em produção.
Referências
- Managing dependencies - The Go Blog
- Go Modules Reference
- Using Go Modules - The Go Blog
- Semantic Versioning
- go.mod file reference
Exercícios
Crie um novo módulo chamado
github.com/meuapp/hellousandogo mod init.✓ Resposta: Execute no terminal:
Isso criará um arquivo go.mod com o conteúdo:mkdir hello && cd hello go mod init github.com/meuapp/hellomodule github.com/meuapp/hello go 1.21Adicione a dependência
github.com/google/uuidna versãov1.6.0ao módulo criado.✓ Resposta: Execute:
O go.mod será atualizado para incluir:go get github.com/google/uuid@v1.6.0require github.com/google/uuid v1.6.0Após adicionar algumas dependências, execute o comando para remover dependências não utilizadas.
✓ Resposta: Execute:
Esse comando remove dependências não utilizadas do go.mod e adiciona as faltantes.go mod tidyAtualize todas as dependências do módulo para as versões mais recentes compatíveis.
✓ Resposta: Execute:
Isso atualiza todas as dependências para a última versão minor ou patch (mantendo a major).go get -u ./...Crie um módulo que depende de duas versões diferentes de um mesmo pacote (ex:
v1ev2do mesmo módulo). Explique como isso é possível.✓ Resposta: Go permite que duas versões principais coexistam porque cada versão major tem seu próprio caminho de módulo. Por exemplo,github.com/user/mod v1.xegithub.com/user/mod/v2 v2.xsão tratados como módulos diferentes. No go.mod, você pode ter ambos:
No código, você importa com o caminho correspondente:require ( github.com/user/mod v1.0.0 github.com/user/mod/v2 v2.0.0 )import "github.com/user/mod"eimport "github.com/user/mod/v2".
Observações finais: O sistema de módulos do Go é robusto e projetado para escalar. Sempre versionar go.mod e go.sum, e use go mod tidy regularmente para manter o projeto limpo. Em ambientes de produção, considere usar um proxy de módulos para garantir disponibilidade e velocidade.