четверг, 11 июля 2019 г.

Флаги тестирования в Golang

Команда 'go test' принимает флаги, которые применяются к самому 'go test', и флаги, которые применяются к полученному бинарному файлу теста.

Несколько флагов управляют профилированием и записывают профиль выполнения, подходящий для "go tool pprof"; запустите "go tool pprof -h" для получения дополнительной информации. Параметры --alloc_space, --alloc_objects и --show_bytes в pprof управляют представлением информации.

Следующие флаги распознаются командой 'go test' и контролируют выполнение любого теста:

-bench regexp

Запускать только те эталонные тесты (benchmarks), которые соответствуют регулярному выражению. По умолчанию эталонные тесты не запускаются. Чтобы запустить все эталонные тесты, используйте '-bench .' или '-bench=.'. Регулярное выражение разделяется символами косой чертой без скобок (/) в последовательности регулярных выражений, и каждая часть идентификатора эталонного теста должна соответствовать элементу в последовательности, если есть. Возможные родители соотвествий запускаются с b.N=1, чтобы идентифицировать нижележащие эталонные тесты. Например, учитывая -bench =X/Y, запускаются эталонные тесты верхнего уровня, соответствующие X с b.N=1, чтобы найти любые нижележащие эталонные тесты, соответствующие Y, которые потом запускаются полностью.


-benchtime t

Запустить достаточно итераций каждого эталонного теста, чтобы взять t, указанный как time.Duration (например, -benchtime 1h30s). По умолчанию это 1 секунда (1s). Специальный синтаксис Nx означает запуск теста N раз (например, -benchtime 100x).


-count n

Запустите каждый тест и эталонный тест n раз (по умолчанию 1). Если установлена опция -cpu, запускать n раз для каждого значения GOMAXPROCS. Примеры всегда запускаются один раз.


-cover

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


-covermode set,count,atomic

Установить режим анализа покрытия для пакета/пакетов, которые тестируются. По умолчанию установлено "set", если не включена опция -race, в этом случае это "atomic".
Значения:
set: bool: это утверждение выполняется?
count: int: сколько раз выполняется это утверждение?
atomic: int: то же самое что count, но корректный в многопоточных тестах; значительно более затратный.
Включает флаг -cover.


-coverpkg pattern1,pattern2,pattern3

Применить анализ покрытия в каждом тесте к пакетам, соответствующим шаблонам (patterns). По умолчанию для каждого теста анализируется только тестируемый пакет. Смотрите 'go help packages' для описания шаблонов пакетов.
Включает флаг -cover.


-cpu 1,2,4

Укажите список значений GOMAXPROCS, для которых тесты или эталонные тесты должны быть выполнены. По умолчанию используется текущее значение GOMAXPROCS.


-failfast

Не запускать новые тесты после первого неудачного теста.


-list regexp

Перечислите тесты, эталонные тесты (benchmarks) или примеры, соответствующие регулярному выражению. Никаких тестов, эталонных тестов или примеров запускаться не будет. Это будет только список тестов верхнего уровня. Никакие субтесты или суб-эталонные тесты не будут показаны.


-parallel n

Разрешить параллельное выполнение тестовых функций, которые вызывают t.Parallel. Значение этого флага - максимальное количество тестов для одновременного запуска; по умолчанию для него установлено значение GOMAXPROCS. Обратите внимание, что -parallel применяется только в одном бинарном тесте. Команда go test может запускать тесты для разных пакетов параллельно, в соответствии с настройкой флага -p (см. go help build).


-run regexp

Запускайте только те тесты и примеры, которые соответствуют регулярному выражению. Для тестов регулярное выражение разделяется символами косой черты без скобок (/) в последовательности регулярных выражений, и каждая часть идентификатора теста должна совпадать с соответствующим элементом в последовательности, если есть. Обратите внимание, что возможные родители соответствий тоже запускаются, так что -run =X/Y соответствует, запускает и сообщает результаты всех тестов, соответствующих X, даже без тестов, соответствующих Y, потому что он должен запустить их, чтобы искать эти под-тесты.


-short

Сообщить длительным тестам, чтобы они сократили свое время выполнения. Флаг выключен по умолчанию, но установлен во время all.bash, чтобы установка дерева Go могла выполнять проверку работоспособности, но не тратить время на прохождение исчерпывающих длительных тестов.


-timeout d

Если тестовый бинарный файл работает дольше, чем продолжительность d, запускать panic. Если d равно 0, тайм-аут отключен. По умолчанию 10 минут (10m).


-v

Подробный вывод: протоколировать все тесты по мере их запуска. Также распечатать весь текст из вызовов Log и Logf, даже если тест пройден успешно.


-vet list

Сконфигурировать вызов "go vet" во время "go test" чтобы использовать разделенный запятыми список проверок. Если список пуст, "go test" запускает "go vet" с курируемым списком проверок, считаемых всегда заслуживающими внимания. Если list равен "off", "go test" вообще не запускает "go vet".


Следующие флаги также распознаются 'go test' и могут использоваться для профилирования тестов во время выполнения:

-benchmem

Распечатать статистику распределения памяти для тестов.


-blockprofile block.out

Записать профиль блокировки goroutine в указанный файл когда все тесты завершены. Записывает тестовый бинарный файл как делает флаг -c.


-blockprofilerate n

Контролировать детализацию профилей блокировки goroutine посредством вызова runtime.SetBlockProfileRate с n. См. 'go doc runtime.SetBlockProfileRate'. Целью профилировщика является выборка в среднем одного блокирующего события каждые n наносекунд, которые программа тратит на блокировку. По умолчанию, если -test.blockprofile установлен без этого флага, все события блокировки записаны, эквивалентно -test.blockprofilerate=1.


-coverprofile cover.out

Записать профиль покрытия в файл после того, как все тесты пройдены.
Включает флаг -cover.


-cpuprofile cpu.out

Записать профиль CPU в указанный файл перед выходом. Записывает тестовый бинарный файл как делает флаг -c.


-memprofile mem.out

Записать профиль распределения в файл после того, как все тесты пройдены. Записывает тестовый бинарный файл как флаг -c.


-memprofilerate n

Включить более точные (и дорогие) профили выделения памяти установкой runtime.MemProfileRate. Смотрите 'go doc runtime.MemProfileRate'. Чтобы профилировать все распределения памяти, используйте -test.memprofilerate=1.


-mutexprofile mutex.out

Записать конфликтный профиль мьютекса в указанный файл когда все тесты завершены. Записывает тестовый бинарный файл как флаг -c.


-mutexprofilefraction n

Образец 1 в n стека следов goroutines, содержащих утвержденный мьютекс.


-outputdir directory

Поместить выходные файлы из профилирования в указанный каталог, по умолчанию каталог, в котором запущен "go test".


-trace trace.out

Записать трассировку выполнения в указанный файл перед выходом.


Каждый из этих флагов также распознается с помощью необязательного 'test.' префикса, как в -test.v. Однако при непосредственном вызове сгенерированного тестового бинарного файла (результат 'go test -c') префикс обязателен.

Команда 'go test' переписывает или удаляет распознанные флаги, в зависимости от ситуации, как до, так и после необязательного списка пакетов, до вызова тестового бинарного файла.

Например, команда

go test -v -myflag testdata -cpuprofile=prof.out -x

скомпилирует тестовый бинарный файл, а затем запустит его как

pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out

(Флаг -x удален, потому что он применяется только к выполнению команды go, а не к самому тесту.)

Флаги теста, которые генерируют профили (кроме покрытия), также оставляют тестовый бинарный файл в pkg.test для использования при анализе профилей.

Когда 'go test' запускает тестовый бинарный файл, он делает это из каталога исходного кода соответствующего пакета. В зависимости от теста может потребоваться сделать то же самое при непосредственном вызове сгенерированного тестового бинарного файла.

Список пакетов командной строки, если он присутствует, должен отображаться перед любым флагом, неизвестным команде go test. Продолжая приведенный выше пример, список пакетов должен отображаться перед -myflag, но может отображаться с любой стороны от -v.

Когда 'go test' выполняется в режиме списка пакетов, 'go test' кэширует успешные результаты тестирования пакета, чтобы избежать ненужного повторного запуска тестов. Чтобы отключить тестовое кэширование, используйте любой тестовый флаг или аргумент, кроме кешируемых флагов. Идиоматический способ явного отключения кэширования тестов - использовать -count=1.

Чтобы аргумент для тестового бинарного файла не интерпретировался как известный флаг или имя пакета, используйте параметр -args (см. go help test), который передает оставшуюся часть командной строки в тестовый бинарный файл без интерпретации и не измененной.

Например, команда

go test -v -args -x -v

скомпилирует тестовый бинарный файл, а затем запустит его как

pkg.test -test.v -x -v

Так же,

go test -args math

скомпилирует тестовый бинарный файл, а затем запустит его как

pkg.test math

В первом примере -x и второй -v передаются в тестовый бинарный файл без изменений и не влияют на саму команду go. Во втором примере аргумент math передается в тестовый бинарный файл, а не интерпретируется как список пакетов.


Читайте также:


Списки пакетов и шаблоны в Golang

Многие команды применяются к набору пакетов:

go action [packages]

Обычно [packages] представляет собой список путей импорта.

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

В противном случае путь импорта P обозначает пакет, найденный в каталоге DIR/src/P для некоторого DIR, указанного в переменной среды GOPATH (более подробно см. go help gopath).

Если пути импорта не указаны, действие применяется к пакету в текущем каталоге.

Есть четыре зарезервированных имени для путей, которые не должны использоваться для пакетов, которые будут собраны с помощью инструмента go:

- "main" обозначает пакет верхнего уровня в отдельном исполняемом файле.

- "all" распространяется на все пакеты, найденные во всех деревьях GOPATH. Например, 'go list all' перечисляет все пакеты в локальной системе. При использовании модулей "all" распространяется на все пакеты в основном модуле и их зависимости, в том числе зависимости, необходимые для тестирования любого из них.

- "std", как и все, распространяется только на пакеты в стандартной библиотеке Go.

- "cmd" распространяется на команды репозитория Go и их внутренние библиотеки.

Пути импорта, начинающиеся с "cmd/", соответствуют только исходному коду в репозитории Go.

Путь импорта - это шаблон, если он содержит один или несколько подстановочных знаков "...", каждая из которых может соответствовать любой строке, включая пустую строку и строки, содержащие косую черту. Такой шаблон распространяется на все каталоги пакетов, найденные в деревьях GOPATH с именами, соответствующими шаблонам.

Чтобы сделать общие шаблоны более удобными, существует два особых случая. Во-первых, /... в конце шаблона может соответствовать пустой строке, так что net/... соответствует и net, и пакетам в его подкаталогах, например, net/http. Во-вторых, любой разделенный косой чертой элемент шаблона, содержащий подстановочный знак, никогда не участвует в совпадении элемента "vendor" в пути к вендорному пакету, так что ./... не соответствует пакетам в подкаталогах ./vendor или ./mycode/vendor, но ./vendor/... и ./mycode/vendor/... соответствуют. Однако обратите внимание, что каталог с именем vendor, который сам содержит код, не является вендорным пакетом: cmd/vendor будет командой с именем vendor, и шаблон cmd/... соответствует ей.

В пути импорта также можно указать пакет для загрузки из удаленного хранилища. Запустите go help importpath для получения подробной информации.

Каждый пакет в программе должен иметь уникальный путь импорта. По договоренности, это организовано путем запуска каждого пути с уникальным префиксом, который принадлежит вам. Например, все внутренние пути в Google начинаются с 'google', а пути, обозначающие удаленные репозитории, начинаются с пути к коду, например, 'github.com/user/repo'.

Пакеты в программе не обязательно должны иметь уникальные имена пакетов, но есть два зарезервированных имени пакета со специальным значением. Имя main указывает на команду, а не на библиотеку. Команды встроены в бинарные файлы и не могут быть импортированы. Имя documentation указывает на документацию для не-Go программы в каталоге. Файлы в документации пакета игнорируются командой go.

В особом случае, если список пакетов представляет собой список файлов .go из одного каталога, команда применяется к одному синтезированному пакету, составленному именно из этих файлов, игнорируя все ограничения сборки в этих файлах и игнорируя любые другие файлы в каталоге.

Каталог и имена файлов, начинающиеся с "." или "_" игнорируются инструментом go, как и каталоги с именем "testdata".


Читайте также:


среда, 10 июля 2019 г.

Команда go get в режиме с поддержкой модулей

Команда 'go get' меняет поведение в зависимости от того, выполняется ли команда go в режиме с поддержкой модулей или в старом режиме GOPATH. Этот текст справки, доступный как 'go help module-get' даже в устаревшем режиме GOPATH, описывает 'go get', так как он работает в режиме с поддержкой модулей (module-aware mode).

Использование:

go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]

get разрешает и добавляет зависимости в текущий модуль разработки, а затем собирает и устанавливает их.

Первый шаг - определить, какие зависимости добавить.

Для каждого именованного пакета или шаблона пакета get должен решить, какую версию соответствующего модуля использовать. По умолчанию get выбирает последнюю версию релиза с тегами, такую как v0.4.5 или v1.2.3. Если нет версий с тегами, get выбирает последнюю версию с тегами, например, v0.0.1-pre1. Если нет версий с тегами, get выбирает последний известный коммит.

Этот выбор версии по умолчанию можно переопределить, добавив суффикс @version к аргументу пакета, как в 'go get golang.org/x/text@v0.3.0'. Для модулей, хранящихся в репозиториях с системой контроля версий, суффиксом версии также может быть хеш коммита, идентификатор ветви или другой синтаксис, известный системе контроля версий, как в 'go get golang.org/x/text@master'. Суффикс версии @latest явно запрашивает поведение по умолчанию, описанное выше.

Если рассматриваемый модуль уже является зависимостью текущего модуля разработки, то get обновит требуемую версию. Указание версии более ранней, чем текущая требуемая версия, является действительным и понижает зависимость. Суффикс версии @none указывает, что зависимость должна быть полностью удалена, понижение или удаление модулей в зависимости от нее по мере необходимости.

Хотя get по умолчанию использует последнюю версию модуля, содержащего именованный пакет, он не использует последнюю версию зависимостей этого модуля. Вместо этого он предпочитает использовать конкретные версии зависимостей, запрошенные этим модулем. Например, если для последней версии A требуется модуль B v1.2.3, в то время как B v1.2.4 и v1.3.1 также доступны, то 'go get A' будет использовать самую последнюю версию A, но затем использовать B v1.2.3, как того требует A . (Если для конкретного модуля существуют конкурирующие требования, то 'go get' разрешает эти требования, выбирая максимально запрашиваемую версию.)

Флаг -u предписывает обновить зависимости для использования более новых минорных или исправлений, когда они доступны. Продолжая предыдущий пример, 'go get -u A' будет использовать самую последнюю версию A с B v1.3.1 (не B v1.2.3).

Флаг -u=patch (не -u patch) дает указание обновить зависимости, чтобы использовать более новые выпуски исправлений, когда они доступны. Продолжая предыдущий пример, 'go get -u=patch A' будет использовать самую последнюю версию A с B v1.2.4 (не B v1.2.3).

В общем, добавление новой зависимости может потребовать обновления существующих зависимостей, чтобы сохранить работоспособную сборку, и 'go get' делает это автоматически. Точно так же, понижение одной зависимости может потребовать понижения других зависимостей, и 'go get' также делает это автоматически.

Флаг -m дает указание остановиться здесь после разрешения, обновления и понижения модулей и обновления go.mod. При использовании -m каждый указанный путь к пакету также должен быть путем к модулю, а не путем импорта пакета ниже корня модуля.

Флаг -insecure разрешает выборку из репозиториев и разрешение пользовательских доменов с использованием небезопасных схем, таких как HTTP. Используйте с осторожностью.

Вторым шагом является загрузка (при необходимости), сборка и установка именованных пакетов.

Если аргумент присваивает имя модулю, а не пакету (так как в корневом каталоге модуля нет исходного Go кода), то этап установки пропускается для этого аргумента, а не вызывает ошибку сборки. Например, 'go get golang.org/x/perf' успешно выполняется, даже если нет кода, соответствующего этому пути импорта.

Обратите внимание, что шаблоны пакетов разрешены и раскрываются после разрешения версий модуля. Например, 'go get golang.org/x/perf/cmd/...' добавляет последнюю версию golang.org/x/perf, а затем устанавливает команды в этой последней версии.

Флаг -d указывает get загрузить исходный код, необходимый для сборки именованных пакетов, включая загрузку необходимых зависимостей, но не создавать и устанавливать их.

Без аргументов пакета 'go get' применяется к основному модулю и к пакету Go в текущем каталоге, если таковые имеются. В частности, 'go get -u' и 'go get -u=patch' обновляют все зависимости основного модуля. Без аргументов пакета, а также без -u 'go get' не намного больше, чем 'go install', а 'go get -d' не намного больше, чем 'go list'.

Для получения дополнительной информации о модулях см. go help modules.

Подробнее об указании пакетов см. go help packages.

Этот текст описывает поведение get используя модули для управления исходным кодом и зависимостями. Если вместо этого команда go выполняется в режиме GOPATH, информация о флагах и эффектах get изменяется, как и 'go help get'. Смотрите go help modules и go help gopath-get.

Смотрите также: go build, go install, go clean, go mod.


Читайте также:


понедельник, 8 июля 2019 г.

Модули и вендоринг в Golang

При использовании модулей команда go полностью игнорирует каталоги поставщиков (vendor directories).

По умолчанию команда go удовлетворяет зависимости, загружая модули из их источников и используя эти загруженные копии (после проверки, как описано в предыдущем посте). Чтобы разрешить взаимодействие со старыми версиями Go или чтобы все файлы, используемые для сборки, хранились вместе в одном дереве файлов, go mod vendor создает каталог с именем vendor в корневом каталоге основного модуля и сохраняет там все пакеты из зависимых модулей, необходимые для поддержки сборок и тестов пакетов в основном модуле.

Для сборки с использованием каталога поставщиков верхнего уровня основного модуля для удовлетворения зависимостей (отключение использования обычных сетевых источников и локальных кэшей) используйте 'go build -mod=vendor'. Обратите внимание, что используется только каталог поставщика верхнего уровня основного модуля; каталоги поставщиков в других местах по-прежнему игнорируются.


Читайте также:


Загрузка и проверка модуля в Golang

Команда go поддерживает в корневом каталоге основного модуля вместе с go.mod файл с именем go.sum, содержащий ожидаемые криптографические контрольные суммы содержимого определенных версий модуля. Каждый раз, когда используется зависимость, ее контрольная сумма добавляется в go.sum, если она отсутствует или требуется для соответствия существующей записи в go.sum.

Команда go поддерживает кэш загруженных пакетов, вычисляет и записывает криптографическую контрольную сумму каждого пакета во время загрузки. В обычной работе команда go проверяет эти предварительно вычисленные контрольные суммы в файле go.sum основного модуля, а не пересчитывает их при каждом вызове команды. Команда go mod verify проверяет, что кэшированные копии загружаемых модулей по-прежнему соответствуют их записанным контрольным суммам и записям в go.sum.

Команда go может извлекать модули из прокси-сервера вместо непосредственного подключения к системам управления версиями в соответствии с настройкой переменной среды GOPROXY.

Смотрите go help goproxy для получения подробной информации о прокси, а также о формате загруженных в кеширование пакетов.


Читайте также:


воскресенье, 7 июля 2019 г.

Совместимость модулей и семантическое управление версиями в Golang

Команда go требует, чтобы модули использовали семантические версии, и ожидает, что версии точно описывают совместимость: она предполагает, что v1.5.4 является обратно совместимой заменой для v1.5.3, v1.4.0 и даже v1.0.0. В общем, команда go ожидает, что пакеты следуют "правилу совместимости импорта" ("import compatibility rule"), которое гласит:

"Если старый пакет и новый пакет имеют одинаковый путь импорта, новый пакет должен быть обратно совместим со старым пакетом".

Поскольку команда go предполагает правило совместимости импорта, определение модуля может установить только минимальную требуемую версию одной из его зависимостей: оно не может установить максимум или исключить выбранные версии. Тем не менее, правило совместимости импорта не является гарантией: возможно, v1.5.4 содержит ошибки и не является обратно совместимой заменой для v1.5.3. Из-за этого команда go никогда не обновляет старую версию до более новой версии модуля без запроса.

В семантическом управлении версиями изменение основного номера версии указывает на отсутствие обратной совместимости с более ранними версиями. Для сохранения совместимости импорта команда go требует, чтобы модули с основной версией v2 или новее использовали путь к модулю с этой основной версией в качестве конечного элемента. Например, версия v2.0.0 для example.com/m должна вместо этого использовать путь к модулю example.com/m/v2, и пакеты в этом модуле будут использовать этот путь в качестве префикса пути импорта, как в example.com/m/v2/sub/pkg. Включение основного номера версии в путь модуля и пути импорта таким способом называется "семантическим контролем версий импорта". Псевдо-версии для модулей с основной версией v2 и более поздними начинаются с этой основной версии вместо v0, как в v2.0.0-20180326061214-4fc5987536ef.

В особом случае пути модулей, начинающиеся с gopkg.in/, продолжают использовать соглашения, установленные в этой системе: основная версия всегда присутствует, и перед ней стоит точка вместо косой черты: gopkg.in/yaml.v1 и gopkg.in/yaml.v2, а не gopkg.in/yaml и gopkg.in/yaml/v2.

Команда go рассматривает модули с различными путями модулей как не связанные: она не устанавливает связи между example.com/m и example.com/m/v2. Модули с разными основными версиями могут использоваться вместе в сборке и хранятся отдельно, поскольку их пакеты используют разные пути импорта.

В семантическом версионировании основная версия v0 предназначена для начальной разработки, что не указывает на ожидания стабильности или обратной совместимости. Основная версия v0 не отображается в пути к модулю, поскольку эти версии являются подготовкой к v1.0.0, а v1 также не отображается в пути к модулю.

Код, написанный до введения семантического соглашения об импорте версий, может использовать основные версии v2 и более поздние для описания того же набора неверсионных путей импорта, который использовался в v0 и v1. Чтобы приспособить такой код, если репозиторий исходного кода имеет тег v2.0.0 или новее для файлового дерева без go.mod, версия считается частью доступных версий модуля v1 и при преобразовании получает суффикс +incompatible до версии модуля, как в v2.0.0+incompatible. Тег +incompatible также применяется к псевдо-версиям, полученным из таких версий, как, например, в v2.0.1-0.yyyymmddhhmmss-abcdefabcdef+incompatible.

В общем, наличие зависимости в списке сборки (как сообщает 'go list -m all') от версии v0, предварительной версии, псевдо-версии или +incompatible версии указывает на то, что проблемы при обновлении более вероятны при обновлении этой зависимости, так как нет ожиданий совместимости для них.


Читайте также:


суббота, 6 июля 2019 г.

Запросы модулей (module query) в Golang

Команда go принимает "запрос модуля" ("module query") вместо версии модуля как в командной строке, так и в файле go.mod основного модуля. (После оценки запроса, найденного в файле go.mod основного модуля, команда go обновляет файл, чтобы заменить запрос его результатом.)

Полностью определенная семантическая версия, такая как "v1.2.3", оценивается как эта конкретная версия.

Префикс семантической версии, такой как "v1" или "v1.2", оценивается как последняя доступная тегированная (помеченная) версия с этим префиксом.

Семантическое сравнение версий, такое как "<v1.2.3" или ">=v1.5.6", оценивается как доступняя теговая версия, ближайшая к цели сравнения (последняя версия для < и <=, самая ранняя версия для > и >=).

Строка "latest" соответствует последней доступной версии с тегами или последней версии без тегов исходного репозитория.

Идентификатор ревизии для исходного репозитория, такой как префикс хеша коммита, тег ревизии или имя ветви, выбирает эту конкретную ревизию кода. Если ревизия также помечена семантической версией, запрос оценивается в эту семантическую версию. В противном случае запрос оценивается как псевдо-версия для коммита.

Все запросы предпочитают выбирать версии выпуска (релиза, release), чем пред-выпускные (пре-релизные, pre-release) версии. Например, "<v1.2.3" предпочтет вернуть "v1.2.2" вместо "v1.2.3-pre1", даже если "v1.2.3-pre1" ближе к цели сравнения.

Версии модуля, запрещенные инструкциями exclude в go.mod основного модуля, считаются недоступными и не могут быть возвращены запросами.

Например, все эти команды действительны:

go get github.com/gorilla/mux@latest    # @latest используется по умолчанию для 'go get'
go get github.com/gorilla/mux@v1.6.2    # записывает v1.6.2
go get github.com/gorilla/mux@e3702bed2 # записывает v1.6.2
go get github.com/gorilla/mux@c856192   # записывает v0.0.0-20180517173623-c85619274f5d
go get github.com/gorilla/mux@master    # записывает текущее значение ветки master


Читайте также: