GoScope Explorando e Navegando em Projetos Go
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
O 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
.
O uso é simples:
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:
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:
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
O rgs é um script que usa o GoScope como base. Ele faz:
- Executa
goscope
para coletar definições e chamadas. - Usa o fzf para criar um filtro interativo.
- Ao selecionar um item, abre o arquivo na linha correspondente, usando seu editor definido em
$EDITOR
.
Para usá-lo:
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
#!/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
-
Compilando o GoScope:
go build -o goscope mv goscope /usr/local/bin/
-
Instalando o rgs:
chmod +x rgs cp rgs /usr/local/bin/
Após isso, rodar goscope
ou rgs
deve funcionar de qualquer lugar.
Conclusão
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: