Tool Dependencies
Introdução
Seção intitulada “Introdução”Go 1.24 (fevereiro de 2025) introduziu a diretiva tool no go.mod, que finalmente resolve um problema antigo: como gerenciar ferramentas de desenvolvimento (linters, geradores de código, etc.) de forma padronizada.
O problema antes do Go 1.24
Seção intitulada “O problema antes do Go 1.24”O Hack tools.go
Seção intitulada “O Hack tools.go”Desenvolvedores criavam um arquivo especial para rastrear ferramentas:
//go:build tools// +build tools
package tools
import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "golang.org/x/tools/cmd/goimports" _ "github.com/swaggo/swag/cmd/swag")Problemas com esta abordagem:
- ❌ Confuso para novos desenvolvedores
- ❌ Build tags obscuros
- ❌ Ferramentas misturadas com dependências de runtime
- ❌ Não havia padrão oficial
A solução: diretiva tool
Seção intitulada “A solução: diretiva tool”Sintaxe
Seção intitulada “Sintaxe”module github.com/usuario/projeto
go 1.27.0
// Ferramentas de desenvolvimentotool ( golang.org/x/tools/cmd/goimports github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/swaggo/swag/cmd/swag)Como adicionar uma tool
Seção intitulada “Como adicionar uma tool”# Adicionar uma ferramentago get -tool golang.org/x/tools/cmd/goimports@latest
# Adicionar múltiplas ferramentasgo get -tool \ github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest \ github.com/swaggo/swag/cmd/swag@latest \ golang.org/x/tools/cmd/stringer@latest
# Adicionar versão específicago get -tool golang.org/x/tools/cmd/goimports@v0.38.0Como executar uma tool
Seção intitulada “Como executar uma tool”# Executar ferramenta registradago tool goimports -w .go tool golangci-lint rungo tool swag init
# Lista todas as ferramentas disponíveisgo toolExemplo
Seção intitulada “Exemplo”A diretiva tool registra o pacote executável. O comando go get -tool também adiciona o módulo da ferramenta em require, com sua versão, e atualiza go.sum. Os trechos abaixo mostram a organização das diretivas; use o comando para gerar os requisitos completos.
go.mod com tool
Seção intitulada “go.mod com tool”module github.com/empresa/api
go 1.27.0
// Dependências de runtimerequire ( github.com/gin-gonic/gin v1.10.0 gorm.io/gorm v1.25.7)
// Ferramentas de desenvolvimentotool ( golang.org/x/tools/cmd/goimports github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/swaggo/swag/cmd/swag golang.org/x/tools/cmd/stringer github.com/google/wire/cmd/wire)Setup de novo desenvolvedor
Seção intitulada “Setup de novo desenvolvedor”# 1. Clone o projetogit clone https://github.com/empresa/apicd api
# 2. Baixe dependências E ferramentasgo mod download
# 3. Instale ferramentas no GOBINgo install tool
# 4. Pronto! Todas as ferramentas disponíveisgo tool goimports -w .golangci-lint run # Também disponível no PATHComandos úteis
Seção intitulada “Comandos úteis”Gerenciamento de ferramentas
Seção intitulada “Gerenciamento de ferramentas”# Adicionar ferramentago get -tool <package>@<version>
# Atualizar todas as ferramentasgo get tool
# Atualizar ferramenta específicago get -tool <package>@latest
# Remover ferramentago get -tool <package>@none
# Listar ferramentasgo list toolExecutar tool
Seção intitulada “Executar tool”# Via go tool (usa versão do go.mod)go tool <nome> [args]
# Instalar no GOBINgo install tool # Instala todasgo install <package> # Instala uma específica na versão selecionada pelo módulo
# Executar diretamente (se instalada)goimports -w .Vantagens da diretiva tool
Seção intitulada “Vantagens da diretiva tool”| Aspecto | tools.go (antigo) | tool (Go 1.24+) |
|---|---|---|
| Clareza | Obscuro | Explícito e oficial |
| Requisitos de versão | Compartilham o grafo do projeto | Compartilham o grafo do projeto |
| Execução | go run manual |
go tool integrado |
| Cache | Depende do comando e da versão do Go | Executável mantido no build cache |
| Padrão | Hack não oficial | Suporte oficial |
Casos de uso comuns
Seção intitulada “Casos de uso comuns”1. Linters e Formatadores
Seção intitulada “1. Linters e Formatadores”tool ( github.com/golangci/golangci-lint/v2/cmd/golangci-lint golang.org/x/tools/cmd/goimports mvdan.cc/gofumpt)# Executar lintinggo tool golangci-lint run
# Formatar códigogo tool goimports -w .go tool gofumpt -l -w .2. Geradores de código
Seção intitulada “2. Geradores de código”tool ( github.com/google/wire/cmd/wire golang.org/x/tools/cmd/stringer github.com/swaggo/swag/cmd/swag google.golang.org/protobuf/cmd/protoc-gen-go)# Gerar códigogo tool wire ./...go tool stringer -type=Statusgo tool swag init3. Ferramentas de teste e cobertura
Seção intitulada “3. Ferramentas de teste e cobertura”tool ( github.com/onsi/ginkgo/v2/ginkgo github.com/golang/mock/mockgen gotest.tools/gotestsum)# Executar testesgo tool gotestsum ./...go tool ginkgo -r
# Gerar mocksgo tool mockgen -source=interface.goCache de ferramentas
Seção intitulada “Cache de ferramentas”Go 1.24+ mantém os executáveis das ferramentas no build cache. O comando continua executando a ferramenta a cada chamada; o que pode ser reaproveitado é a compilação.
go tool goimports -l .go tool goimports -l .O tempo depende da compilação e do trabalho realizado pela ferramenta. No Go 1.27, go tool também mostra os nomes curtos disponíveis para ferramentas declaradas no módulo. Um nome curto só pode ser usado quando identifica uma única ferramenta.
Integração com CI/CD
Seção intitulada “Integração com CI/CD”GitHub Actions
Seção intitulada “GitHub Actions”name: CIon: [push]jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.27.1'
# Ferramentas são baixadas automaticamente - run: go mod download
# Executar linting - run: go tool golangci-lint run
# Verificar formatação - run: | go tool goimports -l . test -z "$(go tool goimports -l .)"Makefile
Seção intitulada “Makefile”.PHONY: tools lint fmt test
# Instalar ferramentastools: go install tool
# Lintinglint: go tool golangci-lint run --timeout=5m
# Formataçãofmt: go tool goimports -w . go tool gofumpt -l -w .
# Gerar códigogenerate: go tool wire ./... go tool stringer -type=Status
# Executar tudoall: tools fmt generate lint testProblema: Conflitos de dependências
Seção intitulada “Problema: Conflitos de dependências”O Desafio
Seção intitulada “O Desafio”Ferramentas participam do mesmo grafo de dependências do projeto. Um requisito maior pode mudar a versão usada pelos dois:
Seu projeto: require github.com/pkg/errors v0.9.1Ferramenta: require github.com/pkg/errors v0.8.0
Versão selecionada pelo MVS: v0.9.1Solução 1: Usar a versão selecionada pelo MVS
Seção intitulada “Solução 1: Usar a versão selecionada pelo MVS”# MVS escolhe o maior requisito entre os módulos envolvidos# Geralmente funciona bemgo mod tidySolução 2: go.mod separado (avançado)
Seção intitulada “Solução 2: go.mod separado (avançado)”# Criar um módulo separado para ferramentasmkdir toolscd toolsGOWORK=off go mod init example.com/projeto/toolsGOWORK=off go get -tool golang.org/x/tools/cmd/goimports@v0.38.0cd ..
# Usar seu arquivo de requisitos a partir da raiz do projetoGOWORK=off go tool -modfile=tools/go.mod goimports -l .Migrando de tools.go
Seção intitulada “Migrando de tools.go”Antes (tools.go)
Seção intitulada “Antes (tools.go)”//go:build tools
package tools
import ( _ "golang.org/x/tools/cmd/goimports" _ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint")Depois (go.mod)
Seção intitulada “Depois (go.mod)”tool ( golang.org/x/tools/cmd/goimports github.com/golangci/golangci-lint/v2/cmd/golangci-lint)Passos de migração
Seção intitulada “Passos de migração”# 1. Remover tools.gorm tools.go
# 2. Adicionar ferramentas via go get -toolgo get -tool golang.org/x/tools/cmd/goimports@latestgo get -tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
# 3. Limpar go.modgo mod tidy
# 4. Testargo tool goimports --helpgo tool golangci-lint --version
# 5. Commitgit add go.mod go.sumgit rm tools.gogit commit -m "Migrate to tool directive (Go 1.24)"Melhores práticas
Seção intitulada “Melhores práticas”- Use
tooldirective para todas as ferramentas de desenvolvimento - Documente ferramentas necessárias no README
- Versione ferramentas (não use
@latestem produção) - Inclua
go install toolno setup de novos desenvolvedores - Use cache de ferramentas no CI para velocidade
❌ Evite
Seção intitulada “❌ Evite”- Misturar ferramentas com dependências de runtime manualmente
- Manter
tools.goem projetos Go 1.24+ - Usar
go runpara ferramentas (usego tool) - Ignorar conflitos de dependências sem investigar
Troubleshooting
Seção intitulada “Troubleshooting”Erro: “unknown command”
Seção intitulada “Erro: “unknown command””# Ferramenta não encontrada$ go tool goimportsgo: unknown tool goimports
# Solução: Adicionar ao go.modgo get -tool golang.org/x/tools/cmd/goimports@latestErro: Versão conflitante
Seção intitulada “Erro: Versão conflitante”# Resolver conflitogo get -tool <package>@<versão-compatível>go mod tidy
# Ou usar go.mod separadoCache não funciona
Seção intitulada “Cache não funciona”# Limpar e reconstruir cachego clean -cachego tool <ferramenta> # Reconstrói cacheRecursos adicionais
Seção intitulada “Recursos adicionais”- Go 1.24 Release Notes
- Proposal: Tool Dependencies
- Blog: How to Use the New tool Directive
- Alex Edwards: Managing Tool Dependencies in Go 1.24+
Conclusão
Seção intitulada “Conclusão”A diretiva tool do Go 1.24 é uma adição extremamente bem-vinda:
- 🎯 Padroniza gerenciamento de ferramentas
- 🚀 Simplifica setup de novos desenvolvedores
- ⚡ Melhora performance com caching
- 📦 Organiza dependências claramente