¿Es cierto que GOPATH y GOROOT ya no son necesarios?

Dio la casualidad de que los desarrolladores que recién comienzan a familiarizarse con Go a menudo encuentran el problema de elegir un directorio de trabajo para los proyectos de Go. Entonces, en el chat de la conferencia GolangConf , también se hizo esta pregunta. Los nuevos gophers a menudo se asustan con las palabras GOPATH y GOROOT . Sin embargo, en las guías de inicio rápido con la versión actual de Go (1.13), estas dos palabras "aterradoras" no se mencionan en absoluto.


A ver por qué. Para la pureza del experimento, implementé Ubuntu nuevo en una máquina virtual e instalé Go de acuerdo con las instrucciones de Wiki :


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

Go 1.13 está instalado y listo para usar:


 $ 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


Acerca de GOROOT ya se ha escrito perfectamente en un artículo de 2015 , y esta información sigue siendo relevante.


Es curioso que entre la lista de directorios emitidos por el último comando ( whereis go ), GOROOT realidad no es:


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

Entonces, por ejemplo, si para el IDE necesito especificar la ruta a los archivos de la biblioteca Go estándar, especificaré /usr/lib/go-1.13 . Quizás, en este escenario, el uso de GOROOT en la vida cotidiana termina.


GOPATH y módulos


Parece que en este lugar es necesario apresurarse para instalar GOPATH , pero no lo haré. En realidad, GOPATH ya GOPATH configurado:


 $ go env GOPATH /home/elena/go 

Me siento cómodo con la GOPATH en ~/go , lo que significa que no la cambiaré.


Inmediatamente crearé un directorio para mi primer proyecto en Go. Esto se puede hacer en cualquier lugar, por ejemplo, directamente en su directorio de inicio. Además, comenzaré a trabajar inmediatamente con la herramienta Go Modules :


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

Para el comando go mod init , especifiqué una ruta de módulo de módulo única para mi proyecto. De esta manera, un proxy u otra herramienta, si es necesario, puede encontrar los archivos de mi proyecto.


Después de llamar al comando go mod init , el directorio go mod init apareció en mi directorio de inicio:


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

En este caso, el archivo de bloqueo (en la parte inferior del árbol) todavía está vacío.


El archivo go.mod apareció en el go.mod ~/hello con los siguientes contenidos:


 module github.com/rumyantseva/hello go 1.13 

Es en go.mod que toda la información sobre las dependencias de mi módulo se almacenará posteriormente.


Ahora escribamos una aplicación usando una dependencia externa. En el directorio ~/hello , creo el archivo main.go y escribo el siguiente código:


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

Por supuesto en la vida real por escribir "¡Hola, mundo!" Puede prescindir de logrus , pero en este ejemplo, esta biblioteca nos ayudará a descubrir dónde se almacenan los archivos de dependencias externas.


Lanzo la aplicación de la manera más simple:


 $ 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 que la aplicación fuera construida y lanzada, la herramienta go mod funcionaba. Definió mi dependencia externa github.com/sirupsen/logrus , tomó su última versión v1.4.2 y v1.4.2 por dependencias transitivas.


Se agregó una línea al archivo go.mod con una descripción de la dependencia de logrus :


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

También apareció el archivo go.sum , en el que, además del hash de la dependencia logrus , se almacena información sobre hash de dependencias 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= 

¿Dónde está el código de dependencia en sí? Se puede encontrar en ~/go/pkg/mod . Además, las sumas de verificación y otra información general para trabajar con dependencias se almacenarán en ~/go/pkg .


Si ya ha encontrado la herramienta go get , sabe que al extraer dependencias, en realidad clona los repositorios (por ejemplo, en el caso de git con git clone ). Pero go mod no funciona de esa manera. Para go mod unidad principal de código es el módulo. Los módulos son archivos. Cuando se trabaja con dependencias go mod , explícitamente (si invocó el comando go mod download ) o implícitamente (si comenzó a compilar la aplicación) descarga y desempaqueta archivos a través de GOPROXY . Veamos cómo se establece el proxy en Go 1.13 de manera predeterminada:


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

Entonces, como proxy cuando construyo mi "¡Hola, Mundo!" utilizado por proxy.golang.org . Por supuesto, esta variable se puede cambiar eligiendo un repositorio diferente de módulos. Por ejemplo, puede implementar su propia compañía de proxy interna, que se almacenará, incluidas las bibliotecas internas, cuyo código no se publicó en código abierto.


En general, si estoy comenzando un nuevo proyecto y no me importa usar Go Modules, es posible que no sepa nada sobre GOPATH . Go creará el directorio ~/go por sí solo cuando sea necesario.


¿Cuándo se necesita GOPATH?


Si básicamente no utiliza los módulos Go (por ejemplo, en un proyecto heredado), alejarse del trabajo más explícito con GOPATH puede no ser tan simple.


Para ver qué sucederá con mi proyecto, si decido no usar go mod , elimine los archivos ~/hello/go.mod y ~/hello/go.sum . También eliminaré ~/go para volver al estado del sistema que tenía al principio:


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

Solo el archivo main.go permanece en el main.go ~/hello . ¿Qué sucede ahora si trato de ejecutarlo con 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) 

Aquí están, estos terroríficos GOROOT y GOPATH :)


Para compilar la aplicación, necesito extraer la dependencia en GOPATH . Hago esto con el buen viejo 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 

Que paso En primer lugar, go get crear el directorio ~/go (el especificado como GOPATH ). Entonces comenzó el proceso de clonación de los repositorios con dependencias. Es curioso que los repositorios de clonación parezcan notablemente más lentos que la opción cuando usamos go mod para descargar y descomprimir módulos. Sin embargo, el código de dependencia ahora se puede encontrar dentro de ~/go/src/ .


Por cierto, todavía no había un cliente git en mi instalación limpia de Ubuntu, y para go get trabajar, tuve que instalarlo.


Lanzo la aplicación:


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

Funciona!


Eso es solo en el nivel de la aplicación, ahora no hago un seguimiento de la versión de las dependencias externas. ¿Qué github.com/sirupsen/logrus si, debido a una vulnerabilidad, en algún momento en el repositorio github.com/sirupsen/logrus no es el registrador que esperaba, sino algún código malicioso? Tarde o temprano, todavía necesito una herramienta para trabajar con dependencias, y si Go Modules por alguna razón no encaja, debe buscar otra cosa ...


Conclusión


Este artículo no abordó algunos puntos específicos, y trabajar con dependencias externas en Go todavía puede causar muchas preguntas. Sin embargo, las nuevas versiones de Go al menos no imponen restricciones sobre dónde se pueden crear los directorios de trabajo de sus proyectos.


Si está comenzando un nuevo proyecto, pruebe Go Modules! Volver al viejo enfoque para trabajar con dependencias solo tiene sentido si algo sale mal. Por cierto, si prefiere almacenar todas las dependencias dentro del proyecto, Go Modules admite el modo de proveedor.


Si necesita trabajar con un proyecto existente y, por alguna razón, no desea traducirlo a Go Modules, es importante indicar en la documentación del proyecto las características de su implementación y administración de dependencias. Si los recién llegados que no están familiarizados con los viejos enfoques para trabajar con dependencias llegan al proyecto, será mucho más fácil para ellos lidiar con el proyecto si toda la documentación está en su lugar.


Por cierto, el 7 de octubre en la conferencia GolangConf , como una de las actividades especiales, estamos planeando una zona de expertos donde cualquiera puede hacer cualquier pregunta sobre Ir a los miembros del comité del programa de la conferencia y los entusiastas de la comunidad rusa de Go. Instalar Ir? Lidiar con las adicciones? ¿Escribir un microservicio? Esto es para nosotros!

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


All Articles