Dev (Back & Front)ARTIGO

GoScope Explorando e Navegando em Projetos Go

GoScope Explorando e Navegando em Projetos Go
Imagem: Cesar Gimenes

Muitas vezes, quero analisar rapidamente um projeto Go para entender onde funções, variáveis e tipos estão definidos ou chamados. Foi assim que criei duas ferramentas de linha de comando: GoScope e rgs. A primeira faz um escaneamento completo de todos os arquivos .go de um projeto, gerando uma lista de definições e chamadas de funções. A segunda usa essa lista para me permitir navegar de forma interativa até o ponto exato do código.

GoScope

GoScope percorre todos os arquivos .go de forma recursiva a partir do diretório atual. Ele imprime:

  • Funções, variáveis, constantes e tipos declarados, junto ao arquivo e linha.
  • Chamadas de função no formato Chamadora.Chamada arquivo:linha.
GoScope

O uso é simples:

fallback
cd /path/do/seu/projeto
goscope

Não é necessário passar parâmetros. Ele sempre analisa o diretório atual e subdiretórios em busca de definições em Go. Isso facilita a vida em projetos grandes, pois você não precisa se preocupar em apontar cada subpasta ou arquivo manualmente.

Exemplo de saída

Suponha um arquivo main.go com este conteúdo:

go
package main

import "fmt"

func main() {
    fmt.Println("Hello World")
    PrintNumber(42)
}

func PrintNumber(n int) {
    fmt.Printf("Number: %d\n", n)
}

Ao rodar goscope, você pode ver algo como:

fallback
main main.go:5
PrintNumber main.go:10
main.Println main.go:6
main.PrintNumber main.go:7
PrintNumber.Printf main.go:11

Isso ajuda a entender onde cada função é declarada e onde é chamada.

rgs

rgs é um script que usa o GoScope como base. Ele faz:

  1. Executa goscope para coletar definições e chamadas.
  2. Usa o fzf para criar um filtro interativo.
  3. Ao selecionar um item, abre o arquivo na linha correspondente, usando seu editor definido em $EDITOR.

Para usá-lo:

fallback
rgs

Digite uma parte do nome da função ou variável, escolha o resultado e pressione Enter. Você será levado diretamente para o local exato no código. É prático quando há centenas de funções espalhadas em múltiplos arquivos.

script rgs

bash
#!/usr/bin/env bash

RCS_CMD="goscope"
INITIAL_QUERY="${*:-}"

selected=$(FZF_DEFAULT_COMMAND=$RCS_CMD \
    fzf --ansi \
        --bind "change:reload:sleep 0.1; $RCS_CMD || true" \
        --delimiter ' ' \
        --preview 'file=$(echo {2} | cut -d":" -f1); \
line=$(echo {2} | cut -d":" -f2); \
# Calcula o range de linhas: 10 linhas acima (se possível) e 10 abaixo.
start=$(( line > 10 ? line - 10 : 1 )); \
end=$(( line + 10 )); \
bat --color=always --highlight-line "$line" --line-range "$start:$end" "$file"' \
        --preview-window 'up,60%,border-bottom' \
        --query "$INITIAL_QUERY")

if [ -n "$selected" ]; then
    IFS=' ' read -r function file_line <<< "$selected"
    file="${file_line%%:*}"
    line="${file_line#*:}"
    $EDITOR "$file" "+$line"
    echo "$file +$line"
fi

Esse script é apenas um exemplo. Você pode personalizá-lo para seu fluxo de trabalho.

Instalação

  1. Compilando o GoScope:
    fallback
    go build -o goscope
    mv goscope /usr/local/bin/
    
  2. Instalando o rgs:
    fallback
    chmod +x rgs
    cp rgs /usr/local/bin/
    

Após isso, rodar goscope ou rgs deve funcionar de qualquer lugar.

Conclusão

GoScope e o rgs facilitam a manutenção de projetos Go grandes ao fornecer uma visão clara de onde cada elemento está localizado e como é chamado. Essa abordagem é muito útil em times grandes, pois ajuda no onboarding de novos membros e acelera correções de bugs.

Vídeo com a explicação detalhada:

Referências

Trabalha com tecnologia desde a década de 90. Já atuou na área de educação e participou de projetos de mobilidade de grande volume para laboratórios farmacêuticos. Criou games tanto para PC, como para iOS. Hoje está direcionando seus esforços em plataformas de Sistemas Embarcados, IoT, microservices e cloud computing. É um entusiasta de tecnologias como Golang e Docker.

Ver perfil