Bagaimana cara mengimpor versi paket tertentu menggunakan go get?

109

berasal dari Nodelingkungan saya biasa menginstal versi tertentu dari vendor lib ke dalam folder proyek ( node_modules) dengan memberitahu npmuntuk menginstal versi lib itu dari package.jsonatau bahkan langsung dari konsol, seperti:

$ npm install express@4.0.0

Kemudian saya biasa mengimpor versi paket itu di proyek saya hanya dengan:

var express = require('express');

Sekarang, saya ingin melakukan hal yang sama dengan go. Bagaimana saya bisa melakukan itu? Apakah mungkin untuk menginstal versi paket tertentu? Jika demikian, dengan menggunakan terpusat $GOPATH, bagaimana cara mengimpor satu versi alih-alih yang lain?

Saya akan melakukan sesuatu seperti ini:

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

Tapi kemudian, bagaimana saya bisa membuat perbedaan selama impor?

Wilk
sumber
4
Anda tidak, go getbukanlah alat yang tepat jika Anda menginginkan perilaku ini. Anda dapat mencari solusi untuk masalah spesifik Anda di Google.
Wessie
1
Baca ini
kostix
stackoverflow.com/questions/30188499/… Ini juga terlihat membantu
earlonrails
Untuk Go 1.11 atau lebih tinggi, lihat Go Modules: stackoverflow.com/questions/53682247/…
Everton

Jawaban:

47

Go 1.11 akan memiliki fitur yang disebut modul go dan Anda cukup menambahkan dependensi dengan sebuah versi. Ikuti langkah ini:

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

Berikut info selengkapnya tentang topik tersebut - https://github.com/golang/go/wiki/Modules

krish
sumber
4
bagaimana cara melakukannya dengan go get only? saya perlu menginstal biner go global ke versi tertentu
James Tan
7
@JamesTan go get github.com/wilk/[email protected](dengan GO111MODULE=on)
Neil Conway
5
Pertanyaannya menggunakan go get, bukan go mod.
Bernardo Loureiro
40

Benar-benar terkejut tidak ada yang menyebutkan gopkg.in .

gopkg.inadalah layanan yang menyediakan pembungkus (pengalihan) yang memungkinkan Anda mengekspresikan versi sebagai url repo, tanpa benar-benar membuat repo. Misalnya gopkg.in/yaml.v1vs gopkg.in/yaml.v2, meskipun mereka berdua tinggal dihttps://github.com/go-yaml/yaml

Ini tidak sempurna jika penulis tidak mengikuti praktik pembuatan versi yang benar (dengan menaikkan nomor versi saat melanggar kompatibilitas mundur), tetapi berfungsi dengan cabang dan tag.

Steven Soroka
sumber
5
Saya suka (dan menggunakan) gopkg, tetapi pembuatan versi tidak bekerja dengan benar dengan sub-paket. Hanya sesuatu yang harus diperhatikan.
Alec Thomas
gopkg.in tidak sepenuhnya diuji di git versi lama, jadi tidak berfungsi sebagaimana mestinya dengan git <v1.9
BMW
Juga, ini hanya berfungsi untuk versi mayor. Ini tidak dapat menjamin build yang dapat direproduksi.
CAFxX
26

Anda dapat menggunakan git checkoutuntuk mendapatkan versi tertentu dan membangun program Anda menggunakan versi ini.

Contoh:

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á
sumber
Solusinya adalah git checkout dan mulai install
ptman
@ aliaksei-maniuk memberi kami solusi yang lebih baik. Gunakan https://github.com/golang/dep
João Paraná
15

Glide adalah manajemen paket yang sangat elegan untuk Go terutama jika Anda berasal dari npm Node atau kargo Rust.

Ini berperilaku dekat dengan fitur vendor baru Godep di 1.6 tetapi jauh lebih mudah. Dependensi dan versi Anda "dikunci" di dalam direktori projectdir / vendor Anda tanpa bergantung pada GOPATH.

Instal dengan minuman (OS X)

$ brew install glide

Masukkan file glide.yaml (mirip dengan package.json). Ini juga mengambil paket yang diimpor yang ada dalam proyek Anda dari GOPATH dan menyalinnya ke direktori vendor / proyek.

$ glide init

Dapatkan paket baru

$ glide get vcs/namespace/package

Perbarui dan kunci versi paket. Ini membuat file glide.lock di direktori proyek Anda untuk mengunci versi.

$ glide up

Saya mencoba meluncur dan dengan senang hati menggunakannya untuk proyek saya saat ini.

Pai 'Oh' Pah
sumber
1
Untuk kelengkapan, berikut adalah situs web untuk glide: glide.sh Dan di sini repo: github.com/Masterminds/glide
Michael
sayangnya Glide tidak "aktif" lagi, di halaman github mereka menyarankan untuk bermigrasi ke manajemen paket resmi (sekarang go modules)
damoiser
13

Pembaruan 18-11-23 : Dari Go 1.11 mod adalah eksperimen resmi. Silakan lihat jawaban @krish.
Pembaruan 19-01-01 : Dari Go 1.12 mod masih merupakan percobaan resmi. Mulai Go 1.13, mode modul akan menjadi default untuk semua pengembangan.
Pembaruan 19-10-17 : Dari Go 1.13 mod adalah pengelola paket resmi.

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

Jawaban lama:

Anda dapat mengatur versi dengan dep resmi

dep ensure --add github.com/gorilla/websocket@1.2.0
vitamin
sumber
3
Pertanyaannya menggunakan go get, bukan dep.
Bernardo Loureiro
9

depadalah eksperimen resmi untuk manajemen ketergantungan untuk bahasa Go. Ini membutuhkan Go 1.8 atau yang lebih baru untuk dikompilasi.

Untuk mulai mengelola dependensi menggunakan dep, jalankan perintah berikut dari direktori root project Anda:

dep init

Setelah eksekusi, dua file akan dibuat: Gopkg.toml("manifest"), Gopkg.lockdan paket yang diperlukan akan diunduh ke vendordirektori.

Anggaplah Anda memiliki proyek yang menggunakan github.com/gorilla/websocketpaket. depakan menghasilkan file berikut:

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

Ada perintah yang membantu Anda untuk update / delete / etc paket, silahkan mencari info lebih lanjut tentang repo github resmi dari dep(alat manajemen ketergantungan untuk Go).

Aliaksei Maniuk
sumber
7

Saat ini Anda bisa menggunakannya go getuntuk itu. Anda dapat mengambil ketergantungan Anda dengan tag versi, cabang atau bahkan komit.

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

lebih jelasnya di sini - Bagaimana cara mengarahkan ketergantungan modul Go di go.mod ke komit terbaru di repo?

Go getjuga akan menginstal biner, seperti yang tertulis di dokumentasi -

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

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

homiak
sumber
4

go get adalah pengelola paket Go. Ia bekerja dengan cara yang sepenuhnya terdesentralisasi dan bagaimana penemuan paket masih dimungkinkan tanpa repositori hosting paket pusat.

Selain mencari dan mengunduh paket, peran besar lainnya dari pengelola paket adalah menangani beberapa versi dari paket yang sama. Go mengambil pendekatan paling minimal dan pragmatis dari pengelola paket mana pun. Tidak ada yang namanya beberapa versi paket Go.

go get selalu menarik dari HEAD dari cabang default di repositori. Selalu. Ini memiliki dua implikasi penting:

  1. Sebagai pembuat paket, Anda harus mematuhi filosofi HEAD yang stabil. Cabang default Anda harus selalu versi stabil yang dirilis dari paket Anda. Anda harus bekerja di cabang fitur dan hanya menggabungkan saat siap untuk rilis.

  2. Versi utama baru dari paket Anda harus memiliki repositori sendiri. Sederhananya, setiap versi utama dari paket Anda (mengikuti versi semantik) akan memiliki repositori sendiri dan dengan demikian jalur impornya sendiri.

    mis. github.com/jpoehls/gophermail-v1 dan github.com/jpoehls/gophermail-v2.

Sebagai seseorang yang membangun aplikasi di Go, filosofi di atas benar-benar tidak memiliki kerugian. Setiap jalur impor adalah API yang stabil. Tidak ada nomor versi yang perlu dikhawatirkan. Hebat!

Untuk detail lebih lanjut: http://zduck.com/2014/go-and-package-versioning/

faisal_kk
sumber
45
Pernyataan Anda tentang fungsionalitas alat go sudah benar, tetapi hampir tidak ada yang memasukkan versi ke dalam nama repositori git mereka, dan banyak orang tidak memperlakukan master / HEAD sebagai API yang stabil. Saat ini saya memiliki layanan kecil dengan sekitar delapan dependensi; hanya satu yang memiliki nomor versi. Amazon mendorong perubahan yang melanggar ke github.com/aws/aws-sdk-go. go getCaching berarti Anda tidak menyadarinya untuk beberapa saat kecuali Anda memiliki server build yang membantu memperbarui Anda ke versi terbaru setiap saat. Ada pengelola paket pihak ketiga, tetapi kebanyakan mentah.
dhasenan
19
@faisal_kk kamu pasti hidup di dunia mimpi. Di dunia NYATA dari komunitas open-source yang luar biasa, semua orang berpegang pada filosofi mereka sendiri. Tidak ada rilis bercabang seperti itu, saya senang kami memiliki tag.
28
Buat repositori untuk setiap versi? Ini gila
deFreitas
8
Ini adalah perilaku yang salah secara fundamental. Kode sumber TIDAK sama dengan paket yang dirilis, dan Anda tidak dapat menggunakan pembuat paket untuk memastikan kompatibilitas mundur / maju. Bukan karena pengembang tidak kompeten, tetapi karena ini secara teoritis tidak mungkin ketika jumlah ketergantungan paket meningkat lebih dari satu. Oleh karena itu, Go get ditakdirkan untuk pergi dengan cara yang sama seperti bower, yang kekurangan utamanya adalah kesalahan yang sama persis. Versi semantik juga tidak cukup kuat, checksum biner benar-benar satu-satunya cara untuk melakukannya.
Gudlaugur Egilsson
5
"Tidak ada nomor versi yang perlu dikhawatirkan. Luar biasa!" Itu pasti pernyataan paling tidak masuk akal dalam jawaban SO yang pernah ada. Versi ada karena suatu alasan. Kurangnya Go dari manajer paket yang memiliki konfigurasi inbuilt atau mekanisme berorientasi perintah untuk pembuatan versi dependensi per kata tidak berarti bahwa pembuatan versi merupakan gangguan. Merendahkan!
Harindaka
2

Pendekatan yang menurut saya bisa diterapkan adalah sistem submodul git . Menggunakan itu Anda dapat submodule dalam versi kode tertentu dan peningkatan / penurunan secara eksplisit dan dicatat - tidak pernah sembarangan.

Struktur folder yang saya ambil dengan ini adalah:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.
buckaroo1177125
sumber
Saya menggunakan pendekatan ini juga. Pada dasarnya ini mengikuti struktur folder yang sama seperti go get, tetapi memungkinkan Anda mengontrol versi yang Anda peroleh dengan lebih baik.
Brad Peabody
jawabannya tidak menjawab pertanyaan dengan kriteria yang diajukan (menggunakan go get)
Baptiste Mille-Mathias
2

Ada perintah go edit -replace untuk menambahkan komit tertentu (bahkan dari repositori bercabang lain) di atas versi paket saat ini. Yang menarik dari opsi ini, adalah Anda tidak perlu mengetahui versi pseudo yang tepat sebelumnya, cukup komit hash id .

Misalnya, saya menggunakan versi stabil dari paket "github.com/onsi/ginkgo v1.8.0".

Sekarang saya ingin - tanpa mengubah baris paket yang diperlukan ini di go.mod - untuk menambahkan tambalan dari garpu saya, di atas versi ginkgo:

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

Setelah pertama kali Anda membangun atau menguji modul Anda, GO akan mencoba menarik versi baru, dan kemudian membuat baris "ganti" dengan versi semu yang benar. Misalnya dalam kasus saya, itu akan ditambahkan di bagian bawah go.mod:

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

Noam Manos
sumber
2

Sedikit contekan tentang pertanyaan modul.

Untuk memeriksa semua versi yang ada: mis go list -m -versions github.com/gorilla/mux

  1. Versi khusus @ v1.2.8
  2. Komit khusus @ c783230
  3. Komit khusus @master
  4. Awalan versi @ v2
  5. Perbandingan @> = 2.1.5
  6. terbaru @latest

Misalnya go get github.com/gorilla/[email protected]

monkrus
sumber