Jak zaimportować określoną wersję pakietu za pomocą go get?

109

pochodzący ze Nodeśrodowiska, którego używałem do instalowania określonej wersji biblioteki dostawcy w folderze projektu ( node_modules), nakazując npmzainstalowanie tej wersji tej biblioteki z package.jsonkonsoli lub nawet bezpośrednio z konsoli, na przykład:

$ npm install express@4.0.0

Następnie zaimportowałem tę wersję tego pakietu do mojego projektu za pomocą:

var express = require('express');

Teraz chcę zrobić to samo z go. Jak mogę to zrobić? Czy można zainstalować określoną wersję pakietu? Jeśli tak, używając scentralizowanego $GOPATH, jak mogę zaimportować jedną wersję zamiast drugiej?

Zrobiłbym coś takiego:

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

Ale jak mogę to zmienić podczas importu?

Wilk
źródło
4
Nie, nie go getjest właściwym narzędziem, jeśli chcesz tego zachowania. Możesz wyszukiwać rozwiązania konkretnego problemu.
Wessie,
1
Przeczytaj to
kostix
stackoverflow.com/questions/30188499/… To też wygląda pomocne
Earlonrails
Dla Go 1.11 lub nowszego, zobacz Go Modules: stackoverflow.com/questions/53682247/…
Everton

Odpowiedzi:

47

Wersja 1.11 będzie miała funkcję o nazwie moduły go i możesz po prostu dodać zależność do wersji. Wykonaj następujące kroki:

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

Oto więcej informacji na ten temat - https://github.com/golang/go/wiki/Modules

krish
źródło
4
jak to się robi, gdy idzie tylko? Musiałem zainstalować globalny plik binarny go do określonej wersji
James Tan
7
@JamesTan go get github.com/wilk/[email protected](z GO111MODULE=on)
Neil Conway
5
Pytanie było używane go get, nie go mod.
Bernardo Loureiro
40

Naprawdę zaskoczony, nikt nie wspomniał o gopkg.in .

gopkg.into usługa zapewniająca opakowanie (przekierowanie), które umożliwia wyrażanie wersji jako adresów URL repozytoriów, bez faktycznego tworzenia repozytoriów. Np. gopkg.in/yaml.v1Vs gopkg.in/yaml.v2, mimo że oboje mieszkają przy ulhttps://github.com/go-yaml/yaml

Nie jest to idealne rozwiązanie, jeśli autor nie przestrzega odpowiednich praktyk wersjonowania (zwiększając numer wersji podczas łamania wstecznej zgodności), ale działa z gałęziami i znacznikami.

Steven Soroka
źródło
5
Lubię (i używam) gopkg, ale wersjonowanie nie działa poprawnie z pakietami podrzędnymi. Po prostu coś, o czym należy pamiętać.
Alec Thomas,
gopkg.in nie jest w pełni przetestowany w starszych wersjach git, więc nie działa poprawnie z git <v1.9
BMW
Ponadto działa tylko w przypadku głównych wersji. Nie można jej zagwarantować, że kompilacje będą odtwarzalne.
CAFxX
26

Możesz użyć git checkout aby uzyskać określoną wersję i zbudować swój program przy użyciu tej wersji.

Przykład:

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
João Paraná
źródło
Rozwiązaniem byłoby git checkout i instalacja
ptman
@ aliaksei-maniuk daje nam lepsze rozwiązanie. Użyj https://github.com/golang/dep
João Paraná
15

Poślizg to naprawdę eleganckie zarządzanie pakietami dla Go, szczególnie jeśli pochodzisz z npm Node lub ładunku Rusta.

Zachowuje się podobnie do nowej funkcji dostawcy Godep w wersji 1.6, ale jest znacznie łatwiejsza. Twoje zależności i wersje są „zablokowane” wewnątrz katalogu projectdir / vendor bez polegania na GOPATH.

Zainstaluj za pomocą naparu (OS X)

$ brew install glide

Zainicjuj plik glide.yaml (podobny do pliku package.json). Spowoduje to również pobranie istniejących zaimportowanych pakietów w Twoim projekcie z GOPATH i skopiowanie ich do katalogu / dostawcy projektu.

$ glide init

Zdobądź nowe pakiety

$ glide get vcs/namespace/package

Zaktualizuj i zablokuj wersje pakietów. Spowoduje to utworzenie pliku glide.lock w katalogu projektu, aby zablokować wersje.

$ glide up

Próbowałem Glide i szczęśliwie używam go w moim obecnym projekcie.

Ciasto „Oh” Pah
źródło
1
Dla kompletności, tutaj jest strona internetowa glide: glide.sh A tutaj repozytorium: github.com/Masterminds/glide
Michael Franzl
niestety Glide nie jest już "aktywny", na stronie github sugerują migrację do oficjalnego zarządzania pakietami (teraz przejdź do modułów)
damoiser
13

Aktualizacja 18-11-23 : Mod From Go 1.11 jest oficjalnym eksperymentem. Zobacz @krish answer.
Aktualizacja 19-01-01 : Mod From Go 1.12 jest nadal oficjalnym eksperymentem. Począwszy od wersji Go 1.13, tryb modułu będzie domyślnym dla wszystkich programów.
Aktualizacja 19-10-17 : Mod From Go 1.13 jest oficjalnym menedżerem pakietów.

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

Stara odpowiedź:

Możesz ustawić wersję według oficjalnego dep

dep ensure --add github.com/gorilla/websocket@1.2.0
witamy
źródło
3
Pytanie było używane go get, nie dep.
Bernardo Loureiro
9

depto oficjalny eksperyment dotyczący zarządzania zależnościami w języku Go. Kompilacja wymaga wersji 1.8 lub nowszej.

Aby rozpocząć zarządzanie zależnościami za pomocą dep, uruchom następujące polecenie z katalogu głównego projektu:

dep init

Po wykonaniu zostaną wygenerowane dwa pliki: Gopkg.toml(„manifest”), Gopkg.locka niezbędne pakiety zostaną pobrane dovendor katalogu.

Załóżmy, że masz projekt korzystający z github.com/gorilla/websocketpakietu. depwygeneruje następujące pliki:

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

Istnieją polecenia, które pomogą Ci aktualizacja / delete / etc pakietów, należy znaleźć więcej informacji na temat oficjalnego repo github z dep(narzędzie zarządzania zależnościach dla Go).

Aliaksei Maniuk
źródło
7

W dzisiejszych czasach możesz po prostu go użyć go get. Możesz pobrać swoją zależność za pomocą tagu wersji, gałęzi lub nawet zatwierdzenia.

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

więcej szczegółów tutaj - Jak wskazać zależność modułu Go w go.mod do ostatniego zatwierdzenia w repozytorium?

Go getzainstaluje również plik binarny, tak jak jest napisane w dokumentacji -

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

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

homiak
źródło
4

go get to menedżer pakietów Go. Działa w całkowicie zdecentralizowany sposób, a odnajdywanie pakietów jest nadal możliwe bez centralnego repozytorium hostingu pakietów.

Oprócz lokalizowania i pobierania pakietów inną ważną rolą menedżera pakietów jest obsługa wielu wersji tego samego pakietu. Go przyjmuje najbardziej minimalne i pragmatyczne podejście ze wszystkich menedżerów pakietów. Nie ma czegoś takiego jak wiele wersji pakietu Go.

go get zawsze ściąga z HEAD domyślnej gałęzi w repozytorium. Zawsze. Ma to dwie ważne konsekwencje:

  1. Jako autor pakietu musisz trzymać się stabilnej filozofii HEAD. Twoja domyślna gałąź zawsze musi być stabilną, wydaną wersją twojego pakietu. Musisz pracować w gałęziach funkcji i scalać tylko wtedy, gdy są gotowe do wydania.

  2. Nowe główne wersje Twojego pakietu muszą mieć własne repozytorium. Mówiąc prościej, każda główna wersja twojego pakietu (po wersjonowaniu semantycznym) miałaby swoje własne repozytorium, a tym samym własną ścieżkę importu.

    np. github.com/jpoehls/gophermail-v1 i github.com/jpoehls/gophermail-v2.

Jako ktoś budujący aplikację w Go, powyższa filozofia naprawdę nie ma wad. Każda ścieżka importu to stabilny interfejs API. Nie musisz się martwić o numery wersji. Niesamowite!

Więcej informacji: http://zduck.com/2014/go-and-package-versioning/

faisal_kk
źródło
45
Twoje wypowiedzi na temat funkcjonalności narzędzi go są poprawne, ale prawie nikt nie włącza wersji do nazw repozytoriów git, a wiele osób nie traktuje master / HEAD jako stabilnego API. Obecnie mam małą usługę z około ośmioma zależnościami; tylko jeden ma numer wersji. Amazon wprowadził przełomową zmianę na github.com/aws/aws-sdk-go. go getBuforowanie oznacza, że ​​przez chwilę nie zauważysz, chyba że masz serwer kompilacji, który za każdym razem aktualizuje Cię do najnowszej wersji. Istnieją zewnętrzne menedżery pakietów, ale w większości są one prymitywne.
dhasenan
19
@faisal_kk musisz żyć w świecie marzeń. W PRAWDZIWYM świecie wspaniałej społeczności open source każdy wyznaje własną filozofię. Nie ma czegoś takiego jak rozgałęzianie wydań, cieszę się, że mamy tagi.
28
Utworzyć repozytorium dla każdej wersji? To jest szalone
deFreitas
8
To jest zasadniczo złe zachowanie. Kod źródłowy NIE jest tym samym, co wydany pakiet i nie można przypisać autorów pakietu, aby zapewnić zgodność wstecz / do przodu. Nie dlatego, że programiści są niekompetentni, ale dlatego, że jest to teoretycznie niemożliwe, gdy liczba zależności pakietów przekracza jeden. Go get jest zatem przeznaczone do pójścia tą samą drogą co altana, której główną wadą była dokładnie ta sama. Wersjonowanie semantyczne też nie jest wystarczająco mocne, binarne sumy kontrolne to naprawdę jedyna droga.
Gudlaugur Egilsson
5
„Nie trzeba się martwić o numery wersji. Super!” To musi być najbardziej absurdalne stwierdzenie w odpowiedzi TAK w historii. Wersjonowanie istnieje z jakiegoś powodu. Brak menedżera pakietów w Go, który ma wbudowaną konfigurację lub mechanizm zorientowany na polecenia do wersjonowania zależności, na przykład, nie oznacza, że ​​przechowywanie wersji jest uciążliwe. Głosowanie przeciw!
Harindaka
2

Podejście, które uznałem za wykonalne, to system podmodułów git . Używając tego możesz podmoduł w danej wersji kodu, a aktualizacja / obniżanie wersji jest jawna i rejestrowana - nigdy nie jest przypadkowa.

Struktura folderów, którą wziąłem z tym, to:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.
buckaroo1177125
źródło
Ja też stosuję to podejście. Zasadniczo ma taką samą strukturę folderów jak go, ale pozwala na lepszą kontrolę nad nabywaną wersją.
Brad Peabody
odpowiedź nie odpowiada na pytanie z zadanymi kryteriami (przy użyciu go get)
Baptiste Mille-Mathias
2

Istnieje polecenie go edit -replace, aby dołączyć określone zatwierdzenie (nawet z innego rozwidlonego repozytorium) na wierzchu bieżącej wersji pakietu. Fajne w tej opcji jest to, że nie musisz znać wcześniej dokładnej pseudo wersji , wystarczy tylko identyfikator skrótu zatwierdzenia .

Na przykład używam stabilnej wersji pakietu „github.com/onsi/ginkgo v1.8.0”.

Teraz chcę - bez modyfikowania tej linii wymaganego pakietu w go.mod - dołączyć łatkę z mojego widelca, na wierzchu wersji ginkgo:

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

Po pierwszym zbudowaniu lub przetestowaniu modułu GO spróbuje pobrać nową wersję, a następnie wygeneruje wiersz „zamień” na poprawną pseudo wersję. Na przykład w moim przypadku doda na dole go.mod:

Zastąp github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451

Noam Manos
źródło
2

Mała ściągawka dotycząca zapytań dotyczących modułów.

Aby sprawdzić wszystkie istniejące wersje: np go list -m -versions github.com/gorilla/mux

  1. Konkretna wersja @ v1.2.8
  2. Konkretne zatwierdzenie @ c783230
  3. Konkretny commit @master
  4. Prefiks wersji @ v2
  5. Porównanie @> = 2.1.5
  6. Najnowsze @ najnowsze

Na przykład go get github.com/gorilla/[email protected]

monkrus
źródło