É verdade que GOPATH e GOROOT não são mais necessários?

Acontece que os desenvolvedores que estão começando a se familiarizar com o Go frequentemente encontram o problema de escolher um diretório de trabalho para projetos do Go. Portanto, no bate-papo da conferência GolangConf , essa pergunta também foi feita. Os novos esquilos se assustam com as palavras GOPATH e GOROOT . No entanto, nos guias de início rápido da versão atual do Go (1.13), essas duas palavras “assustadoras” não são mencionadas.


Vamos ver o porquê. Para a pureza do experimento, implantei o Ubuntu fresco em uma máquina virtual e instalei o Go de acordo com as instruções do Wiki :


sudo add-apt-repository ppa:longsleep/golang-backports sudo apt-get update sudo apt-get install golang-go 

O Go 1.13 está instalado e pronto para uso:


 $ go version go version go1.13 linux/amd64 $ which go /usr/bin/go $ whereis go go: /usr/bin/go /usr/lib/go /usr/share/go /usr/share/man/man1/go.1.gz 

GOROOT


Sobre o GOROOT já foi perfeitamente escrito em um artigo de 2015 , e essas informações ainda são relevantes.


É engraçado que, na lista de diretórios emitidos pelo último comando (para whereis go ), o GOROOT não seja:


 $ go env GOROOT /usr/lib/go-1.13 

Portanto, por exemplo, se para o IDE precisar especificar o caminho para os arquivos da biblioteca Go padrão, especificarei /usr/lib/go-1.13 . Talvez, nesse cenário, o uso de GOROOT na vida cotidiana termine.


GOPATH e módulos


Parece que neste local é necessário se apressar para instalar o GOPATH , mas não o farei. Na verdade, GOPATHGOPATH definido:


 $ go env GOPATH /home/elena/go 

Estou confortável com a GOPATH em ~/go , o que significa que não vou mudar.


Criarei imediatamente um diretório para o meu primeiro projeto no Go. Isso pode ser feito em qualquer lugar, por exemplo, diretamente no seu diretório pessoal. Além disso, começarei a trabalhar imediatamente com a ferramenta Go Modules :


 $ mkdir ~/hello $ go mod init github.com/rumyantseva/hello go: creating new go.mod: module github.com/rumyantseva/hello 

Para o comando go mod init , especifiquei um caminho de módulo de módulo exclusivo para o meu projeto. Dessa forma, um proxy ou outra ferramenta, se necessário, pode encontrar os arquivos do meu projeto.


Depois de chamar o comando go mod init , o diretório go mod init apareceu no meu diretório pessoal:


 $ tree ~/go /home/elena/go └── pkg └── mod └── cache └── lock 3 directories, 1 file 

Nesse caso, o arquivo de bloqueio (na parte inferior da árvore) ainda está vazio.


O arquivo go.mod apareceu no go.mod ~/hello com o seguinte conteúdo:


 module github.com/rumyantseva/hello go 1.13 

É no go.mod que todas as informações sobre as dependências do meu módulo serão armazenadas posteriormente.


Vamos agora escrever um aplicativo usando uma dependência externa. No diretório ~/hello , crio o arquivo main.go e escrevo o seguinte código:


 package main import ( "github.com/sirupsen/logrus" ) func main() { logrus.Info("Hello, world!") } 

Claro que na vida real escrevi "Olá, mundo!" Você pode ficar sem logrus , mas neste exemplo, esta biblioteca nos ajudará a descobrir onde os arquivos de dependências externas estão armazenados.


Eu inicio o aplicativo da maneira mais simples:


 $ go run main.go go: finding github.com/sirupsen/logrus v1.4.2 go: downloading github.com/sirupsen/logrus v1.4.2 go: extracting github.com/sirupsen/logrus v1.4.2 go: downloading golang.org/x/sys v0.0.0-20190422165155-953cdadca894 go: extracting golang.org/x/sys v0.0.0-20190422165155-953cdadca894 go: finding golang.org/x/sys v0.0.0-20190422165155-953cdadca894 INFO[0000] Hello, world! 

Antes de o aplicativo ser criado e lançado, a ferramenta go mod funcionava. Ele definiu minha dependência externa github.com/sirupsen/logrus , pegou sua versão mais recente v1.4.2 e optou por dependências transitivas.


Uma linha foi adicionada ao arquivo go.mod com uma descrição da dependência do logrus :


 module github.com/rumyantseva/hello go 1.13 require github.com/sirupsen/logrus v1.4.2 // indirect 

O arquivo go.sum também apareceu, no qual, além do hash da dependência do logrus , são armazenadas informações sobre os hashes das dependências transitivas:


 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 

Onde está o próprio código de dependência? Pode ser encontrado em ~/go/pkg/mod . Além disso, somas de verificação e outras informações gerais para trabalhar com dependências serão armazenadas em ~/go/pkg .


Se você já se deparou com a ferramenta go get , sabe que, ao extrair dependências, na verdade clona os repositórios (por exemplo, no caso de git com git clone ). Mas o go mod não funciona dessa maneira. Para o go mod principal unidade de código é o módulo. Módulos são arquivos. Ao trabalhar com dependências go mod , ele explicitamente (se você chamou o comando go mod download ) ou implicitamente (se você começou a compilar o aplicativo) baixa e descompacta arquivos via GOPROXY . Vamos ver como o proxy é definido no Go 1.13 por padrão:


 $ go env GOPROXY https://proxy.golang.org,direct 

Então, como proxy na criação do meu "Olá, mundo!" usado pelo proxy.golang.org . Obviamente, essa variável pode ser alterada escolhendo um repositório diferente de módulos. Por exemplo, você pode implantar sua própria empresa proxy interna, que será armazenada, incluindo bibliotecas internas, cujo código não foi publicado em código aberto.


Em geral, se estou iniciando um novo projeto e não me importo de usar os Módulos Go, talvez eu não saiba nada sobre o GOPATH . O Go criará o diretório ~/go por conta própria quando necessário.


Quando é necessário o GOPATH?


Se você basicamente não usa os Módulos Go (por exemplo, em um projeto herdado), fugir do trabalho mais explícito com o GOPATH pode não ser tão simples.


Para ver o que acontecerá com o meu projeto, se eu decidir não usar o go mod , exclua os arquivos ~/hello/go.mod e ~/hello/go.sum . Também removerei ~/go para retornar ao estado do sistema que eu tinha no início:


 rm -rf ~/go ~/hello/go.mod ~/hello/go.sum 

Somente o arquivo main.go permanece no main.go ~/hello . O que acontece agora se eu tentar executá-lo com go run ?


 $ go run main.go main.go:4:2: cannot find package "github.com/sirupsen/logrus" in any of: /usr/lib/go-1.13/src/github.com/sirupsen/logrus (from $GOROOT) /home/elena/go/src/github.com/sirupsen/logrus (from $GOPATH) 

Aqui estão eles, esses assustadores GOROOT e GOPATH :)


Para compilar o aplicativo, preciso aumentar a dependência no GOPATH . Eu faço isso com o bom e velho go get :


 $ go get -v github.com/sirupsen/logrus github.com/sirupsen/logrus (download) created GOPATH=/home/elena/go; see 'go help gopath' get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/unix?go-get=1 get "golang.org/x/sys/unix": verifying non-authoritative meta tag golang.org/x/sys (download) golang.org/x/sys/unix github.com/sirupsen/logrus 

O que aconteceu Primeiro, crie o diretório ~/go (o especificado como GOPATH ). Em seguida, o processo de clonagem dos repositórios com dependências começou. É engraçado que os repositórios de clonagem pareçam visivelmente mais lentos que a opção quando usamos o go mod para baixar e descompactar módulos. No entanto, o código de dependência agora pode ser encontrado em ~/go/src/ .


A propósito, ainda não havia um cliente git na minha instalação limpa do Ubuntu e, para go get trabalhar, eu tive que instalá-lo.


Eu inicio o aplicativo:


 $ go run main.go INFO[0000] Hello, world! 

Isso funciona!


Isso é apenas no nível do aplicativo, agora não acompanho a versão das dependências externas. E se, devido a uma vulnerabilidade, em algum momento no repositório github.com/sirupsen/logrus não for o logger que eu esperava, mas algum código malicioso? Mais cedo ou mais tarde, ainda preciso de uma ferramenta para trabalhar com dependências e, se por algum motivo o Go Modules não se encaixar, você deverá procurar outra coisa ...


Conclusão


Este artigo não abordou alguns pontos específicos e o trabalho com dependências externas no Go ainda pode causar muitas perguntas. No entanto, novas versões do Go pelo menos não impõem restrições sobre onde os diretórios de trabalho de seus projetos podem ser criados.


Se você estiver iniciando um novo projeto, tente os Módulos Go! Reverter a abordagem antiga para trabalhar com dependências só faz sentido se algo der errado. A propósito, se você preferir armazenar todas as dependências dentro do projeto, o Go Modules suporta o modo de fornecedor.


Se você precisar trabalhar com um projeto existente e, por algum motivo, não quiser convertê-lo em módulos Go, é importante indicar na documentação do projeto os recursos de seu gerenciamento de implantação e dependência. Se os recém-chegados não familiarizados com as antigas abordagens para trabalhar com dependências chegarem ao projeto, será muito mais fácil lidar com o projeto se toda a documentação estiver no local.


A propósito, no dia 7 de outubro na conferência GolangConf , como uma das atividades especiais, estamos planejando uma zona de especialistas em que qualquer pessoa pode fazer perguntas sobre o Go aos membros do comitê do programa da conferência e entusiastas da comunidade go russa. Instalar o Go? Lidar com vícios? Escreva um microsserviço? Isto é para nós!

Source: https://habr.com/ru/post/pt467697/


All Articles