Как импортировать определенную версию пакета с помощью go get?

109

исходящий из Nodeсреды, которую я использовал для установки определенной версии библиотеки поставщика в папку проекта ( node_modules), указав npmустановить эту версию этой библиотеки из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

Но тогда как я могу изменить ситуацию во время импорта?

Wilk
источник
4
Вы этого не сделаете, go getэто неподходящий инструмент, если вы хотите такого поведения. Вы можете найти решения вашей конкретной проблемы в Google.
Wessie
1
Прочтите это
kostix
stackoverflow.com/questions/30188499/ ... Это тоже выглядит полезным
earlonrails
Для Go 1.11 или выше см. Модули Go: stackoverflow.com/questions/53682247/…
Эвертон

Ответы:

47

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 only? мне нужно было установить глобальный бинарный файл для конкретной версии
Джеймс Тан
7
@JamesTan go get github.com/wilk/uuid@0.0.1GO111MODULE=on)
Нил Конвей
7
Вопрос был в использовании 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 01
@ aliaksei-maniuk дает нам лучшее решение. Используйте https://github.com/golang/dep
Жоао Парана
15

Glide - это действительно элегантное средство управления пакетами для Go, особенно если вы работаете с Node npm или Rust.

Он похож на новую функцию поставщика Godep в версии 1.6, но намного проще. Ваши зависимости и версии «заблокированы» внутри каталога projectdir / vendor без использования GOPATH.

Установить с помощью brew (OS X)

$ brew install glide

Запустите файл glide.yaml (аналог package.json). Это также захватывает существующие импортированные пакеты в вашем проекте из GOPATH и копирует их в каталог vendor / проекта.

$ glide init

Получите новые пакеты

$ glide get vcs/namespace/package

Обновите и заблокируйте версии пакетов. Это создает файл glide.lock в каталоге вашего проекта для блокировки версий.

$ glide up

Я пробовал скольжение и с радостью использую его в своем текущем проекте.

Пирог "Ой"
источник
1
Для полноты картины вот сайт для glide: glide.sh И вот репо: github.com/Masterminds/glide
Майкл Франц
к сожалению, 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 ensure --add github.com/gorilla/websocket@1.2.0
Vitams
источник
3
Вопрос был в использовании go get, а не в том dep.
Бернардо Лоурейро,
11

Начиная с Go 1.5 есть «эксперимент с поставщиками», который помогает управлять зависимостями. Начиная с версии Go 1.6 это больше не эксперимент. Есть также некоторые другие варианты в вики Go..

Изменить: как упоминалось в этом ответе, gopkg.in - хороший вариант для закрепления github-depdencies до 1.5.

Larsmoa
источник
9

depэто официальный эксперимент по управлению зависимостями для языка Go. Для компиляции требуется Go 1.8 или новее.

Чтобы начать управление зависимостями с помощью dep, выполните следующую команду из корневого каталога вашего проекта:

dep init

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

Предположим, у вас есть проект, использующий github.com/gorilla/websocketpackage. 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 в go.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/

faisal_kk
источник
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
«Нет никаких номеров версий, о которых стоит беспокоиться. Прекрасно!» Это должно быть самое абсурдное утверждение в SO-ответе. Версионирование существует не просто так. Отсутствие у Go менеджера пакетов, который имеет встроенную конфигурацию или командно-ориентированный механизм для управления версиями зависимостей, скажем, не означает, что управление версиями является помехой. Голосование против!
Хариндака 01
2

Подход, который я нашел работоспособным, - это система подмодулей git . Используя это, вы можете создать подмодуль в данной версии кода, и обновление / понижение версии будет явным и записанным - никогда не случайным.

Структура папок, которую я взял с собой, следующая:

+ myproject
++ src
+++ myproject
+++ github.com
++++ submoduled_project of some kind.
Buckaroo1177125
источник
Я тоже использую этот подход. По сути, он следует той же структуре папок, что и go get, но позволяет вам лучше контролировать, какую версию вы приобретаете.
Брэд Пибоди
ответ не отвечает на вопрос с заданными критериями (с использованием go get)
Baptiste Mille-Mathias
2

Это сработало для меня

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

Вадим Темиров
источник
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

монкра
источник