Як імпортувати конкретну версію пакета за допомогою go get?


109

виходячи з Nodeсередовища, я використовував для встановлення конкретної версії lib постачальника в папку проекту ( node_modules), кажучи npmпро встановлення цієї версії цього lib з package.jsonконсолі або навіть безпосередньо з консолі, наприклад:

$ npm install express@4.0.0

Потім я імпортував цю версію цього пакету в мій проект лише за допомогою:

var express = require('express');

Тепер я хочу зробити те саме go. Як я можу це зробити? Чи можливо встановити конкретну версію пакета? Якщо так, використовуючи централізовану $GOPATH, як я можу імпортувати одну версію замість іншої?

Я б зробив щось подібне:

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

Але тоді, як я можу змінити під час імпорту?


4
go getЯкщо ви не хочете , це не правильний інструмент, якщо ви хочете такої поведінки. Ви можете розібратися, щоб вирішити вашу конкретну проблему.
Вессі

1
Прочитайте це
kostix

stackoverflow.com/questions/30188499/… Це теж здається корисним
вушні перила

Про програму Go 1.11 або вище див. Модулі Go: stackoverflow.com/questions/53682247/…
Everton

Відповіді:


46

Go 1.11 матиме функцію під назвою go модулі, і ви можете просто додати залежність від версії. Виконайте такі дії:

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

Ось додаткові відомості з цієї теми - https://github.com/golang/go/wiki/Modules


4
як це зробити з go get тільки? Мені потрібно було встановити глобальну бінарну версію до конкретної версії
Джеймс Тан

7
@JamesTan go get github.com/wilk/uuid@0.0.1GO111MODULE=on)
Ніл Конвей

5
Питання було вживання go get, не go mod.
Бернардо

40

Дійсно здивований, ніхто не згадав gopkg.in .

gopkg.inце сервіс, який надає обгортку (переадресацію), яка дозволяє висловлювати версії у вигляді URL-адрес репо, не створюючи фактично репост. Наприклад , gopkg.in/yaml.v1проти gopkg.in/yaml.v2, навіть якщо вони обидва живуть вhttps://github.com/go-yaml/yaml

Це не ідеально, якщо автор не дотримується належних методів версій (збільшуючи номер версії при порушенні зворотної сумісності), але він працює з гілками та тегами.


5
Мені подобається (і я використовую) gopkg, але версія не працює належним чином з підпакетами. Просто щось слід пам’ятати.
Алек Томас

gopkg.in не повністю перевірений у старих версіях git, тому він не працює належним чином із git <v1.9
BMW

Також він працює лише для основних версій. Неможливо гарантувати відтворювані конструкції.
CAFxX

26

Ви можете використовувати git checkoutдля отримання конкретної версії та створення програми за допомогою цієї версії.

Приклад:

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

Вирішенням цього питання буде: git checkout та перехід до встановлення
ptman

@ aliaksei-maniuk дай нам краще рішення. Використовуйте https://github.com/golang/dep
Жоао Парана

15

Glide - це дійсно елегантне управління пакетами для Go, особливо якщо ви приїжджаєте з node npm або вантажу Rust.

Він добре поводиться з новою функцією постачальника Godep в 1.6, але набагато простіше. Ваші залежності та версії "заблоковані" всередині каталогу projectdir / vendor, не покладаючись на GOPATH.

Встановити заваркою (OS X)

$ brew install glide

Запустіть файл glide.yaml (схожий на package.json). Це також захоплює існуючі імпортовані пакети у вашому проекті з GOPATH та копіює його до постачальника / каталогу проекту.

$ glide init

Отримайте нові пакети

$ glide get vcs/namespace/package

Оновіть та заблокуйте версії пакетів. Це створює файл glide.lock у каталозі вашого проекту для блокування версій.

$ glide up

Я спробував ковзати і з радістю використовую його для свого поточного проекту.


1
Для повноти, ось веб-сайт для glide : glide.sh А ось репортаж
Майкл

на жаль, Glide вже не "активний", на сторінці github пропонують перейти до офіційного управління пакунками (тепер переходять модулі)
damoiser

13

Оновлення 18-11-23 : Мод Go 1.11 - це офіційний експеримент. Дивіться відповідь @krish.
Оновлення 19-01-01 : Мод Go 1,12 все ще є офіційним експериментом. Починаючи з Go 1.13, модульний режим буде за замовчуванням для всієї розробки.
Оновлення 19-10-17 : Мод Go 1.13 є офіційним менеджером пакунків.

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

Стара відповідь:

Ви можете встановити версію за офіційним dep

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

3
Питання було вживання go get, не dep.
Бернардо


9

depє офіційним експериментом з управління залежностями Go Go. Для компіляції потрібен Go 1.8 або новіший.

Щоб почати керувати залежностями dep, виконайте наступну команду з кореневого каталогу вашого проекту:

dep init

Після виконання буде створено два файли: Gopkg.toml("manifest"), Gopkg.lockа необхідні пакети будуть завантажені вvendor каталог.

Припустимо, що у вас є проект, який використовує github.com/gorilla/websocketпакет. depгенерує такі файли:

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

Є команди , які допоможуть вам оновлення / видалення / і т.д. пакетів, будь ласка , знайти більш детальну інформацію про офіційному GitHub репо з dep(інструмент управління залежностями для Go).


7

Сьогодні ви можете просто використовувати go getдля цього. Ви можете отримати залежність, використовуючи тег версії, гілку чи навіть комісію.

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

Більше деталей тут - Як вказати залежність модуля Go у mod.mod на останню передачу репо?

Go getтакож встановить двійковий файл, як зазначено в документації -

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

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


4

go get - це менеджер пакунків Go. Це працює повністю децентралізовано і як відкриття пакунків все ще можливо без центрального сховища хостингу пакетів.

Крім розміщення та завантаження пакетів, інша велика роль менеджера пакунків - це обробка декількох версій одного пакета. Go застосовує найменший і прагматичний підхід будь-якого менеджера пакунків. Немає такої речі, як кілька версій пакету Go.

go get завжди витягує з HEAD гілки за замовчуванням у сховищі. Завжди. Це має два важливі наслідки:

  1. Як автор пакету, ви повинні дотримуватися стійкої філософії HEAD. Ваша філія за замовчуванням завжди повинна бути стабільною, випущеною версією вашого пакета. Ви повинні працювати в галузях функцій і зливатися лише тоді, коли готові до випуску.

  2. Нові основні версії вашого пакета повинні мати власне сховище. Простіше кажучи, кожна основна версія вашого пакета (після семантичної версії) мала б своє сховище, а отже, і власний шлях імпорту.

    наприклад, github.com/jpoehls/gophermail-v1 та github.com/jpoehls/gophermail-v2.

Оскільки хтось будує додаток у Go, зазначена вище філософія насправді не має недоліків. Кожен шлях імпорту - це стабільний API. Немає номерів версій, про які слід турбуватися. Дивовижно!

Детальніше: http://zduck.com/2014/go-and-package-versioning/


45
Ваші твердження щодо функціональності інструментів go є правильними, але майже ніхто не включає версії у свої назви сховищ git, і багато людей не ставляться до master / HEAD як до стабільного API. В даний час у мене є невеликий сервіс із приблизно вісьмома залежностями; лише одна має номер версії. Amazon переніс переломну зміну до github.com/aws/aws-sdk-go. go getкешування означає, що ви деякий час не помічаєте, якщо у вас немає сервера збірки, який допоможе оновлювати вас до останньої версії кожного разу. Є сторонні менеджери пакунків, але вони в основному сирі.
dhasenan

19
@faisal_kk ти повинен жити у світі мрії. У реальному світі чудової спільноти з відкритим кодом усі дотримуються власної філософії. Немає такого розгалуження випусків, я радий, що у нас є теги.

28
Створити сховище для кожної версії? Це божевільно
deFreitas

8
Це принципово неправильна поведінка. Вихідний код НЕ такий же, як випущений пакет, і ви не можете надіслати авторів пакунків, щоб забезпечити сумісність назад / вперед. Не тому, що розробники некомпетентні, а тому, що це теоретично неможливо, коли кількість залежностей від пакета збільшується понад одну. Тому Go get судилося йти тим же шляхом, що і цистерна, головною вадою якої була саме така. Семантична версія не є достатньо сильною, двійкові контрольні суми - це єдиний шлях.
Гудлаугур Егільссон

5
"Немає номерів версій, для яких слід хвилюватися. Дивовижно!" Це повинно бути найбільш абсурдним твердженням у відповіді на ВП. Версія є з причини. Відсутність менеджера пакунків, який має вбудовану конфігурацію або механізм, орієнтований на команду для модернізації залежностей за кожним словом, не означає, що оновлення неприємності. Схиляючись!
Харіндака

2

Підхід, який я знайшов, є дієвим - це підмодульна система git . Використовуючи це, ви можете підмодулювати в заданій версії коду, а оновлення / пониження версії явне та записане - ніколи не є випадковим.

Структура папки, яку я взяв із цим, є:

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

Я також використовую такий підхід. По суті, вона відповідає тій же структурі папок, що і go get, але дозволяє краще контролювати, яку версію ви купуєте.
Бред Пібоді

відповідь не відповідає на запитання із заданими критеріями (використовуючи go get)
Baptiste Mille-Mathias


2

Існує команда go edit -replace, щоб додати певну комісію (навіть з іншого роздрібного сховища) поверх поточної версії пакета. Що цікаво в цьому варіанті, це те, що вам не потрібно заздалегідь знати точну версію псевдо , лише ідентифікаційний хеш-код .

Наприклад, я використовую стабільну версію пакета "github.com/onsi/ginkgo v1.8.0".

Тепер я хочу - не змінюючи цей рядок необхідного пакету в go.mod - додати патч з моєї вилки, поверх версії ginkgo:

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

Після того, як ви вперше побудуєте або протестуєте свій модуль, GO спробує вивести нову версію, а потім генерувати рядок «заміни» на правильну псевдо версію. Наприклад, у моєму випадку він додасть у нижній частині go.mod:

замінити github.com/onsi/ginkgo => github.com/manosnoam/ginkgo v0.0.0-20190902135631-1995eead7451


2

Невеликий шпаргалка на запити модулів.

Для перевірки всіх існуючих версій: напр go list -m -versions github.com/gorilla/mux

  1. Конкретна версія @ v1.2.8
  2. Конкретна комісія @ c783230
  3. Конкретна фіксація @master
  4. Префікс версії @ v2
  5. Порівняння @> = 2.1.5
  6. Останні @latest

Напр go get github.com/gorilla/mux@v1.7.4

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.