GoLang: Porque não usar o GOPATH

Nas versões anteriores de Go configurando-o requeria a configuração de algumas variáveis de ambiente. Com o tempo estes requisitos foram removidos mas muitos tutoriais online ainda mencionam estas variáveis causando confusão.

Recentemente uma nova funcionalidade chamada Go Modules foi lançada que finalmente torna o GOPATH desnecessário. Neste post, vou explicar o que é o GOPATH, por que Go Modules são preferidos e como configurar um projeto para usar Go Modules (que é surpreendentemente fácil).

O GOPATH é uma variável de ambiente que dirá ao Go onde ele deve ler e baixar todos os arquivos fonte que ele usará para compilar seu projeto. Este conceito vem com algumas restrições incomuns que você não vê em outras linguagens de programação:

  • Requer que você escreva seus projetos Go dentro deste diretório apontado pela variável GOPATH (por padrão ~/go), mesmo que seus outros projetos residam em outro lugar;
  • A hierarquia de diretório dentro do diretório GOPATH deve refletir a URL do seu projeto. Por exemplo, se sua URL é github.com/foo/bar você precisa criar um diretório $GOPATH/src/github.com , então, crie um novo diretório dentro dele: foo/ e dentro dele um novo diretório bar/ . Então, dentro do diretório bar/ você deve colocar o seu projeto git real;
  • Não há nenhuma forma interna para manter o controle das versões dos pacotes que você está usando.

O pior problema com esta configuração é que ela é completamente diferente do que estamos acostumados na maioria das outras linguagens de programação. Além disso, como o GOPATH é uma variável de ambiente ela requer que os usuários saibam um pouco sobre a configuração do seu sistema operacional, o que é sujeito a erros especialmente para iniciantes.

Por que você deve usar os módulos Go?

Go Modules não depende de nenhuma das dependências mencionadas acima para configurar variáveis de ambiente específicas, nem dos requisitos para colocar o seu projeto em um diretório específico como é com o GOPATH.

Também é retro-compatível, seguro e fácil de usar:

  1. Requer um único comando para migrar um projeto existente para usar os Módulos Go;
  2. Afecta apenas o seu ambiente de desenvolvimento (assim como o GOPATH) para que não afete a sua implementação de produção de forma alguma;
  3. É retro-compatível com o GOPATH, o que significa que se você atualizar um projeto para usar os Módulos Go e seus colegas de trabalho ainda preferirem usar o GOPATH eles podem fazê-lo sem problemas.

Outra razão para aprender a usar os Go Modules é que o GOPATH provavelmente deixará de ser amplamente adotado no futuro, portanto você precisará aprendê-lo mais cedo ou mais tarde.

Existem, no entanto, algumas advertências:

Caveat 1: GoLang versão 1.11 ou superior

Go Modules só funcionará com GoLang versão 1.11 ou superior. No momento de escrever este post, algumas distribuições Linux, incluindo Ubuntu, ainda usavam GoLang 1.10.

Você pode testar a versão atual do seu pacote Go instalado com o seguinte comando:

go version

Deve sair algo como:

go version go1.11.2 linux/amd64

Se a versão que você vê está abaixo 1.11.x você precisará desinstalá-la e seguir os passos abaixo para instalar a versão Go necessária. Note também que as instruções abaixo foram feitas para funcionar no Ubuntu e distribuições derivadas, se você estiver usando alguma outra distro, você precisará adaptar os comandos para que funcionem para você.

Primeiro, abra um terminal e depois poderá executar os seguintes comandos:

# If you have already installed the Go package remove it:
sudo apt-get remove --purge --auto-remove golang# Make sure your system is up-to-date:
sudo apt-get update
sudo apt-get -y upgrade# Download the Go 1.11 package and extract it:
wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
sudo tar -xvf go1.11.linux-amd64.tar.gz# Install it manually on your /usr/local directory:
sudo mv go /usr/local
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc# Then close your terminal, open a new one and test if Go is at the correct version:
which go # should output: /usr/local/go/bin/go
go version # should output: go version go1.11.x linux/amd64 or similar
  • Baixar o pacote Go 1.11 (ou mais recente) e extraí-lo:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Instalá-lo manualmente no seu directório /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Então feche o seu terminal, abra um novo e teste se Go está na versão correcta:
    which go, deve sair: /usr/local/go/bin/go
    go version, deve sair: go version go1.11.x linux/amd64 ou similar
  • Se você já instalou o pacote Go remova-o:
    sudo apt-get remove --purge --auto-remove golang
  • >

  • Certifique-se de que seu sistema está atualizado:
    sudo apt-get update
    sudo apt-get -y upgrade
  • >Baixar o pacote Go 1.11 e extraia-o:
    wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
    sudo tar -xvf go1.11.linux-amd64.tar.gz
  • Instale-o manualmente no seu diretório /usr/local:
    sudo mv go /usr/local
    echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
  • Então feche o seu terminal, abra um novo e teste se Go está na versão correcta:
    which go, deve sair: /usr/local/go/bin/go
    go version, deve sair: go version go1.11.x linux/amd64 ou similar

Caveat 2: Desfaça as alterações no GOPATH e GOROOT

Se você fez alterações nos valores padrão do seu GOPATH ou GOROOT, pode ser sábio remover essas alterações. Elas não são necessárias e misturar as configurações do GOPATH com os Módulos Go é uma forma de causar confusão. Mais especificamente:

  1. O valor padrão para o GOPATH (quando não configurado) é ~/go , então quando menciono o diretório ~/go quero dizer o diretório padrão usado pelo Go. Se você fez alterações no seu GOPATH, este diretório pode estar em outro lugar, então sugiro que você desfaça estas alterações para evitar confusão.
  2. Você não deve ter que alterar a variável de ambiente GOROOT desde que instalamos Go no diretório padrão: /usr/local. Se, entretanto, você alterou esta variável de ambiente, sugiro que a desfaça para evitar confusão.

Caveat 3: Você não precisa modificar o diretório ~/go

Como mencionado antes ~/go é o diretório padrão onde Go espera ler seus arquivos quando o GOPATH não está configurado. No entanto, isto só faz diferença se você estiver planejando criar seus projetos usando GOPATH.

Se você quiser usar os módulos Go, você não precisa criar, editar ou mesmo ler o diretório ~/go. Se ele ainda não existir será criado automaticamente para você, e se ele existir você não precisará alterar nada nele.

Então você pode ignorar qualquer tutorial que lhe peça para fazer alterações neste diretório já que provavelmente eles estão se referindo aos requisitos do GOPATH.

Também, se você tem um projeto Go atualmente dentro deste diretório e você quer que ele funcione com Go Modules você deve movê-lo para fora já que versões antigas do Go desabilitariam o go mod dentro do GOPATH mesmo que ele tivesse um arquivo go.mod.

Using Go Modules

Using Go Modules consiste basicamente em usar o seguinte comando:

go mod init <your_projects_import_path>

Para criar um novo projeto você só precisa criar um novo diretório (em qualquer lugar fora de ~/go/) e então inicializá-lo como um módulo, ou seja:

mkdir myProject/
cd myProject
go mod init github.com/myGithubName/myProject

O comando go mod init criará um novo arquivo chamado go.mod no diretório do seu projeto. Este ficheiro irá conter o caminho de importação do seu projecto (normalmente a URL do seu repo) e uma lista com todos os pacotes que está a utilizar neste projecto.

Não deverá precisar de editar este ficheiro uma vez que é gerido automaticamente pela maioria dos comandos go como go run e go get . Assim, após executar estes 3 comandos você terminou de configurar este diretório como um Módulo Go.

Para testá-lo crie um novo arquivo main.go dentro deste diretório com estas linhas de código:

package mainimport "fmt"func main() {
fmt.Println("Hello Go Modules")
}

Em seguida, teste-o usando o comando go run comando:

go run main.go 

Que deve sair Hello Go Modules como esperado.

Mas eu já tenho um projeto que usa GOPATH, como migrar?

O processo é semelhante:

  1. Mover o directório do seu projecto para qualquer lugar fora ~/go/
  2. Initializá-lo como um Módulo Go, por exemplo:
mv ~/go/src/github.com/myGithubName/myProject ~/anywhere_else/
cd ~/anywhere_else/myProject
go mod init github.com/myGithubName/myProject

Então você pode testar se tudo está funcionando com go test ./... ou go run main.go , ambos os comandos irão baixar automaticamente suas dependências e atualizar o go.mod arquivo.

Isso é legal, então devo criar módulos, submódulos e sub-submódulos? Nope.

Embora seja possível criar vários módulos em um único projeto, isso é quase sempre desnecessário. Se você quer uma subpasta para organizar seu código Go você está procurando por pacotes, não por módulos. Você só deve executar o comando go mod init uma vez por projeto, não mais.

O que devo fazer com os arquivos `go.mod` e `go.sum`?

As com NPM’s package.json e package-lock.json o conceito de Módulos Go também cria alguns arquivos para manter o controle de todas as versões de suas dependências, ou seja, os arquivos go.mod e os arquivos go.sum.

Você não deve precisar editar nenhum desses 2 arquivos, pois eles são gerenciados automaticamente por algumas ferramentas go como go get e go test. É também uma boa idéia adicioná-los aos seus commits, já que eles são necessários para realizar compilações reproduzíveis do seu projeto, ou seja, compilando com todas as mesmas versões e pacotes que você tem localmente.

Conclusion

Você deve estar pronto para usar os Módulos Go em seus próprios projetos. Usar não é obrigatório, mas se você leu até aqui provavelmente já notou o quanto os Go Modules são mais fáceis e intuitivos quando comparados com o GOPATH. Há também uma característica que apenas os Módulos Go lhe oferecerão: Buildds.

Se quiser saber mais detalhes sobre os Go Modules sugiro que leia este post para uma versão mais curta ou esta para uma mais longa, ambas são muito concisas e fáceis de ler. Eu também recomendo que você faça sua própria pesquisa, há vários posts ótimos sobre este tópico na Web. Feliz codificação!

Deixe uma resposta

O seu endereço de email não será publicado.