DEV Community

Cover image for Go Tool: Uma análise da nova ferramenta para gerenciar dependências
Rafael Pazini
Rafael Pazini

Posted on

Go Tool: Uma análise da nova ferramenta para gerenciar dependências

Por um tempo, os desenvolvedores Go precisaram usar soluções improvisadas para gerenciar dependências de ferramentas. Com o lançamento do Go 1.24, isso mudou completamente. Vamos ver como!

Quem trabalha com Go sabe bem o quanto o ecossistema de ferramentas é fundamental para o desenvolvimento produtivo. Desde geradores de código como stringer até analisadores estáticos como staticcheck, essas ferramentas se tornaram parte essencial do fluxo de trabalho diário. No entanto, gerenciar essas dependências sempre foi um desafio - especialmente ao trabalhar em equipe.

Até agora, a solução padrão era o famoso padrão "tools.go" - um arquivo com imports em branco que não eram realmente usados no código, mas garantiam que as ferramentas fossem baixadas quando necessário. Era funcional, mas nunca pareceu uma solução elegante.

O Go 1.24, lançado em fevereiro de 2025, finalmente resolve esse problema introduzindo uma maneira oficial e elegante de gerenciar ferramentas: a nova funcionalidade go tool e a diretiva tool no arquivo go.mod. Esta mudança, representa uma melhoria significativa na experiência do desenvolvedor Go, permitindo um gerenciamento mais claro e eficiente das dependências de ferramentas.

O Problema Anterior

Antes do Go 1.24, para garantir que ferramentas como stringer, mockgen ou staticcheck estivessem disponíveis para todos da equipe, os desenvolvedores tipicamente usavam uma abordagem que ficou conhecida como o "padrão tools.go". Esse padrão envolvia:

  1. Criar um arquivo chamado "tools.go" com restrições de build para que não fosse incluído na compilação normal
  2. Adicionar imports em branco de todas as ferramentas necessárias
  3. Usar go run para executar essas ferramentas quando necessário
//go:build tools
// +build tools

package tools

import (
    _ "golang.org/x/tools/cmd/stringer"
    _ "golang.org/x/vuln/cmd/govulncheck"
    _ "honnef.co/go/tools/cmd/staticcheck"
)

Enter fullscreen mode Exit fullscreen mode

Embora funcional, esta abordagem tinha várias desvantagens:

  • Misturava ferramentas de desenvolvimento com dependências reais do código
  • Exigia comandos como go run golang.org/x/tools/cmd/stringer, que eram verbosos
  • Cada execução requeria uma recompilação da ferramenta, tornando o processo lento

A nova solução: go tool e a Diretiva tool

O Go 1.24 introduz uma solução elegante para esse problema com dois novos recursos principais:

  1. A diretiva tool no arquivo go.mod
  2. O comando go tool para executar ferramentas

Adicionando Ferramentas ao Projeto

Para adicionar uma ferramenta ao seu projeto, agora você pode simplesmente usar:

go get -tool golang.org/x/tools/cmd/stringer

Enter fullscreen mode Exit fullscreen mode

Este comando baixa a ferramenta e adiciona uma diretiva tool ao seu arquivo go.mod:

module example.com/myproject
go 1.24

tool (
    golang.org/x/tools/cmd/stringer
)

Enter fullscreen mode Exit fullscreen mode

Para versões específicas, basta adicionar o número da versão:

go get -tool honnef.co/go/tools/cmd/[email protected]

Enter fullscreen mode Exit fullscreen mode

Executando ferramentas

Após adicionar uma ferramenta, você pode executá-la facilmente com o comando go tool:

go tool stringer -type=Day enum.go

Enter fullscreen mode Exit fullscreen mode

Ou para ferramentas com nomes ambíguos, use o caminho completo:

go tool golang.org/x/tools/cmd/stringer -type=Day enum.go

Enter fullscreen mode Exit fullscreen mode

O comando go tool sem argumentos lista todas as ferramentas disponíveis, incluindo as nativas do Go e as definidas no seu módulo.

Caching de executáveis

Uma grande vantagem da nova abordagem é que os executáveis criados pelo go tool agora são armazenados em cache no Go build cache. Isso significa que as execuções repetidas são muito mais rápidas, pois a ferramenta não precisa ser recompilada a cada vez.

Benefícios da nova abordagem

A nova diretiva tool e o comando go tool oferecem diversos benefícios:

  1. Separação clara: Ferramentas são claramente distinguidas das dependências de código
  2. Sintaxe simplificada: Comandos mais curtos e intuitivos
  3. Versionamento: Versões específicas das ferramentas podem ser bloqueadas facilmente
  4. Melhor desempenho: Graças ao caching de executáveis
  5. Consistência: Todas as pessoas da equipe usam exatamente as mesmas versões das ferramentas
  6. Meta-padrão: O padrão tool permite operações em todas as ferramentas simultaneamente, como go get tool para atualizar todas elas

Exemplo do mundo real: Geração de Mocks para testes

Vamos ver um exemplo prático de como usar a nova funcionalidade go tool para gerar mocks para testes usando a ferramenta mockgen.

Passo 1: Adicionar mockgen ao projeto

# Adicionar mockgen como ferramenta
go get -tool github.com/golang/mock/mockgen

# Verificar se foi adicionada corretamente
cat go.mod

Enter fullscreen mode Exit fullscreen mode

Nosso go.mod agora terá uma seção como:

tool (
    github.com/golang/mock/mockgen
)

Enter fullscreen mode Exit fullscreen mode

Passo 2: Criar uma interface para mock

// service.go
package service

type UserService interface {
    GetUser(id string) (*User, error)
    CreateUser(user *User) error
}

type User struct {
    ID   string
    Name string
    Age  int
}

Enter fullscreen mode Exit fullscreen mode

Passo 3: Gerar o mock usando go tool

go tool mockgen -source=service.go -destination=mocks/mock_service.go -package=mocks

Enter fullscreen mode Exit fullscreen mode

Passo 4: Usar o mock em testes

// service_test.go
package service_test

import (
    "testing"

    "github.com/golang/mock/gomock"
    "example.com/myproject/mocks"
    "example.com/myproject/service"
)

func TestUserService(t *testing.T) {
    ctrl := gomock.NewController(t)
    defer ctrl.Finish()

    mockUserService := mocks.NewMockUserService(ctrl)

    // Configurar expectativas
    mockUser := &service.User{ID: "1", Name: "John", Age: 30}
    mockUserService.EXPECT().GetUser("1").Return(mockUser, nil)

    // Testar funcionalidade que usa o serviço
    user, err := mockUserService.GetUser("1")
    if err != nil {
        t.Errorf("Erro não esperado: %v", err)
    }
    if user.Name != "John" {
        t.Errorf("Nome esperado: John, obtido: %s", user.Name)
    }
}

Enter fullscreen mode Exit fullscreen mode

Este exemplo demonstra como a nova funcionalidade go tool simplifica o processo de desenvolvimento, especialmente para tarefas como geração de código. A sintaxe é mais limpa e todo o processo fica mais transparente para todos os membros da equipe.

Considerações e Limitações

Apesar dos muitos benefícios, existem algumas considerações importantes ao usar a nova funcionalidade:

  1. Versões compartilhadas de dependências: Ferramentas e código-fonte compartilham a mesma resolução de versão de dependências. Isso significa que, se uma ferramenta e seu código usam a mesma biblioteca mas com versões diferentes, pode haver conflitos.
  2. Aumento do tamanho do cache: Como os executáveis são armazenados em cache, isso pode aumentar o tamanho total do cache de build.
  3. Apenas ferramentas Go: Este mecanismo só funciona para ferramentas escritas em Go. Para ferramentas em outras linguagens, você ainda precisará de métodos alternativos.
  4. Compatibilidade: A funcionalidade está disponível apenas no Go 1.24 ou posterior.

Conclusão

A nova funcionalidade go tool e a diretiva tool no Go 1.24 representam uma evolução significativa na forma como os desenvolvedores Go gerenciam ferramentas. Em vez de usar soluções improvisadas, agora temos uma abordagem oficial, elegante e eficiente.

Para desenvolvedores que trabalham em equipes ou em projetos complexos, essa mudança traz benefícios imediatos em termos de consistência, simplicidade e desempenho. É mais um exemplo de como a linguagem Go continua evoluindo de forma pragmática, mantendo a simplicidade e atendendo às necessidades reais dos desenvolvedores.

Se você ainda não experimentou o Go 1.24, esta é mais uma excelente razão para fazer a atualização e começar a aproveitar todo o potencial do novo gerenciamento de ferramentas.

Top comments (0)