Использование "go get" для загрузки бинарных файлов без добавления их в go.mod
Я использую модули Go в своем проекте и в своей системе сборки (например, Travis CI). Я загружаю утилиту командной строки (написанную на Go) с go get
чтобы помочь с моим процессом сборки, например:
go get github.com/mitchellh/gox
Тем не менее, это go get
вызывает добавление файла в мой go.mod
файл. Это загрязняет среду сборки, делая ее "грязной" (так как в некоторых файлах, отслеживаемых в git, есть изменения, в данном случае go.mod и go.sum), и я использую git describe --always --dirty --tag
описать мою сборку, которая выглядит как "грязная".
Есть ли способ "пойти получить" бинарный файл просто загрузить его, не добавляя его в go.mod/go.sum?
Я пытался установить GOPATH в другом месте, даже тогда, go get
обновляет go.mod / go.sum, чтобы добавить это как // indirect
зависимость.
dir="$(mktemp -d)"; \
env GOPATH="$dir" go get github.com/mitchellh/gox && \
mv "$dir/bin/gox" "$(go env GOPATH)"/bin/gox
3 ответа
Надеемся, что в Go 1.14 появится новый флаг для go get
это именно то, что вы просите. Это отслеживается в выпуске № 30515 "cmd / go: предложить согласованную команду глобальной установки".
До этого у вас есть несколько разных вариантов.
Перейти 1.12 и 1.13: изменить каталог
Если вы используете Go 1.12 или более позднюю версию, простейшее решение, вероятно, состоит в том, чтобы переместиться за пределы вашего текущего модуля в каталог без go.mod
до выполнения go get
, такие как:
$ cd /tmp
$ go get github.com/foo/bar@v1.2.3
$ cd - # return to prior directory
Go 1.11, 1.12, 1.13+: гобин
gobin - это модульная команда для установки или запуска двоичных файлов, которая обеспечивает дополнительную гибкость, включая возможность установки без изменения текущего модуля. go.mod
, Увидеть gobin
README и FAQ для более подробной информации.
Go 1.11: временный модуль
Если вы используете Go 1.11 с модулями, первым шагом, вероятно, является обновление до Go 1.12 или 1.13, если в модулях есть много улучшений. Если вам необходимо использовать Go 1.11 и вы хотите использовать @version
синтаксис без обновления вашего текущего модуля go.mod
Тогда один из подходов заключается в создании временного модуля:
cd $(mktemp -d) && go mod init tempmod && go get github.com/foo/bar@v1.2.3
Это потому, что в Go 1.11 вы не можете использовать @version
синтаксис, если вы не в модуле, который был ослаблен в Go 1.12. Этот подход был автоматизирован с помощью простого сценария оболочки @rogpeppe.
дополнительные детали
В общем, go
Команда в модуле-модуле всегда определяет, в каком модуле он находится, в зависимости от текущего рабочего каталога, когда вы вызываете go
команда. (Вы могли бы сделать аналогию с тем, как make
без каких-либо аргументов будет искать make-файл в текущем рабочем каталоге, или как исторически go build
без всяких аргументов создаст текущий рабочий каталог и т. д.).
С модулями, go get
ищет go.mod
файл в текущем рабочем каталоге или любом из его родителей, и go get
будет использовать ограничения, перечисленные в любом go.mod
как часть решения для версий, а также обновления go.mod
если необходимо, основываясь на выполнении go get
, Вот почему ваш go.mod
файл обновляется, если вы запустите go get
из существующего модуля.
С другой стороны, начиная с Go 1.12, если вы находитесь в каталоге, который не является частью какого-либо модуля (то есть каталог не имеет go.mod
Мало кто из ее родителей), то нет go.mod
обновить, но go
Команда все еще может работать в режиме модуля и использовать @version
синтаксис.
Из примечаний к выпуску Go 1.12:
Когда для GO111MODULE установлено значение on, команда go теперь поддерживает операции с поддержкой модулей вне каталога модуля, при условии, что этим операциям не нужно разрешать пути импорта относительно текущего каталога или явно редактировать файл go.mod. Такие команды, как go get, go list и go mod, ведут себя как в модуле с изначально пустыми требованиями. В этом режиме go env GOMOD сообщает о нулевом устройстве системы (/dev/null или NUL).
Go 1.16 и далее
Go 1.16 (выпущен в феврале 2021 г.) включает изменение, которое позволяет устанавливать двоичный файл, не затрагивая.
В выпуске 40276 отслеживается предложение:
cmd / go: 'go install' должен устанавливать исполняемые файлы в модульном режиме вне модуля
Это было реализовано в CL 254365 . В рамках этого изменения вы можете запустить, например:
go install golang.org/x/tools/cmd/goimports@latest
установить двоичный файл, не затрагивая
go.mod
.
Чтобы установить определенную версию, замените
@latest
с например
@v0.1.5
.
В go help build
:
Флаг сборки -mod обеспечивает дополнительный контроль над обновлением и использованием go.mod.
Если вызывается с -mod=readonly, команда go не допускается из неявного автоматического обновления go.mod