Tool Dependencies
Gerenciamento de dependências de ferramentas com a diretiva tool (Go 1.24+)
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.
Antes do Go 1.24, desenvolvedores usavam hacks como tools.go com imports vazios. Agora há uma solução oficial e elegante!
O problema antes do Go 1.24
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
toolSintaxe
module github.com/usuario/projeto
go 1.25
// Ferramentas de desenvolvimento
tool (
golang.org/x/tools/cmd/goimports
github.com/golangci/golangci-lint/cmd/golangci-lint
github.com/swaggo/swag/cmd/swag
)Como adicionar uma tool
tool# Adicionar uma ferramenta
go get -tool golang.org/x/tools/cmd/goimports@latest
# Adicionar múltiplas ferramentas
go get -tool \
github.com/golangci/golangci-lint/cmd/golangci-lint@latest \
github.com/swaggo/swag/cmd/swag@latest \
golang.org/x/tools/cmd/stringer@latest
# Adicionar versão específica
go get -tool github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0Como executar uma `tool```
# Executar ferramenta registrada
go tool goimports -w .
go tool golangci-lint run
go tool swag init
# Lista todas as ferramentas disponíveis
go toolExemplo
go.mod com tool
toolmodule github.com/empresa/api
go 1.25
// Dependências de runtime
require (
github.com/gin-gonic/gin v1.10.0
gorm.io/gorm v1.25.7
)
// Ferramentas de desenvolvimento
tool (
golang.org/x/tools/cmd/goimports
github.com/golangci/golangci-lint/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
# 1. Clone o projeto
git clone github.com/empresa/api
cd api
# 2. Baixe dependências E ferramentas
go mod download
# 3. Instale ferramentas no GOBIN
go install tool
# 4. Pronto! Todas as ferramentas disponíveis
go tool goimports -w .
golangci-lint run # Também disponível no PATHComandos úteis
Gerenciamento de ferramentas
# Adicionar ferramenta
go get -tool <package>@<version>
# Atualizar todas as ferramentas
go get -tool -u all
# Atualizar ferramenta específica
go get -tool <package>@latest
# Remover ferramenta
go get -tool <package>@none
# Listar ferramentas
go list -m -tool allExecutar tool
tool# Via go tool (usa versão do go.mod)
go tool <nome> [args]
# Instalar no GOBIN
go install tool # Instala todas
go install tool <package> # Instala uma específica
# Executar diretamente (se instalada)
goimports -w .Vantagens da diretiva tool
Clareza
Obscuro
Explícito e oficial
Separação
Misturado com deps
Separado claramente
Execução
go run manual
go tool integrado
Cache
Não
Sim (builds mais rápidos)
Padrão
Hack não oficial
Suporte oficial
IDEs
Suporte limitado
Suporte nativo
Casos de uso comuns
1. Linters e Formatadores
tool (
github.com/golangci/golangci-lint/cmd/golangci-lint
golang.org/x/tools/cmd/goimports
mvdan.cc/gofumpt
)# Executar linting
go tool golangci-lint run
# Formatar código
go tool goimports -w .
go tool gofumpt -l -w .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ódigo
go tool wire ./...
go tool stringer -type=Status
go tool swag init3. Ferramentas de teste e cobertura
tool (
github.com/onsi/ginkgo/v2/ginkgo
github.com/golang/mock/mockgen
gotest.tools/gotestsum
)# Executar testes
go tool gotestsum ./...
go tool ginkgo -r
# Gerar mocks
go tool mockgen -source=interface.goCache de ferramentas
Go 1.24+ cacheia execuções de ferramentas no build cache:
# Primeira execução: lenta
go tool golangci-lint run
# Tempo: 5s
# Segunda execução: rápida (cache)
go tool golangci-lint run
# Tempo: 0.1s
# Limpar cache se necessário
go clean -cacheIntegração com CI/CD
GitHub Actions
name: CI
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.25'
# 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
.PHONY: tools lint fmt test
# Instalar ferramentas
tools:
go install tool
# Linting
lint:
go tool golangci-lint run --timeout=5m
# Formatação
fmt:
go tool goimports -w .
go tool gofumpt -l -w .
# Gerar código
generate:
go tool wire ./...
go tool stringer -type=Status
# Executar tudo
all: tools fmt generate lint testProblema: Conflitos de dependências
O Desafio
Ferramentas podem ter dependências conflitantes com seu projeto:
Seu projeto: require github.com/pkg/errors v0.9.1
Ferramenta: require github.com/pkg/errors v0.8.0
❌ CONFLITO!Solução 1: Aceitar o conflito (simples)
# MVS escolhe a versão mais nova
# Geralmente funciona bem
go mod tidySolução 2: go.mod separado (avançado)
# Criar tools/go.mod separado
mkdir tools
cd tools
cat > go.mod << 'EOF'
module tools
go 1.25
tool (
github.com/golangci/golangci-lint/cmd/golangci-lint
)
EOF
go mod download
# Usar com -modfile
cd ..
go tool -modfile=tools/go.mod golangci-lint runMigrando de tools.go
Antes (tools.go)
//go:build tools
package tools
import (
_ "golang.org/x/tools/cmd/goimports"
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
)Depois (go.mod)
// go.mod
tool (
golang.org/x/tools/cmd/goimports
github.com/golangci/golangci-lint/cmd/golangci-lint
)Passos de migração
# 1. Remover tools.go
rm tools.go
# 2. Adicionar ferramentas via go get -tool
go get -tool golang.org/x/tools/cmd/goimports@latest
go get -tool github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# 3. Limpar go.mod
go mod tidy
# 4. Testar
go tool goimports --help
go tool golangci-lint --version
# 5. Commit
git add go.mod go.sum
git rm tools.go
git commit -m "Migrate to tool directive (Go 1.24)"Melhores práticas
✅ Faça
Use
tooldirective para todas as ferramentas de desenvolvimentoDocumente ferramentas necessárias no README
Versione ferramentas (não use
@latestem produção)Inclua
go install toolno setup de novos desenvolvedoresUse cache de ferramentas no CI para velocidade
❌ 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
Erro: "unknown command"
# Ferramenta não encontrada
$ go tool goimports
go: unknown tool goimports
# Solução: Adicionar ao go.mod
go get -tool golang.org/x/tools/cmd/goimports@latestErro: Versão conflitante
# Resolver conflito
go get -tool <package>@<versão-compatível>
go mod tidy
# Ou usar go.mod separadoCache não funciona
# Limpar e reconstruir cache
go clean -cache
go tool <ferramenta> # Reconstrói cacheRecursos adicionais
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
{% hint style="success" %} Migre seus projetos! Substitua `
tools.gopela diretivatool` para aproveitar todos os benefícios do Go 1.24+.
Last updated