¿Cómo importo una versión específica de un paquete usando go get?


109

proveniente de un Nodeentorno que solía instalar una versión específica de una lib de proveedor en la carpeta del proyecto ( node_modules) diciendo npmque instale esa versión de esa lib desde elpackage.json o incluso directamente desde la consola, así:

$ npm install express@4.0.0

Luego solía importar esa versión de ese paquete en mi proyecto solo con:

var express = require('express');

Ahora, quiero hacer lo mismo con go. ¿Cómo puedo hacer eso? ¿Es posible instalar una versión específica de un paquete? Si es así, utilizando un sistema centralizado$GOPATH , ¿cómo puedo importar una versión en lugar de otra?

Haría algo como esto:

$ go get github.com/wilk/uuid@0.0.1
$ go get github.com/wilk/uuid@0.0.2

Pero entonces, ¿cómo puedo marcar la diferencia durante la importación?


4
No es así, no go getes la herramienta correcta si desea este comportamiento. Puede buscar en Google soluciones a su problema específico.
Wessie

1
Lea esto
kostix


Para Go 1.11 o superior, consulte Módulos Go: stackoverflow.com/questions/53682247/…
Everton

Respuestas:


46

Go 1.11 tendrá una función llamada módulos go y simplemente puede agregar una dependencia con una versión. Sigue estos pasos:

go mod init .
go mod edit -require github.com/wilk/uuid@0.0.1` 
go get -v -t ./...   
go build
go install 

Aquí hay más información sobre ese tema: https://github.com/golang/go/wiki/Modules


4
¿Cómo se hace con go get only? Necesitaba instalar un binario go global en una versión específica
James Tan

7
@JamesTan go get github.com/wilk/uuid@0.0.1(con GO111MODULE=on)
Neil Conway

5
La pregunta estaba usando go get, no go mod.
Bernardo Loureiro

40

Realmente sorprendido de que nadie haya mencionado gopkg.in .

gopkg.ines un servicio que proporciona un contenedor (redireccionamiento) que le permite expresar versiones como URL de repositorios, sin crear realmente repositorios. Ej. gopkg.in/yaml.v1Vs gopkg.in/yaml.v2, a pesar de que ambos viven enhttps://github.com/go-yaml/yaml

Esto no es perfecto si el autor no sigue las prácticas de control de versiones adecuadas (incrementando el número de versión cuando se rompe la compatibilidad con versiones anteriores), pero funciona con ramas y etiquetas.


5
Me gusta (y uso) gopkg, pero el control de versiones no funciona correctamente con los subpaquetes . Solo algo a tener en cuenta.
Alec Thomas

gopkg.in no está completamente probado en versiones antiguas de git, por lo que no funciona correctamente con git <v1.9
BMW

Además, solo funciona para versiones principales. Es inutilizable para garantizar construcciones reproducibles.
CAFxX

26

Puede usar git checkoutpara obtener una versión específica y construir su programa usando esta versión.

Ejemplo:

export GOPATH=~/
go get github.com/whateveruser/whateverrepo
cd ~/src/github.com/whateveruser/whateverrepo
git tag -l
# supose tag v0.0.2 is correct version
git checkout tags/v0.0.2
go run whateverpackage/main.go

La solución entonces sería git checkout e instalar
ptman

@ aliaksei-maniuk nos da una mejor solución. Utilice https://github.com/golang/dep
João Paraná

15

Planeo es una gestión de paquetes realmente elegante para Go, especialmente si vienes del npm de Node o de la carga de Rust.

Se comporta de manera similar a la nueva función de proveedor de Godep en 1.6, pero es mucho más fácil. Sus dependencias y versiones están "bloqueadas" dentro de su directorio projectdir / vendor sin depender de GOPATH.

Instalar con brew (OS X)

$ brew install glide

Inicie el archivo glide.yaml (similar a package.json). Esto también toma los paquetes importados existentes en su proyecto desde GOPATH y luego los copia en el directorio proveedor / del proyecto.

$ glide init

Obtén nuevos paquetes

$ glide get vcs/namespace/package

Actualice y bloquee las versiones de los paquetes. Esto crea un archivo glide.lock en el directorio de su proyecto para bloquear las versiones.

$ glide up

Probé glide y lo he estado usando felizmente para mi proyecto actual.


1
Para completar, aquí está el sitio web de glide: glide.sh Y aquí el repositorio: github.com/Masterminds/glide
Michael Franzl

Desafortunadamente, Glide ya no está "activo", en la página de github sugieren migrar a la administración oficial de paquetes (ahora vaya a los módulos)
damoiser

13

Actualización 18-11-23 : From Go 1.11 mod es un experimento oficial. Consulte la respuesta de @krish.
Actualización 19-01-01 : From Go 1.12 mod sigue siendo un experimento oficial. A partir de Go 1.13, el modo de módulo será el predeterminado para todo el desarrollo.
Actualización 19-10-17 : From Go 1.13 mod es el administrador de paquetes oficial.

https://blog.golang.org/using-go-modules

Respuesta anterior:

Puede configurar la versión por dep oficial

dep ensure --add github.com/gorilla/websocket@1.2.0

3
La pregunta estaba usando go get, no dep.
Bernardo Loureiro


9

depes el experimento oficial para la gestión de dependencias para el lenguaje Go. Requiere Go 1.8 o más reciente para compilar.

Para comenzar a administrar las dependencias usando dep, ejecute el siguiente comando desde el directorio raíz de su proyecto:

dep init

Después de la ejecución, se generarán dos archivos: Gopkg.toml("manifiesto"), Gopkg.locky los paquetes necesarios se descargarán envendor directorio.

Supongamos que tiene el proyecto que usa github.com/gorilla/websocketpackage. depgenerará los siguientes archivos:

Gopkg.toml

# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
#   name = "github.com/user/project"
#   version = "1.0.0"
#
# [[constraint]]
#   name = "github.com/user/project2"
#   branch = "dev"
#   source = "github.com/myfork/project2"
#
# [[override]]
#  name = "github.com/x/y"
#  version = "2.4.0"


[[constraint]]
  name = "github.com/gorilla/websocket"
  version = "1.2.0"

Gopkg.lock

# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.


[[projects]]
  name = "github.com/gorilla/websocket"
  packages = ["."]
  revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
  version = "v1.2.0"

[solve-meta]
  analyzer-name = "dep"
  analyzer-version = 1
  inputs-digest = "941e8dbe52e16e8a7dff4068b7ba53ae69a5748b29fbf2bcb5df3a063ac52261"
  solver-name = "gps-cdcl"
  solver-version = 1

Hay comandos que lo ayudan a actualizar / eliminar / etc paquetes, encuentre más información en el repositorio oficial de github de dep(herramienta de administración de dependencias para Go).


7

Hoy en día solo puedes usarlo go get. Puede buscar su dependencia por la etiqueta de versión, rama o incluso la confirmación.

go get github.com/someone/some_module@master
go get github.com/someone/some_module@v1.1.0
go get github.com/someone/some_module@commit_hash

más detalles aquí - ¿Cómo apuntar la dependencia del módulo Go en go.mod a una última confirmación en un repositorio?

Go gettambién instalará el binario, como dice en la documentación -

Get downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.

(de https://golang.org/cmd/go/ )


4

go get es el administrador de paquetes de Go. Funciona de una manera completamente descentralizada y aún es posible el descubrimiento de paquetes sin un repositorio central de alojamiento de paquetes.

Además de localizar y descargar paquetes, la otra gran función de un administrador de paquetes es manejar múltiples versiones del mismo paquete. Go adopta el enfoque más mínimo y pragmático de cualquier administrador de paquetes. No existen versiones múltiples de un paquete Go.

go get siempre extrae del HEAD de la rama predeterminada en el repositorio. Siempre. Esto tiene dos implicaciones importantes:

  1. Como autor de un paquete, debe adherirse a la filosofía HEAD estable. Su rama predeterminada siempre debe ser la versión estable y publicada de su paquete. Debe trabajar en las ramas de funciones y solo fusionar cuando esté listo para lanzar.

  2. Las nuevas versiones principales de su paquete deben tener su propio repositorio. En pocas palabras, cada versión principal de su paquete (siguiendo el control de versiones semántico) tendría su propio repositorio y, por lo tanto, su propia ruta de importación.

    por ejemplo, github.com/jpoehls/gophermail-v1 y github.com/jpoehls/gophermail-v2.

Como alguien que crea una aplicación en Go, la filosofía anterior realmente no tiene inconvenientes. Cada ruta de importación es una API estable. No hay números de versión de los que preocuparse. ¡Increíble!

Para más detalles: http://zduck.com/2014/go-and-package-versioning/


45
Sus afirmaciones sobre la funcionalidad de las herramientas go son correctas, pero casi nadie incorpora versiones en sus nombres de repositorio de git, y muchas personas no tratan a master / HEAD como una API estable. Actualmente tengo un pequeño servicio con unas ocho dependencias; solo uno tiene un número de versión. Amazon impulsó un cambio radical en github.com/aws/aws-sdk-go. go getEl almacenamiento en caché significa que no se da cuenta por un tiempo, a menos que tenga un servidor de compilación que lo actualice a la última versión cada vez. Hay administradores de paquetes de terceros, pero en su mayoría son basura.
Dhasenan

19
@faisal_kk debes estar viviendo en un mundo de sueños. En el mundo REAL de la maravillosa comunidad de código abierto, todos se adhieren a su propia filosofía. No existen los lanzamientos de ramificación, me alegro de que tengamos etiquetas.

28
¿Crear un repositorio para cada versión? Es una locura
deFreitas

8
Este es un comportamiento fundamentalmente incorrecto. El código fuente NO es lo mismo que un paquete publicado, y no puede incluir autores de paquetes para garantizar la compatibilidad hacia atrás / adelante. No porque los desarrolladores sean incompetentes, sino porque esto es teóricamente imposible cuando el número de dependencias de paquetes aumenta más allá de una. Go get, por lo tanto, está destinado a seguir el mismo camino que Bower, cuyo principal defecto era exactamente el mismo. El control de versiones semántico tampoco es lo suficientemente fuerte, las sumas de comprobación binarias son realmente el único camino a seguir.
Gudlaugur Egilsson

5
"No hay números de versión de los que preocuparse. ¡Impresionante!" Esa tiene que ser la declaración más absurda en una respuesta SO. El control de versiones está ahí por una razón. La falta de un administrador de paquetes en Go que tenga una configuración incorporada o un mecanismo orientado a comandos para el control de versiones de las dependencias no implica que el control de versiones sea una molestia. ¡Votación en contra!
Harindaka

2

El enfoque que encontré viable es el sistema de submódulos de git . Con eso, puede submódulo en una versión determinada del código y la actualización / degradación es explícita y registrada, nunca al azar.

La estructura de carpetas que he tomado con esto es:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.

Yo también utilizo este enfoque. Esencialmente, sigue la misma estructura de carpetas que go get, pero le permite un mejor control sobre la versión que está adquiriendo.
Brad Peabody

la respuesta no responde a la pregunta con los criterios formulados (usando go get)
Baptiste Mille-Mathias

2

Eso funcionó para mi

GO111MODULE=on go get -u github.com/segmentio/aws-okta@v0.22.1


2

Hay un comando go edit -replace para agregar una confirmación específica (incluso de otro repositorio bifurcado) sobre la versión actual de un paquete. Lo bueno de esta opción es que no necesita saber la pseudoversión exacta de antemano, solo el ID de hash de confirmación .

Por ejemplo, estoy usando la versión estable del paquete "github.com/onsi/ginkgo v1.8.0".

Ahora quiero, sin modificar esta línea del paquete requerido en go.mod, agregar un parche de mi fork, además de la versión de ginkgo:

$ GO111MODULE="on"  go mod edit -replace=github.com/onsi/ginkgo=github.com/manosnoam/ginkgo@d6423c2

Después de la primera vez que compile o pruebe su módulo, GO intentará extraer la nueva versión y luego generará la línea "reemplazar" con la pseudoversión correcta. Por ejemplo, en mi caso, se agregará en la parte inferior de go.mod:

reemplazar github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451


2

Una pequeña hoja de trucos sobre consultas de módulos.

Para comprobar todas las versiones existentes: p. Ej. go list -m -versions github.com/gorilla/mux

  1. Versión específica @ v1.2.8
  2. Confirmación específica @ c783230
  3. Confirmación específica @master
  4. Prefijo de versión @ v2
  5. Comparación @> = 2.1.5
  6. Último @latest

P.ej go get github.com/gorilla/mux@v1.7.4

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.