Introducción
Para gestionar dependencias en Go, anteriormente se utilizaba principalmente glide. A continuación se presenta información sobre la herramienta de gestión de versiones oficial que apareció en Go 1.11, conocida como mod.
Para comprender mejor su funcionamiento, el equipo oficial de Go proporciona tres comandos de ayuda: go help mod, go help modules y go help module-get.
Configuración de GO111MODULE
La variable de entorno GO111MODULE permite activar o desactivar el soporte para módulos. Esta varialbe acepta tres valores: off, on y auto, siendo auto el valor predeterminado.
- GO111MODULE=off: Sin soporte de módulos. Go buscará paquetes en la ruta
GOPATHy en la carpetavendor. - GO111MODULE=on: Con soporte de módulos. Go ignorará
GOPATHyvendor, utilizando únicamentego.modpara descargar dependencias. - GO111MODULE=auto: Activación automática cuando se trabaja fuera de
$GOPATH/srcy existe un archivogo.moden el directorio raíz.
Al trabajar con módulos, la variable GOPATH pierde relevancia para la resolución de dependencias. Sin embargo, las dependencias descargadas se almacenan en $GOPATH/pkg/mod, los resultados de go install se placed en $GOPATH/bin.
Comandos de Go Mod
A continuación se detallan los comandos principales disponibles:
download descarga módulos al caché local
edit edita el archivo go.mod desde herramientas o scripts
graph muestra el gráfico de dependencias de módulos
init inicializa un nuevo módulo en el directorio actual
tidy agrega módulos faltantes y elimina los no utilizados
vendor crea una copia de las dependencias en vendor
verify verifica que las dependencias tengan el contenido esperado
why explica por qué se necesitan ciertos paquetes o módulos
Uso de Go Mod
Creación del archivo go.mod
En un proyecto nuevo, es necesario ejecutar go mod init para inicializar y crear el archivo go.mod, el cual contendrá las rutas y versiones de todas las dependencias.
module github.com/miusuario/observador
require (
github.com/apex/log v1.0.0
github.com/fatih/color v1.7.0 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/go-ini/ini v1.38.2
github.com/go-kit/kit v0.7.0
github.com/go-logfmt/logfmt v0.3.0 // indirect
)
La etiqueta indirect indica que la librería fue incluida de manera transitiva.
El comando go mod vendor permite crear una carpeta vendor en el proyecto y copiar todas las dependencias allí.
El comando go mod download almacena las dependencias en el caché local para su uso posterior.
Visualización de información de librerías importadas
go list -m -json all
-json: Muestra la información en formato JSONall: Muestra todas las librerías
Ruta del caché de módulos
Por defecto, el caché se encuentra en $GOPATH/pkg:
$GOPATH/pkg/mod
A continuación se muestra la estructura de archivos descargados para un proyecto:
mod ls -lh cache/download/github.com/go-kit/kit/@v/
total 3016
-rw-r--r-- 1 usuario staff 7B Sep 29 15:37 list
-rw------- 1 usuario staff 50B Sep 29 15:37 v0.7.0.info
-rw------- 1 usuario staff 29B Sep 29 15:37 v0.7.0.mod
-rw-r--r-- 1 usuario staff 1.5M Sep 29 15:37 v0.7.0.zip
-rw-r--r-- 1 usuario staff 47B Sep 29 15:37 v0.7.0.ziphash
Se puede observar que para cada versión de una librería se crea una carpeta отдельная que contiene información específica de dicha versión.
Problema conocido: go mod no puede descargar paquetes de google
Para la mayoría de desarrolladores de Go en el mundo, la introducción de Go modules trajo grandes beneficios. Sin embargo, para aquellos que se encuentran en determinadas regiones con restricciones de red, esta ventaja viene acompañada de algunas dificultades.
El motivo radica en que, en modo módulo, Go ya no busca paquetes en la ubicación tradicional de GOPATH ni en el directorio vendor, sino que utiliza el caché local en GOPATH/pkg/mod (en Go 1.11 era esta ubicación, aunque podría variar en versiones posteriores).
Como es ampliamente conocido, en ciertas regiones no es posible utilizar go get ni git clone para obtener algunos paquetes de terceros. El caso más común son los paquetes bajo golang.org/x. En el modo tradicional GOPATH, existía una solución alternativa: clonar primero los paquetes desde mirrors en GitHub y luego renombrarlos a golang.org/x/xxx. También era posible colocar estos paquetes en el directorio vendor y commitearlos al repositorio.
Sin embargo, tras la llegada de los módulos, una vez activado el modo módulo, go build ya no considera los paquetes en GOPATH ni en vendor. En su lugar, consulta el caché en GOPATH/pkg/mod; si no encuentra el módulo, procederá a descargar una versión específica. Para los módulos bajo golang.org/x/xxx, esta descarga suele fallar en regiones con restricciones.
Algunos podrían sugerir continuar utilizando mirrors y renombrando paquetes. En teoría es posible, pero en la práctica resulta bastante tedioso. Veamos la estructura del directorio de caché local de Go modules:
/Users/usuario/go/pkg/mod $tree -L 7
.
├── cache
│ └── download
│ └── golang.org
│ └── x
│ └── text
│ └── @v
│ ├── list
│ ├── v0.1.0.info
│ ├── v0.1.0.mod
│ ├── v0.1.0.zip
│ ├── v0.1.0.ziphash
│ ├── v0.3.0.info
│ ├── v0.3.0.mod
│ ├── v0.3.0.zip
│ └── v0.3.0.ziphash
└── golang.org
└── x
├── text@v0.1.0
└── text@v0.3.0
La estructura del directorio mod está cuidadosamente diseñada. En cache/download se almacena la "metainformación" de cada módulo, junto con archivos zip de cada versión. En este ejemplo se可以看到 para el módulo golang.org/x/text existen dos versiones (v0.1.0 y v0.3.0) con su información y código fuente correspondiente.
Si se intentara replicar el enfoque del modo GOPATH mediante "descarga desde mirror más renombrado", sería necesario crear manualmente la metainformación para cada versión del módulo, incluyendo los archivos como xx.info, xxx.mod, entre otros. Este enfoque resulta poco práctico y su "experiencia de usuario" no es óptima.
Solución: Go Module Proxy
Entonces, ¿cómo pueden los desarrolladores en regiones con restricciones de red disfrutar de los beneficios de Go modules? ¡El problema tiene solución! La respuesta se encuentra en Go 1.11.
Junto con la introducción de Go modules, Go 1.11 también incorporó el concepto de Go module proxy (consultar go help goproxy).
De manera predeterminada, el comando go get, ya sea en modo GOPATH o en modo módulo, descarga directamente los módulos desde servicios VCS como GitHub o GitLab. Sin embargo, en Go 1.11 es posible modificar este comportamiento mediante la variable de entorno GOPROXY, permitiendo que los comandos de Go descarguen módulos desde otras fuentes.
Por ejemplo:
export GOPROXY=https://goproxy.io
Una vez configurado de esta manera, los comandos de Go utilizarán el protocolo de descarga de módulos para interactuar con el proxy y descargar la versión específica del módulo.
Si se configura un servidor proxy de módulos de Go en un VPS extranjero, sería posible descargar módulos como los ubicados bajo golang.org/x. Además, otros problemas secundarios como la lentitud al obtener paquetes desde GitHub podrían verse solucionados.
Aunque el propósito original de Go proxy no fue resolver las limitaciones de descarga en regiones con restricciones de red, es innegable que GOPROXY proporciona a los desarrolladores mayor control y capacidad de intervención sobre la obtención de módulos y paquetes, basándose en el sistema de versionado de Go.
Referencias
- 初窥Go module
- Introduction to Go Modules
- https://ieevee.com/tech/2018/...
- https://colobu.com/2018/08/27...
- https://studygolang.com/artic...