Go Modules
Nesta aula, você aprenderá sobre o sistema de módulos do Go, incluindo a estrutura dos arquivos go.mod e go.sum, o comando go get, versionamento semântico e gerenciamento de dependências. Serão apresentados exemplos práticos e boas práticas para trabalhar com módulos em Go.
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 substitui o antigo GOPATH, permitindo que projetos definam suas dependências de forma explícita e versionada. Com modules, você pode trabalhar fora do GOPATH e ter controle preciso sobre as versões das bibliotecas que seu projeto utiliza.
Nesta aula, exploraremos os arquivos go.mod e go.sum, o comando go get, as regras de versionamento semântico e como gerenciar dependências de forma eficiente. Ao final, você será capaz de iniciar um novo módulo, adicionar dependências e entender como o Go resolve versões.
go.mod e go.sum
O arquivo go.mod é o coração de um módulo Go. Ele define o nome do módulo (geralmente o repositório ou caminho do pacote), a versão do Go utilizada e as dependências do projeto com suas versões. Quando você executa go mod init <module-name>, o Go cria esse arquivo automaticamente.
O go.sum contém hashes criptográficos (SHA-256) das dependências baixadas, garantindo a integridade e segurança do código. Ele é gerado automaticamente e não deve ser editado manualmente. Sempre que uma dependência é adicionada ou atualizada, o go.sum é atualizado.
Exemplo de go.mod:
module github.com/meuprojeto/exemplo
go 1.21
require (
github.com/gorilla/mux v1.8.1
github.com/lib/pq v1.10.9
)
Exemplo de go.sum (trecho):
github.com/gorilla/mux v1.8.1 h1:TuMoUvkRETdXqU+3a2JqFg94GKNY4G57W9iM5J5k8ck=
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. Quando executado, ele baixa o pacote especificado, atualiza o go.mod e o go.sum, e coloca o código no cache local. Você pode especificar uma versão usando @versão ou @latest (padrão).
Exemplos de uso:
# Adicionar a 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.0
# Atualizar todas as dependências para a versão mais recente compatível
go get -u ./...
# Remover dependências não utilizadas
go mod tidy
O go mod tidy é uma boa prática para limpar o go.mod e go.sum, removendo dependências que não são mais necessárias e adicionando as que estão faltando.
Versionamento
O Go adota o versionamento semântico (SemVer) para módulos. As versões seguem o formato vMAJOR.MINOR.PATCH. Mudanças incompatíveis (breaking changes) devem ser indicadas com incremento na versão MAJOR. O Go também suporta prefixos como v0 para desenvolvimento inicial e v1 para versão estável.
Quando você depende de um módulo que ainda não atingiu a versão estável (v0.x.x), o Go assume que qualquer versão pode conter breaking changes. Para módulos com versão major >= 2, o caminho do módulo deve incluir o sufixo /v2, /v3, etc. Isso permite que diferentes versões maiores coexistam.
Exemplo de dependência com versão major >=2:
require (
github.com/algum/modulo/v2 v2.3.4
)
O Go também utiliza o conceito de "versão mínima" (Minimal Version Selection - MVS). Isso significa que, ao resolver dependências, o Go escolhe a versão mínima necessária que satisfaz todas as restrições, evitando conflitos.
Dependências
Gerenciar dependências em Go é simples com modules. Você pode adicionar dependências diretamente no código e usar go mod tidy para sincronizar. O Go também oferece o comando go mod vendor para criar uma pasta vendor com todas as dependências, útil para ambientes offline ou revisão de código.
Dependências transitivas são automaticamente resolvidas. Se você usa a biblioteca A que depende da B, o Go baixa ambas. Você pode visualizar a árvore de dependências com go mod graph.
Boas práticas:
- Sempre execute
go mod tidyantes de commitar. - Evite depender de versões
latestem produção; fixe versões específicas. - Use
go get -uperiodicamente para atualizar dependências, mas teste antes. - Para módulos privados, configure
GOPRIVATEou usereplacenogo.mod.
Referências
- Managing dependencies - Go Documentation
- Go Modules Reference
- Using Go Modules - Go Blog
- Semantic Versioning 2.0.0
- go.mod file reference
Exercícios
-
Crie um novo módulo chamado
github.com/meuapp/hellousandogo mod init. Em seguida, adicione a dependênciagithub.com/fatih/colorna versão mais recente. Mostre o conteúdo dogo.modapós a adição.✓ Resposta:go mod init github.com/meuapp/hello go get github.com/fatih/colorConteúdo do
go.mod:module github.com/meuapp/hello go 1.21 require github.com/fatih/color v1.16.0 -
No módulo criado no exercício 1, escreva um programa que imprime "Hello, World!" em vermelho usando o pacote
color. Execute o programa e verifique a saída.✓ Resposta:package main import "github.com/fatih/color" func main() { color.Red("Hello, World!") }Execute com
go run main.go(assumindo que o arquivo se chama main.go). -
Use
go get -u ./...para atualizar todas as dependências do módulo do exercício 1. Depois, executego mod tidye verifique se ogo.sumfoi atualizado.✓ Resposta:go get -u ./... go mod tidyO
go.sumserá atualizado com os novos hashes se houver atualizações. -
Adicione uma dependência que não é usada no código (por exemplo,
github.com/google/uuid). Executego mod tidye verifique se a dependência foi removida dogo.mod.✓ Resposta:go get github.com/google/uuid go mod tidyApós
go mod tidy, a dependência não utilizada será removida dogo.mod. -
Crie um módulo que dependa de dois pacotes:
github.com/gorilla/muxegithub.com/lib/pq. Usego mod graphpara exibir a árvore de dependências e identifique se há dependências transitivas.✓ Resposta:go get github.com/gorilla/mux github.com/lib/pq go mod graphExemplo de saída:
github.com/meuapp/hello github.com/gorilla/mux@v1.8.1 github.com/meuapp/hello github.com/lib/pq@v1.10.9 github.com/gorilla/mux@v1.8.1 github.com/gorilla/context@v1.1.1Aqui,
github.com/gorilla/contexté uma dependência transitiva demux.
Boas Práticas e Observações Finais
Sempre versionar seu módulo seguindo SemVer e manter o go.mod limpo com go mod tidy. Evite usar replace a menos que necessário para substituir dependências locais ou forks. Para projetos maiores, considere usar go mod vendor para garantir builds reproduzíveis. Lembre-se de que o Go Modules é uma ferramenta poderosa que simplifica o gerenciamento de dependências, tornando o ecossistema Go mais robusto e confiável.