February 14, 2018 · Go Dep

Управление зависимостями в Go с помощью dep

Практически в любом проекте рано или поздно возникает необходимость использования сторонних библиотек. Многие современные языки имеют общепринятые пакетные менеджеры для управления зависимостями в приложении. Например npm для Node.js или Composer для PHP.

В Go существует достаточно много инструментов для управления пакетами от разных разработчиков. Некоторые из них даже не написаны на Go.

dep

Одним из таких инструментов является dep. В отличие от других, он был официальным экспериментом разработчиков команды Go, но пока не включен в официальный набор утилит. Поскольку у него есть все шансы стать стандартом, предлагаю с ним ознакомиться.

23 января 2018 года состоялся релиз v0.4.1 и уже готов для использования в production, все нижеизложенное будет справедливо для этой версии.

Установка

Разработчиками рекомендуется скачать готовый бинарник последнего релиза для вашей платформы.

В MacOS установить или обновить до последней версии можно с помощью Homebrew

$ brew install dep
$ brew upgrade dep

Если интересно посмотреть как все работает, можно скачать используя go get

go get -u github.com/golang/dep/cmd/dep

Для компиляции из исходного кода потребуется Go 1.8 или выше.

Инициализация

Как обычно создадим проект в $GOPATH и перейдем в его папку:

mkdir -p $GOPATH/src/github.com/username/hello
cd $GOPATH/src/github.com/username/hello

Инициализация менеджера происходит командой:

dep init

Эта команда создаст в папке проекта папку vendor для хранения библиотек и файлы Gopkg.lock и Gopkg.toml.

Есть еще пара команд:

Главная команда dep ensure. Слово ensure (гарантировать, обеспечивать) означает то, что будет выполнена не дискретная операция (как добавление зависимости), а что-то целостное. Вместо того, чтобы выполнять несколько последовательных команд для изменения состояния проекта, каждый запуск dep ensure обеспечивает полный, безопасный и воспроизводимый набор изменений состояния проекта. Это означает, что на диск будет записано всё или ничего. За исключением критический ситуаций.

Существует четыре ситуации, когда использовать dep ensure:

Добавление зависимости

Допустим, нам нужен пакет github.com/pkg/errors. Его можно добавить командой:

dep ensure -add github.com/pkg/errors

Команды dep ensure и dep status как и команды git можно вызывать из любых подпапок проекта.

После успешного добавления пакета будет изменен файл Gopkg.lock и содержимое папки vendor. Версия пакета github.com/pkg/errors будет добавлена в Gopkg.toml однако мы получим предупреждение:

"github.com/pkg/errors" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/.
If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/.

Это означает, что мы должны использовать import "github.com/pkg/errors" где-то в коде проекта. Иначе после вызова dep ensure этот пакет будет отмечен как неиспользуемый и удалён из папки vendor и файла Gopkg.lock.

Можно поступить наоборот. Сначала использовать import в коде, а затем установить зависимость, например создать файл main.go:

package main

import (
	"github.com/fatih/color"
)

func main() {
	color.Red("Error!")
}

и выполнить dep ensure.

Все зависимости будут разрешены, более того, если до этого dep не был инициирован, то зависимости для существующего кода будут скачаны сразу после dep init.

Обновление зависимостей

Отдельный пакет можно обновить командой:

dep ensure -update github.com/user/project

Или при необходимости попытаться обновить всё сразу:

dep ensure -update

Правила для изменения файла Gopkg.toml

Содержимое директории vendor и файл Gopkg.lock редактировать не нужно, они генерируются автоматически. А файл Gopkg.toml предоставляет пять основных типов правил, для настройки:

После внесения любых изменений в этот файл, вызов dep ensure приведет весь проект в необходимое состояние.

Comments powered by Disqus