SlideShare a Scribd company logo
1 of 71
Download to read offline
Управление зависимостями в Go 1.11
Minimal Version Selection
Ivan Korolev
Senior Go Developer
ivan.korolev@ozon.ru
github.com/mwf
03
Зависимости в Go
Зависимости в Go
• Как это было?
• Minimal Version Selection
• Текущий статус
• Примеры работы с зависимостями
• Подводные камни
04
Вместо предисловия
05
What is Software Engineering?
Software engineering is what happens to programming 
when you add time and other programmers.
В начале было...
06
• pre-go1 - makefiles, gobuild (2009)
• pre-go1 - goinstall (2010) - VCS-репозитории
• go 1 - go get (2011)
• go 1.2 FAQ: Import Compatibility Rule (2013)
• создан gopkg.in (2014) - gopkg.in/yaml.v2
go get -u golang.org/x/tools/cmd/goimports
Vendoring и воспроизводимые сборки
(reproducible builds)
07
• goven (2012) - модификация импортов
• godep (2013) - модификация $GOPATH
• gb, glide, gom ... (2014)
• go 1.5 - vendoring в тулчейне
"original.com/pkg" -> "you.com/external/original.com/pkg"
GO15VENDOREXPERIMENT=1 go build
Vendoring - проблемы
08
• Дюжина менеджеров зависимостей (с разным форматом)
• Нет поддержки SemVer в go toolchain
• Коммитить папку vendor в репу - 

cannot use opts 

(type "<lib>/vendor/google.golang.org/
grpc".CallOption) as type []"<app>/vendor/
google.golang.org/grpc".CallOption
"Одно кольцо чтоб править всеми"
09
2016-2017 - Sam Boyer's dep, "официальный эксперимент"
Встречаем... vgo
(февраль 2018)
010
• Semantic Import Versioning

import "github.com/go-yaml/yaml/v2"
• Go module - коллекция пакетов с общим путём
• Minimal Version Selection
• $GOPATH - больше не завязаны на src
Semantic Import Versioning
011
Go modules
012
package main
import (
"fmt"
"rsc.io/quote"
)
func main() {
fmt.Println(quote.Hello())
}
Go modules
013
$ go mod init example.com/test
go: creating new go.mod: module example.com/test
$ cat go.mod
module example.com/test
Go modules
014
$ go mod tidy
go: finding rsc.io/quote v1.5.2
go: downloading rsc.io/quote v1.5.2
go: finding rsc.io/sampler v1.3.0
go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: downloading rsc.io/sampler v1.3.0
go: downloading golang.org/x/text
v0.0.0-20170915032832-14c0d48ead0c
Go modules
015
$ cat go.mod
module example.com/test
require rsc.io/quote v1.5.2
Зависимости в Go
• Как это было?
• Minimal Version Selection
• Текущий статус
• Примеры работы с зависимостями
• Подводные камни
016
Minimal Version Selection
017
build list - список всех модулей зависимостей и их
версий
Задачи:
• Построение build list
• Обновление всех зависимостей
• Обновление модуля до нужной версии
• Откат модуля до нужной версии
MVS - пример
018
MVS - сборка (рекурсивно)
019
MVS - сборка (обход графа)
020
MVS - обновление всех модулей
021
MVS - мин. список зависимостей
алгоритм R
022
Реверсивный обратный обход
E1.3, D1.4, B1.2, G1.1, F1.1, C1.3
C1.3, F1.1, G1.1, B1.2, D1.4, E1.3
MVS - обновление одного модуля
023
MVS - обновление одного модуля
024
build list + алгоритм R
E1.2, D1.3, B1.2, D1.4, C1.2, G1.1,
F1.1, C1.3
C1.3, F1.1, G1.1, C1.2, D1.4, B1.2,
D1.3 E1.2
MVS - откат одного модуля
025
MVS - откат одного модуля
026
маркировка недоступных+
алгоритм R
E1.1, D1.1, B1.1, D1.2, E1.2, C1.1
C1.1, E1.2, D1.2, B1.1, D1.1, E1.1
Minimal Version Selection
027
Простота реализации - алгоритмы на графах
Минимальность вносимых изменений
Не NP-полная (не нужно решать 3SAT)
Локальные replace и exclude
Воспроизводимость билдов 👍
MVS - воспроизводимость билдов
028
Библиотека не должна диктовать сборку - replace и
exclude локальные.
Cargo и Dep - навязывают последние версии через
манифест.
Есть вероятность забыть обновить манифест - билд
нестабилен (B > 1.1, используем B 1.2)
Зависимости в Go
• Как это было?
• Minimal Version Selection
• Текущий статус
• Примеры работы с зависимостями
• Подводные камни
029
Статус
13 июля - vgo влили в go devel
20 июля - go1.11beta2
24 августа - go1.11
go help modules
030
Статус - обратная совместимость
GO111MODULE=auto
GO111MODULE=on go build <...>
Зачем?
Можно бы было определять "динамически" по наличию
go.mod в репозитории...
031
Статус - обратная совместимость
$GOPATH/src/A - без go.mod, импортирует B
$GOPATH/src/B - есть go.mod, импортирует C
$GOPATH/src/C - отсутствует
032
Статус - обратная совместимость
033
$ cd $GOPATH/src/A
$ go build
# B
../B/b.go:10: import "C": C not found
<Странно, попробуем собрать B напрямую>
$ go build B
../B/b.go:10: import "C": C not found
Статус - обратная совместимость
034
<Но я же только что работал с B!>
$ cd ../B
$ go build
$
<ЧТО? Собирается же>
$ go build B
$ go build С
$
Статус - обратная совместимость
035
<ОК, вернёмся к A >
$ cd ../A
$ go build
../B/b.go:10: import "C": C not found
Начало работы (fail 1)
$ cd `mktemp -d`
$ go get github.com/gorilla/mux@latest
go: cannot use path@version syntax in GOPATH mode
Почему?!
GO111MODULE=auto
036
Начало работы (fail 2)
$ export GO111MODULE=on
...
$ go get github.com/alecthomas/gometalinter
go: cannot find main module; see 'go help modules'
037
Начало работы
$ cd `mktemp -d`
$ go mod init example.com/test
$ go get github.com/gorilla/mux@latest
go: finding github.com/gorilla/mux v1.6.2
go: downloading github.com/gorilla/mux v1.6.2
$ cat go.mod
module example.com/test
require github.com/gorilla/mux v1.6.2 // indirect
038
go.mod
039
module example.com/test
require (
github.com/BurntSushi/toml v0.3.0 // indirect
github.com/apache/thrift
v0.0.0-20180627210808-129f332d72fa // indirect
github.com/go-chi/chi v3.3.3+incompatible
github.com/go-chi/cors v1.0.0
...
google.golang.org/grpc v1.13.0
)
go.sum
$ cat go.sum
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/
r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod
h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
$GOPATH/pkg/mod/<import_path>
$GOPATH/pkg/mod/cache
$ go clean -modcache
040
Хранение версий
$ ls -al $GOPATH/pkg/mod/cache/download/github.com/gorilla/mux/@v/
total 360
drwxr-xr-x 15 ikorolev staff 480 Jul 24 13:18 .
drwxr-xr-x 3 ikorolev staff 96 Jul 24 13:06 ..
-rw-r--r-- 1 ikorolev staff 21 Jul 24 13:18 list
-rw------- 1 ikorolev staff 123 Jul 24 13:18 v1.5.0.info
-rw------- 1 ikorolev staff 30 Jul 24 13:18 v1.5.0.mod
-rw-r--r-- 1 ikorolev staff 37948 Jul 24 13:18 v1.5.0.zip
-rw-r--r-- 1 ikorolev staff 47 Jul 24 13:18 v1.5.0.ziphash
-rw------- 1 ikorolev staff 123 Jul 24 13:17 v1.6.1.info
-rw------- 1 ikorolev staff 30 Jul 24 13:17 v1.6.1.mod
-rw-r--r-- 1 ikorolev staff 46619 Jul 24 13:17 v1.6.1.zip
-rw-r--r-- 1 ikorolev staff 47 Jul 24 13:17 v1.6.1.ziphash
041
Хранение версий
$ ls -al $GOPATH/src/mod/github.com/gorilla/
total 0
drwxr-xr-x 5 ikorolev staff 160 Jul 24 13:18 .
drwxr-xr-x 9 ikorolev staff 288 Jul 24 13:44 ..
dr-xr-xr-x 16 ikorolev staff 512 Jul 24 13:18 mux@v1.5.0
dr-xr-xr-x 21 ikorolev staff 672 Jul 24 13:17 mux@v1.6.1
dr-xr-xr-x 22 ikorolev staff 704 Jul 24 13:06 mux@v1.6.2
042
go get
043
# или просто 'go get')
go get github.com/gorilla/mux@latest
# зафиксирует v1.6.2 в go.mod
go get github.com/gorilla/mux@v1.6.2
# тоже зафиксирует v1.6.2
go get github.com/gorilla/mux@e3702bed2
# запишет v1.6.3-0.20180517173623-c85619274f5d
go get github.com/gorilla/mux@c856192
# запишет v1.6.3-0.20180903154305-9e1f5955c0d2
go get github.com/gorilla/mux@master
Как релизить v2, v3...?
044
Указать в go.mod новую версию
module github.com/utrack/clay/v2


• master + версия в go.mod
• Бранч v2 (поддержка нескольких версий сразу)
• Директория /v2
go get (v2+)
045
$ go get github.com/utrack/clay/v2
go: finding github.com/utrack/clay/v2 v2.2.6
...
go get (v2+)
046
$ go get github.com/utrack/clay/v2
go: finding github.com/utrack/clay/v2 v2.2.6
...
$ go get github.com/utrack/clay@v2.2.6
go: finding github.com/utrack/clay v2.2.6
go: github.com/utrack/
clay@v0.0.0-20180828102536-0c2090de4d77: go.mod has post-
v0 module path "github.com/utrack/clay/v2" at revision
0c2090de4d77
go: error loading module requirements
go get (v2+)
047
$ go get github.com/utrack/clay/v2
go: finding github.com/utrack/clay/v2 v2.2.6
...
$ go get github.com/utrack/clay@v2.2.6
go: finding github.com/utrack/clay v2.2.6
go: github.com/utrack/
clay@v0.0.0-20180828102536-0c2090de4d77: go.mod has post-
v0 module path "github.com/utrack/clay/v2" at revision
0c2090de4d77
go: error loading module requirements
$ go get github.com/utrack/clay/v2@v2.2.6
А в старых проектах?
048
import "github.com/go-chi/chi/v3" - сломает клиентов
со старыми версиями go...
go1.9.7
go1.10.3
And don't forget to suffer :)
go get (старые проекты v2+)
049
$ go get github.com/go-chi/chi
go: finding github.com/go-chi/chi v3.3.3+incompatible
go: downloading github.com/go-chi/chi v3.3.3+incompatible
$ go get github.com/go-chi/chi@v3.3.0
go: finding github.com/go-chi/chi v3.3.0
go: downloading github.com/go-chi/chi v3.3.0+incompatible
go install, go build/run
050
$ go install github.com/utrack/clay/v2/cmd/protoc-gen-
goclay
Работает с go.mod - установит нужную версию
Не умеет в @<version>
$ go build -mod=vendor .
Соберёт бинарь, используя ./vendor
$ go build -mod=readonly .
Упадёт, если go.mod должен быть изменён в процессе
go mod
051
$ go mod init # создаст go.mod, подтянув зависимости
из ваших манифестов glide, dep и пр. (проблема с
replace - #24087)
$ go mod tidy -v # обновит go.mod
$ go mod vendor # заполнит vendor
$ go mod verify # сверит кеш модулей с go.sum
$ go mod graph # полный граф зависимостей
$ go mod graph | grep github.com/gogo/protobuf
gitlab.ozon.ru/map/fleet github.com/gogo/protobuf@v1.1.1
github.com/utrack/clay/v2@v2.2.1 github.com/gogo/protobuf@v1.0.0
gitlab.ozon.ru/map/types/v2@v2.5.0 github.com/gogo/protobuf@v1.1.1
go mod
052
$ go mod edit # редактирование go.mod (для роботов)
-module - поменять имя модуля
-require=path@version и -droprequire=path
-exclude=path@version и -dropexclude=path@version
-replace=old[@v]=new[@v] и -dropreplace=old[@v]
-json - печатает текущий go.mod в json
-fmt
-print
go mod
053
$ go mod why [-m] [-vendor] packages...
Выводит список пакетов (путь по графу зависимостей), до
использования пакета (или пакетов модуля)
$ go mod why -m github.com/mwf/vgo-modules/a
# github.com/mwf/vgo-modules/a
github.com/mwf/vgo-modules/c_user
github.com/mwf/vgo-modules/c
github.com/mwf/vgo-modules/a
go list
054
$ go list -m all # build list
github.com/mwf/vgo-modules
github.com/mwf/vgo-modules/a v0.0.1
github.com/mwf/vgo-modules/b v0.0.1
$ go list -m -versions github.com/gorilla/mux
github.com/gorilla/mux v1.2.0 v1.3.0 v1.4.0 v1.5.0
v1.6.0 v1.6.1 v1.6.2
go list - обновление зависимостей
055
$ go get github.com/go-chi/chi@v3.2.0
$ go list -m -u all
example.com/test
github.com/go-chi/chi v3.2.0+incompatible [v3.3.3+incompatible]
$ go get -u github.com/go-chi/chi
go: downloading github.com/go-chi/chi v3.3.3+incompatible
Есть go get -u=patch, работает только при наличии go.mod у
зависимости ¯_(ツ)_/¯
go test
056
$ go test ./... # как и раньше
$ go test all # запуск тестов всех зависимостей
Внимание, all включает тесты стандартной библиотеки!
#26317 cmd/go: exclude standard library from "all" pattern in modules
go test $(go list -f "{{if not .Standard}}{{.ImportPath}}{{end}}" $(go list -f
'{{ join .Deps "n"}}' $(go list -m)/...) $(go list -m)/...)
Вложенные модули
057
├── cmd/
│ ├── main.go # Точка входа в приложение
│ ├── go.mod # Зависимости бинаря
│
├── <пакеты библиотеки>
├── go.mod # Зависимости библиотеки
Вложенные модули
058
Гибкая работа с зависимостями
Отдельные релизы
git tag cmd/v1.2.3
git tag v2.2.3
Полезно для example и integration
Вложенные модули
059
├── example/
│ ├── ...
│ ├── go.mod
├── go.mod # Основные зависимости
module example.com/lib/example
require example.com/lib
replace example.com/lib => ../
Вложенные модули
060
https://github.com/heptiolabs/healthcheck
Liveness и Readiness хэндлеры для k8s
├─ checker/
│ ├─ db/
│ │ ├─ postgres/ # go.mod
│ │ ├─ mysql/ # go.mod
│ ├─ kafka/ # go.mod
├─ metrics/ # go.mod
├─ handler.go
├─ go.mod
Зависимости в Go
• Как это было?
• Minimal Version Selection
• Текущий статус
• Примеры работы с зависимостями
• Подводные камни
061
go run vs go build
062
https://github.com/golang/go/issues/26483
$ cd `mktemp -d`
$ curl -sS https://swtch.com/hello.go >hello.go
$ go mod -init -module=example.com/test
$ go run hello.go
$ cat go.mod
module example.com/test
require rsc.io/quote v1.5.2 // indirect
go run vs go build
063
https://github.com/golang/go/issues/26483
Откат обновления зависимостей
064
#26481 - cmd/go: downgrading a module with `go get` retains
indirect dependencies
С 0.1 -> A 0.1
C 0.2 -> A 0.2 (bug)
$ go list -m all
github.com/mwf/vgo-modules/c_user
github.com/mwf/vgo-modules/a v0.1.0
github.com/mwf/vgo-modules/c v0.1.0
Откат обновления зависимостей
065
main -> C 0.1 - хотим обновить до 0.2
go get github.com/mwf/vgo-modules/c@v0.2.0
$ go list -m all
github.com/mwf/vgo-modules/c_user
github.com/mwf/vgo-modules/a v0.2.0
github.com/mwf/vgo-modules/c v0.2.0
Откат обновления зависимостей
066
go test -> fail -> откат
go get github.com/mwf/vgo-modules/c@v0.1.0
module github.com/mwf/vgo-modules/c_user
require (
github.com/mwf/vgo-modules/a v0.2.0 // indirect
github.com/mwf/vgo-modules/c v0.1.0
)
Откат обновления зависимостей
067
Откат обновления зависимостей
068
go get github.com/mwf/vgo-modules/a@v0.1.0
module github.com/mwf/vgo-modules/c_user
require (
github.com/mwf/vgo-modules/c v0.1.0
)
¯_(ツ)_/¯
Важные issue
069
• #24250 cmd/go: allow installing programs (at specific
versions) to GOBIN
• #25922 cmd/go: clarify best practice for tool
dependencies
• #25873 cmd/go: allow forcing tags on/off during go mod
vendor, tidy
• #26404 cmd/go: export module information for binaries
programmatically
Итоги
070
Скорость работы
Воспроизводимость сборок (high-fidelity builds)
Можно использовать v1, v2... одновременно
Подмодули - гибкое управление зависимостями
- Боль с установкой бинарей
Спасибо!
https://research.swtch.com/vgo
https://www.youtube.com/watch?v=F8nrpe0XWRg
https://github.com/golang/go/wiki/Modules
go help modules

More Related Content

Similar to Minimal Version Selection - dependency management in Go 1.11, Golang Meetup 06.09.2018 [RUS]

Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.DrupalForumZP2012
 
Git для продолжающих
Git для продолжающихGit для продолжающих
Git для продолжающихIvan Evtukhovich
 
Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.Dmytro Olaresko
 
Git для начинающих
Git для начинающихGit для начинающих
Git для начинающихVadim Drobinin
 
Scino: DVCS на примере Git
Scino: DVCS на примере GitScino: DVCS на примере Git
Scino: DVCS на примере GitSCINO
 
GIT Slides (25.03.2015)
GIT Slides (25.03.2015)GIT Slides (25.03.2015)
GIT Slides (25.03.2015)Ilya V
 
Никита Шультайс. "Система управления версиями git"
Никита Шультайс. "Система управления версиями git"Никита Шультайс. "Система управления версиями git"
Никита Шультайс. "Система управления версиями git"Egor Stremousov
 
Олег Мохов "Драматическая история одной маленькой промостранички"
Олег Мохов "Драматическая история одной маленькой промостранички"Олег Мохов "Драматическая история одной маленькой промостранички"
Олег Мохов "Драматическая история одной маленькой промостранички"Yandex
 
Git in Agile project - XP Days Ukraine 2011
Git in Agile project - XP Days Ukraine 2011Git in Agile project - XP Days Ukraine 2011
Git in Agile project - XP Days Ukraine 2011Alexander Korotkikh
 
Презентация Git-flow (на русском)
Презентация Git-flow (на русском)Презентация Git-flow (на русском)
Презентация Git-flow (на русском)Sergey Chudakov
 
базовые принципы работы с Git
базовые принципы работы с Gitбазовые принципы работы с Git
базовые принципы работы с GitDressTester
 
Сборка web проекта с использованием Grunt и Node.js
Сборка web проекта с использованием Grunt и Node.jsСборка web проекта с использованием Grunt и Node.js
Сборка web проекта с использованием Grunt и Node.jsGeeksLab Odessa
 
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)Ontico
 
Алексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersАлексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersAleksey Fomkin
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!Roman Dvornov
 

Similar to Minimal Version Selection - dependency management in Go 1.11, Golang Meetup 06.09.2018 [RUS] (20)

Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.
 
Heroku. Zen cloud
Heroku. Zen cloudHeroku. Zen cloud
Heroku. Zen cloud
 
Git для продолжающих
Git для продолжающихGit для продолжающих
Git для продолжающих
 
Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.Системы управления версиями (VCS). Знакомство с Git.
Системы управления версиями (VCS). Знакомство с Git.
 
Git для начинающих
Git для начинающихGit для начинающих
Git для начинающих
 
Scino: DVCS на примере Git
Scino: DVCS на примере GitScino: DVCS на примере Git
Scino: DVCS на примере Git
 
GIT Slides (25.03.2015)
GIT Slides (25.03.2015)GIT Slides (25.03.2015)
GIT Slides (25.03.2015)
 
Gitlab devconf
Gitlab devconfGitlab devconf
Gitlab devconf
 
Никита Шультайс. "Система управления версиями git"
Никита Шультайс. "Система управления версиями git"Никита Шультайс. "Система управления версиями git"
Никита Шультайс. "Система управления версиями git"
 
Олег Мохов "Драматическая история одной маленькой промостранички"
Олег Мохов "Драматическая история одной маленькой промостранички"Олег Мохов "Драматическая история одной маленькой промостранички"
Олег Мохов "Драматическая история одной маленькой промостранички"
 
Git in Agile project - XP Days Ukraine 2011
Git in Agile project - XP Days Ukraine 2011Git in Agile project - XP Days Ukraine 2011
Git in Agile project - XP Days Ukraine 2011
 
Приручаем Git
Приручаем GitПриручаем Git
Приручаем Git
 
GitFlow_MOEX
GitFlow_MOEXGitFlow_MOEX
GitFlow_MOEX
 
Презентация Git-flow (на русском)
Презентация Git-flow (на русском)Презентация Git-flow (на русском)
Презентация Git-flow (на русском)
 
базовые принципы работы с Git
базовые принципы работы с Gitбазовые принципы работы с Git
базовые принципы работы с Git
 
Сборка web проекта с использованием Grunt и Node.js
Сборка web проекта с использованием Grunt и Node.jsСборка web проекта с использованием Grunt и Node.js
Сборка web проекта с использованием Grunt и Node.js
 
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)
Практическое применение WebWorkers / Алексей Фомкин (Data Monsters)
 
Алексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web WorkersАлексей Фомкин, Практическое применение Web Workers
Алексей Фомкин, Практическое применение Web Workers
 
Gradle in Enterprise, Is it possible?
Gradle in Enterprise, Is it possible?Gradle in Enterprise, Is it possible?
Gradle in Enterprise, Is it possible?
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 

Minimal Version Selection - dependency management in Go 1.11, Golang Meetup 06.09.2018 [RUS]

  • 1. Управление зависимостями в Go 1.11 Minimal Version Selection
  • 2. Ivan Korolev Senior Go Developer ivan.korolev@ozon.ru github.com/mwf
  • 4. Зависимости в Go • Как это было? • Minimal Version Selection • Текущий статус • Примеры работы с зависимостями • Подводные камни 04
  • 5. Вместо предисловия 05 What is Software Engineering? Software engineering is what happens to programming  when you add time and other programmers.
  • 6. В начале было... 06 • pre-go1 - makefiles, gobuild (2009) • pre-go1 - goinstall (2010) - VCS-репозитории • go 1 - go get (2011) • go 1.2 FAQ: Import Compatibility Rule (2013) • создан gopkg.in (2014) - gopkg.in/yaml.v2 go get -u golang.org/x/tools/cmd/goimports
  • 7. Vendoring и воспроизводимые сборки (reproducible builds) 07 • goven (2012) - модификация импортов • godep (2013) - модификация $GOPATH • gb, glide, gom ... (2014) • go 1.5 - vendoring в тулчейне "original.com/pkg" -> "you.com/external/original.com/pkg" GO15VENDOREXPERIMENT=1 go build
  • 8. Vendoring - проблемы 08 • Дюжина менеджеров зависимостей (с разным форматом) • Нет поддержки SemVer в go toolchain • Коммитить папку vendor в репу - 
 cannot use opts 
 (type "<lib>/vendor/google.golang.org/ grpc".CallOption) as type []"<app>/vendor/ google.golang.org/grpc".CallOption
  • 9. "Одно кольцо чтоб править всеми" 09 2016-2017 - Sam Boyer's dep, "официальный эксперимент"
  • 10. Встречаем... vgo (февраль 2018) 010 • Semantic Import Versioning
 import "github.com/go-yaml/yaml/v2" • Go module - коллекция пакетов с общим путём • Minimal Version Selection • $GOPATH - больше не завязаны на src
  • 12. Go modules 012 package main import ( "fmt" "rsc.io/quote" ) func main() { fmt.Println(quote.Hello()) }
  • 13. Go modules 013 $ go mod init example.com/test go: creating new go.mod: module example.com/test $ cat go.mod module example.com/test
  • 14. Go modules 014 $ go mod tidy go: finding rsc.io/quote v1.5.2 go: downloading rsc.io/quote v1.5.2 go: finding rsc.io/sampler v1.3.0 go: finding golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c go: downloading rsc.io/sampler v1.3.0 go: downloading golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
  • 15. Go modules 015 $ cat go.mod module example.com/test require rsc.io/quote v1.5.2
  • 16. Зависимости в Go • Как это было? • Minimal Version Selection • Текущий статус • Примеры работы с зависимостями • Подводные камни 016
  • 17. Minimal Version Selection 017 build list - список всех модулей зависимостей и их версий Задачи: • Построение build list • Обновление всех зависимостей • Обновление модуля до нужной версии • Откат модуля до нужной версии
  • 19. MVS - сборка (рекурсивно) 019
  • 20. MVS - сборка (обход графа) 020
  • 21. MVS - обновление всех модулей 021
  • 22. MVS - мин. список зависимостей алгоритм R 022 Реверсивный обратный обход E1.3, D1.4, B1.2, G1.1, F1.1, C1.3 C1.3, F1.1, G1.1, B1.2, D1.4, E1.3
  • 23. MVS - обновление одного модуля 023
  • 24. MVS - обновление одного модуля 024 build list + алгоритм R E1.2, D1.3, B1.2, D1.4, C1.2, G1.1, F1.1, C1.3 C1.3, F1.1, G1.1, C1.2, D1.4, B1.2, D1.3 E1.2
  • 25. MVS - откат одного модуля 025
  • 26. MVS - откат одного модуля 026 маркировка недоступных+ алгоритм R E1.1, D1.1, B1.1, D1.2, E1.2, C1.1 C1.1, E1.2, D1.2, B1.1, D1.1, E1.1
  • 27. Minimal Version Selection 027 Простота реализации - алгоритмы на графах Минимальность вносимых изменений Не NP-полная (не нужно решать 3SAT) Локальные replace и exclude Воспроизводимость билдов 👍
  • 28. MVS - воспроизводимость билдов 028 Библиотека не должна диктовать сборку - replace и exclude локальные. Cargo и Dep - навязывают последние версии через манифест. Есть вероятность забыть обновить манифест - билд нестабилен (B > 1.1, используем B 1.2)
  • 29. Зависимости в Go • Как это было? • Minimal Version Selection • Текущий статус • Примеры работы с зависимостями • Подводные камни 029
  • 30. Статус 13 июля - vgo влили в go devel 20 июля - go1.11beta2 24 августа - go1.11 go help modules 030
  • 31. Статус - обратная совместимость GO111MODULE=auto GO111MODULE=on go build <...> Зачем? Можно бы было определять "динамически" по наличию go.mod в репозитории... 031
  • 32. Статус - обратная совместимость $GOPATH/src/A - без go.mod, импортирует B $GOPATH/src/B - есть go.mod, импортирует C $GOPATH/src/C - отсутствует 032
  • 33. Статус - обратная совместимость 033 $ cd $GOPATH/src/A $ go build # B ../B/b.go:10: import "C": C not found <Странно, попробуем собрать B напрямую> $ go build B ../B/b.go:10: import "C": C not found
  • 34. Статус - обратная совместимость 034 <Но я же только что работал с B!> $ cd ../B $ go build $ <ЧТО? Собирается же> $ go build B $ go build С $
  • 35. Статус - обратная совместимость 035 <ОК, вернёмся к A > $ cd ../A $ go build ../B/b.go:10: import "C": C not found
  • 36. Начало работы (fail 1) $ cd `mktemp -d` $ go get github.com/gorilla/mux@latest go: cannot use path@version syntax in GOPATH mode Почему?! GO111MODULE=auto 036
  • 37. Начало работы (fail 2) $ export GO111MODULE=on ... $ go get github.com/alecthomas/gometalinter go: cannot find main module; see 'go help modules' 037
  • 38. Начало работы $ cd `mktemp -d` $ go mod init example.com/test $ go get github.com/gorilla/mux@latest go: finding github.com/gorilla/mux v1.6.2 go: downloading github.com/gorilla/mux v1.6.2 $ cat go.mod module example.com/test require github.com/gorilla/mux v1.6.2 // indirect 038
  • 39. go.mod 039 module example.com/test require ( github.com/BurntSushi/toml v0.3.0 // indirect github.com/apache/thrift v0.0.0-20180627210808-129f332d72fa // indirect github.com/go-chi/chi v3.3.3+incompatible github.com/go-chi/cors v1.0.0 ... google.golang.org/grpc v1.13.0 )
  • 40. go.sum $ cat go.sum github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/ r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= $GOPATH/pkg/mod/<import_path> $GOPATH/pkg/mod/cache $ go clean -modcache 040
  • 41. Хранение версий $ ls -al $GOPATH/pkg/mod/cache/download/github.com/gorilla/mux/@v/ total 360 drwxr-xr-x 15 ikorolev staff 480 Jul 24 13:18 . drwxr-xr-x 3 ikorolev staff 96 Jul 24 13:06 .. -rw-r--r-- 1 ikorolev staff 21 Jul 24 13:18 list -rw------- 1 ikorolev staff 123 Jul 24 13:18 v1.5.0.info -rw------- 1 ikorolev staff 30 Jul 24 13:18 v1.5.0.mod -rw-r--r-- 1 ikorolev staff 37948 Jul 24 13:18 v1.5.0.zip -rw-r--r-- 1 ikorolev staff 47 Jul 24 13:18 v1.5.0.ziphash -rw------- 1 ikorolev staff 123 Jul 24 13:17 v1.6.1.info -rw------- 1 ikorolev staff 30 Jul 24 13:17 v1.6.1.mod -rw-r--r-- 1 ikorolev staff 46619 Jul 24 13:17 v1.6.1.zip -rw-r--r-- 1 ikorolev staff 47 Jul 24 13:17 v1.6.1.ziphash 041
  • 42. Хранение версий $ ls -al $GOPATH/src/mod/github.com/gorilla/ total 0 drwxr-xr-x 5 ikorolev staff 160 Jul 24 13:18 . drwxr-xr-x 9 ikorolev staff 288 Jul 24 13:44 .. dr-xr-xr-x 16 ikorolev staff 512 Jul 24 13:18 mux@v1.5.0 dr-xr-xr-x 21 ikorolev staff 672 Jul 24 13:17 mux@v1.6.1 dr-xr-xr-x 22 ikorolev staff 704 Jul 24 13:06 mux@v1.6.2 042
  • 43. go get 043 # или просто 'go get') go get github.com/gorilla/mux@latest # зафиксирует v1.6.2 в go.mod go get github.com/gorilla/mux@v1.6.2 # тоже зафиксирует v1.6.2 go get github.com/gorilla/mux@e3702bed2 # запишет v1.6.3-0.20180517173623-c85619274f5d go get github.com/gorilla/mux@c856192 # запишет v1.6.3-0.20180903154305-9e1f5955c0d2 go get github.com/gorilla/mux@master
  • 44. Как релизить v2, v3...? 044 Указать в go.mod новую версию module github.com/utrack/clay/v2 
 • master + версия в go.mod • Бранч v2 (поддержка нескольких версий сразу) • Директория /v2
  • 45. go get (v2+) 045 $ go get github.com/utrack/clay/v2 go: finding github.com/utrack/clay/v2 v2.2.6 ...
  • 46. go get (v2+) 046 $ go get github.com/utrack/clay/v2 go: finding github.com/utrack/clay/v2 v2.2.6 ... $ go get github.com/utrack/clay@v2.2.6 go: finding github.com/utrack/clay v2.2.6 go: github.com/utrack/ clay@v0.0.0-20180828102536-0c2090de4d77: go.mod has post- v0 module path "github.com/utrack/clay/v2" at revision 0c2090de4d77 go: error loading module requirements
  • 47. go get (v2+) 047 $ go get github.com/utrack/clay/v2 go: finding github.com/utrack/clay/v2 v2.2.6 ... $ go get github.com/utrack/clay@v2.2.6 go: finding github.com/utrack/clay v2.2.6 go: github.com/utrack/ clay@v0.0.0-20180828102536-0c2090de4d77: go.mod has post- v0 module path "github.com/utrack/clay/v2" at revision 0c2090de4d77 go: error loading module requirements $ go get github.com/utrack/clay/v2@v2.2.6
  • 48. А в старых проектах? 048 import "github.com/go-chi/chi/v3" - сломает клиентов со старыми версиями go... go1.9.7 go1.10.3 And don't forget to suffer :)
  • 49. go get (старые проекты v2+) 049 $ go get github.com/go-chi/chi go: finding github.com/go-chi/chi v3.3.3+incompatible go: downloading github.com/go-chi/chi v3.3.3+incompatible $ go get github.com/go-chi/chi@v3.3.0 go: finding github.com/go-chi/chi v3.3.0 go: downloading github.com/go-chi/chi v3.3.0+incompatible
  • 50. go install, go build/run 050 $ go install github.com/utrack/clay/v2/cmd/protoc-gen- goclay Работает с go.mod - установит нужную версию Не умеет в @<version> $ go build -mod=vendor . Соберёт бинарь, используя ./vendor $ go build -mod=readonly . Упадёт, если go.mod должен быть изменён в процессе
  • 51. go mod 051 $ go mod init # создаст go.mod, подтянув зависимости из ваших манифестов glide, dep и пр. (проблема с replace - #24087) $ go mod tidy -v # обновит go.mod $ go mod vendor # заполнит vendor $ go mod verify # сверит кеш модулей с go.sum $ go mod graph # полный граф зависимостей $ go mod graph | grep github.com/gogo/protobuf gitlab.ozon.ru/map/fleet github.com/gogo/protobuf@v1.1.1 github.com/utrack/clay/v2@v2.2.1 github.com/gogo/protobuf@v1.0.0 gitlab.ozon.ru/map/types/v2@v2.5.0 github.com/gogo/protobuf@v1.1.1
  • 52. go mod 052 $ go mod edit # редактирование go.mod (для роботов) -module - поменять имя модуля -require=path@version и -droprequire=path -exclude=path@version и -dropexclude=path@version -replace=old[@v]=new[@v] и -dropreplace=old[@v] -json - печатает текущий go.mod в json -fmt -print
  • 53. go mod 053 $ go mod why [-m] [-vendor] packages... Выводит список пакетов (путь по графу зависимостей), до использования пакета (или пакетов модуля) $ go mod why -m github.com/mwf/vgo-modules/a # github.com/mwf/vgo-modules/a github.com/mwf/vgo-modules/c_user github.com/mwf/vgo-modules/c github.com/mwf/vgo-modules/a
  • 54. go list 054 $ go list -m all # build list github.com/mwf/vgo-modules github.com/mwf/vgo-modules/a v0.0.1 github.com/mwf/vgo-modules/b v0.0.1 $ go list -m -versions github.com/gorilla/mux github.com/gorilla/mux v1.2.0 v1.3.0 v1.4.0 v1.5.0 v1.6.0 v1.6.1 v1.6.2
  • 55. go list - обновление зависимостей 055 $ go get github.com/go-chi/chi@v3.2.0 $ go list -m -u all example.com/test github.com/go-chi/chi v3.2.0+incompatible [v3.3.3+incompatible] $ go get -u github.com/go-chi/chi go: downloading github.com/go-chi/chi v3.3.3+incompatible Есть go get -u=patch, работает только при наличии go.mod у зависимости ¯_(ツ)_/¯
  • 56. go test 056 $ go test ./... # как и раньше $ go test all # запуск тестов всех зависимостей Внимание, all включает тесты стандартной библиотеки! #26317 cmd/go: exclude standard library from "all" pattern in modules go test $(go list -f "{{if not .Standard}}{{.ImportPath}}{{end}}" $(go list -f '{{ join .Deps "n"}}' $(go list -m)/...) $(go list -m)/...)
  • 57. Вложенные модули 057 ├── cmd/ │ ├── main.go # Точка входа в приложение │ ├── go.mod # Зависимости бинаря │ ├── <пакеты библиотеки> ├── go.mod # Зависимости библиотеки
  • 58. Вложенные модули 058 Гибкая работа с зависимостями Отдельные релизы git tag cmd/v1.2.3 git tag v2.2.3 Полезно для example и integration
  • 59. Вложенные модули 059 ├── example/ │ ├── ... │ ├── go.mod ├── go.mod # Основные зависимости module example.com/lib/example require example.com/lib replace example.com/lib => ../
  • 60. Вложенные модули 060 https://github.com/heptiolabs/healthcheck Liveness и Readiness хэндлеры для k8s ├─ checker/ │ ├─ db/ │ │ ├─ postgres/ # go.mod │ │ ├─ mysql/ # go.mod │ ├─ kafka/ # go.mod ├─ metrics/ # go.mod ├─ handler.go ├─ go.mod
  • 61. Зависимости в Go • Как это было? • Minimal Version Selection • Текущий статус • Примеры работы с зависимостями • Подводные камни 061
  • 62. go run vs go build 062 https://github.com/golang/go/issues/26483 $ cd `mktemp -d` $ curl -sS https://swtch.com/hello.go >hello.go $ go mod -init -module=example.com/test $ go run hello.go $ cat go.mod module example.com/test require rsc.io/quote v1.5.2 // indirect
  • 63. go run vs go build 063 https://github.com/golang/go/issues/26483
  • 64. Откат обновления зависимостей 064 #26481 - cmd/go: downgrading a module with `go get` retains indirect dependencies С 0.1 -> A 0.1 C 0.2 -> A 0.2 (bug) $ go list -m all github.com/mwf/vgo-modules/c_user github.com/mwf/vgo-modules/a v0.1.0 github.com/mwf/vgo-modules/c v0.1.0
  • 65. Откат обновления зависимостей 065 main -> C 0.1 - хотим обновить до 0.2 go get github.com/mwf/vgo-modules/c@v0.2.0 $ go list -m all github.com/mwf/vgo-modules/c_user github.com/mwf/vgo-modules/a v0.2.0 github.com/mwf/vgo-modules/c v0.2.0
  • 66. Откат обновления зависимостей 066 go test -> fail -> откат go get github.com/mwf/vgo-modules/c@v0.1.0 module github.com/mwf/vgo-modules/c_user require ( github.com/mwf/vgo-modules/a v0.2.0 // indirect github.com/mwf/vgo-modules/c v0.1.0 )
  • 68. Откат обновления зависимостей 068 go get github.com/mwf/vgo-modules/a@v0.1.0 module github.com/mwf/vgo-modules/c_user require ( github.com/mwf/vgo-modules/c v0.1.0 ) ¯_(ツ)_/¯
  • 69. Важные issue 069 • #24250 cmd/go: allow installing programs (at specific versions) to GOBIN • #25922 cmd/go: clarify best practice for tool dependencies • #25873 cmd/go: allow forcing tags on/off during go mod vendor, tidy • #26404 cmd/go: export module information for binaries programmatically
  • 70. Итоги 070 Скорость работы Воспроизводимость сборок (high-fidelity builds) Можно использовать v1, v2... одновременно Подмодули - гибкое управление зависимостями - Боль с установкой бинарей