Comment importer une version spécifique d'un package à l'aide de go get?


109

provenant d'un Nodeenvironnement que j'avais l'habitude d'installer une version spécifique d'une bibliothèque de fournisseur dans le dossier du projet ( node_modules) en disant npmd'installer cette version de cette bibliothèque à partir de package.jsonou même directement à partir de la console, comme ceci:

$ npm install express@4.0.0

Ensuite, j'avais l'habitude d'importer cette version de ce package dans mon projet simplement avec:

var express = require('express');

Maintenant, je veux faire la même chose avec go. Comment puis je faire ça? Est-il possible d'installer une version spécifique d'un package? Si c'est le cas, en utilisant une version centralisée $GOPATH, comment puis-je importer une version au lieu d'une autre?

Je ferais quelque chose comme ça:

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

Mais alors, comment puis-je faire une différence lors de l'importation?


4
Vous n'avez pas, go getn'est pas l'outil approprié si vous voulez ce comportement. Vous pouvez rechercher des solutions à votre problème spécifique sur Google.
Wessie

1
Lire ceci
kostix


Pour Go 1.11 ou version ultérieure, voir Modules Go: stackoverflow.com/questions/53682247/...
Everton

Réponses:


47

Go 1.11 aura une fonctionnalité appelée modules go et vous pourrez simplement ajouter une dépendance avec une version. Suivez ces étapes:

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

Voici plus d'informations sur ce sujet - https://github.com/golang/go/wiki/Modules


4
comment faire avec aller chercher seulement? j'avais besoin d'installer un binaire global go vers une version spécifique
James Tan

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

5
La question utilisait go get, non go mod.
Bernardo Loureiro

40

Vraiment surpris, personne n'a mentionné gopkg.in .

gopkg.inest un service qui fournit un wrapper (redirection) qui vous permet d'exprimer des versions sous forme d'URL de dépôt, sans créer réellement de dépôts. Par exemple gopkg.in/yaml.v1vs gopkg.in/yaml.v2, même s'ils vivent tous les deux àhttps://github.com/go-yaml/yaml

Ce n'est pas parfait si l'auteur ne suit pas les bonnes pratiques de gestion des versions (en incrémentant le numéro de version lors de la rupture de la compatibilité descendante), mais cela fonctionne avec les branches et les balises.


5
J'aime (et j'utilise) gopkg, mais la gestion des versions ne fonctionne pas correctement avec les sous-packages. Juste quelque chose dont il faut être conscient.
Alec Thomas

gopkg.in n'est pas entièrement testé dans les anciennes versions de git, il ne fonctionne donc pas correctement avec git <v1.9
BMW

En outre, cela ne fonctionne que pour les versions majeures. Il est inutilisable de garantir des constructions reproductibles.
CAFxX

26

Vous pouvez utiliser git checkoutpour obtenir une version spécifique et créer votre programme en utilisant cette version.

Exemple:

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 solution serait alors de git checkout et d'aller installer
ptman

@ aliaksei-maniuk nous donne une meilleure solution. Utilisez https://github.com/golang/dep
João Paraná

15

Glide est une gestion de paquets très élégante pour Go, surtout si vous venez du npm de Node ou de la cargaison de Rust.

Il se comporte étroitement avec la nouvelle fonctionnalité de fournisseur de Godep dans la version 1.6, mais est beaucoup plus facile. Vos dépendances et versions sont "verrouillées" dans votre répertoire projectdir / vendor sans dépendre de GOPATH.

Installer avec infusion (OS X)

$ brew install glide

Lancez le fichier glide.yaml (semblable à package.json). Cela récupère également les packages importés existants dans votre projet à partir de GOPATH et les copie ensuite dans le répertoire fournisseur / du projet.

$ glide init

Obtenez de nouveaux packages

$ glide get vcs/namespace/package

Mettez à jour et verrouillez les versions des packages. Cela crée un fichier glide.lock dans le répertoire de votre projet pour verrouiller les versions.

$ glide up

J'ai essayé le glide et je l'ai utilisé avec plaisir pour mon projet actuel.


1
Pour être complet, voici le site de glide: glide.sh Et voici le repo: github.com/Masterminds/glide
Michael Franzl

malheureusement Glide n'est plus "actif", sur la page github ils suggèrent de migrer vers la gestion officielle des paquets (maintenant allez modules)
damoiser

13

Mise à jour 18-11-23 : From Go 1.11 mod est une expérience officielle. Veuillez consulter la réponse @krish.
Mise à jour 19-01-01 : From Go 1.12 mod est toujours une expérience officielle. À partir de Go 1.13, le mode module sera le mode par défaut pour tous les développements.
Mise à jour 19-10-17 : From Go 1.13 mod est le gestionnaire de paquets officiel.

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

Ancienne réponse:

Vous pouvez définir la version par dep officiel

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

3
La question utilisait go get, non dep.
Bernardo Loureiro


9

depest l'expérience officielle de gestion des dépendances pour le langage Go. Il nécessite Go 1.8 ou plus récent pour être compilé.

Pour commencer à gérer les dépendances à l'aide de dep, exécutez la commande suivante à partir du répertoire racine de votre projet:

dep init

Après l'exécution, deux fichiers seront générés: Gopkg.toml("manifest"), Gopkg.locket les packages nécessaires seront téléchargés dans le vendorrépertoire.

Supposons que vous ayez le projet qui utilise github.com/gorilla/websocketpackage. depgénérera les fichiers suivants:

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

Il existe des commandes qui vous aident à mettre à jour / supprimer les packages / etc, veuillez trouver plus d'informations sur le référentiel github officiel de dep(outil de gestion des dépendances pour Go).


7

De nos jours, vous pouvez simplement l'utiliser go get. Vous pouvez récupérer votre dépendance par la balise de version, la branche ou même le commit.

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

plus de détails ici - Comment pointer la dépendance du module Go dans go.mod vers un dernier commit dans un dépôt?

Go getégalement installer le binaire, comme il est dit dans la documentation -

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

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


4

go get est le gestionnaire de paquets Go. Cela fonctionne de manière complètement décentralisée et comment la découverte de paquets est toujours possible sans un référentiel central d'hébergement de paquets.

Outre la localisation et le téléchargement de packages, l'autre grand rôle d'un gestionnaire de packages est de gérer plusieurs versions du même package. Go adopte l'approche la plus minimale et la plus pragmatique de tous les gestionnaires de packages. Il n'existe pas de versions multiples d'un package Go.

go get tire toujours de la HEAD de la branche par défaut dans le référentiel. Toujours. Cela a deux conséquences importantes:

  1. En tant qu'auteur de package, vous devez adhérer à la philosophie stable HEAD. Votre branche par défaut doit toujours être la version stable et publiée de votre package. Vous devez travailler dans les branches de fonctionnalités et ne fusionner que lorsque vous êtes prêt à publier.

  2. Les nouvelles versions majeures de votre package doivent avoir leur propre référentiel. En termes simples, chaque version majeure de votre package (après le contrôle de version sémantique) aurait son propre référentiel et donc son propre chemin d'importation.

    par exemple github.com/jpoehls/gophermail-v1 et github.com/jpoehls/gophermail-v2.

En tant que personne qui construit une application en Go, la philosophie ci-dessus n'a vraiment pas d'inconvénient. Chaque chemin d'importation est une API stable. Il n'y a pas de numéros de version à craindre. Impressionnant!

Pour plus de détails: http://zduck.com/2014/go-and-package-versioning/


45
Vos déclarations sur la fonctionnalité des outils go sont correctes, mais presque personne n'incorpore des versions dans leurs noms de référentiel git, et de nombreuses personnes ne traitent pas master / HEAD comme une API stable. J'ai actuellement un petit service avec environ huit dépendances; un seul a un numéro de version. Amazon a poussé un changement radical à github.com/aws/aws-sdk-go. go getLa mise en cache signifie que vous ne le remarquez pas pendant un certain temps à moins que vous n'ayez un serveur de build qui vous met à jour à chaque fois avec la dernière version. Il existe des gestionnaires de paquets tiers, mais ils sont pour la plupart grossiers.
dhasenan

19
@faisal_kk vous devez vivre dans un monde de rêve. Dans le monde RÉEL de la merveilleuse communauté open-source, chacun adhère à sa propre philosophie. Le branchement des versions n'existe pas, je suis content que nous ayons des tags.

28
Créer un référentiel pour chaque version? Il est fou
deFreitas

8
C'est un comportement fondamentalement mauvais. Le code source n'est PAS le même qu'un package publié, et vous ne pouvez pas mettre sur les auteurs de packages pour assurer la compatibilité ascendante / ascendante. Non pas parce que les développeurs sont incompétents, mais parce que cela est théoriquement impossible lorsque le nombre de dépendances de packages augmente au-delà d'un. Go get est donc destiné à suivre le même chemin que bower, dont le principal défaut était exactement le même. Le versionnage sémantique n'est pas assez fort non plus, les sommes de contrôle binaires sont vraiment la seule voie à suivre.
Gudlaugur Egilsson

5
"Il n'y a pas de numéro de version à s'inquiéter. Génial!" Cela doit être la déclaration la plus absurde dans une réponse SO. Le contrôle de version est là pour une raison. L'absence de Go d'un gestionnaire de paquets qui a une configuration intégrée ou un mécanisme orienté commande pour la versionnage des dépendances en soi n'implique pas que la versionnage est une nuisance. Downvoter!
Harindaka

2

L'approche que j'ai trouvée viable est le système de sous-modules de git . En utilisant cela, vous pouvez sous-module dans une version donnée du code et la mise à niveau / rétrogradation est explicite et enregistrée - jamais au hasard.

La structure de dossier que j'ai prise avec ceci est:

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

J'utilise aussi cette approche. Essentiellement, il suit la même structure de dossiers que go get, mais vous permet de mieux contrôler la version que vous achetez.
Brad Peabody

la réponse ne répond pas à la question avec les critères demandés (en utilisant go get)
Baptiste Mille-Mathias

2

Cela a fonctionné pour moi

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


2

Il existe une commande go edit -replace pour ajouter un commit spécifique (même à partir d'un autre référentiel forké) par-dessus la version actuelle d'un package. Ce qui est cool avec cette option, c'est que vous n'avez pas besoin de connaître au préalable la pseudo version exacte , juste l' ID de hachage du commit .

Par exemple, j'utilise la version stable du package "github.com/onsi/ginkgo v1.8.0".

Maintenant, je veux - sans modifier cette ligne de package requis dans go.mod - ajouter un correctif de mon fork, en plus de la version ginkgo:

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

Après la première fois que vous construisez ou testez votre module, GO essaiera d'extraire la nouvelle version, puis générera la ligne «remplacer» avec la pseudo version correcte. Par exemple dans mon cas, il ajoutera en bas de go.mod:

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


2

Une petite feuille de triche sur les requêtes de module.

Pour vérifier toutes les versions existantes: par exemple go list -m -versions github.com/gorilla/mux

  1. Version spécifique @ v1.2.8
  2. Commit spécifique @ c783230
  3. Commit spécifique @master
  4. Préfixe de version @ v2
  5. Comparaison @> = 2.1.5
  6. Dernier @latest

Par exemple go get github.com/gorilla/mux@v1.7.4

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.