Есть ли более простой способ обновлять локальные пакеты Go?
Я использую несколько пакетов, которые импортирую в разные проекты, начиная от пользовательских адаптеров для моей бизнес-логики, которые совместно используются облачными функциями lambda и google и другими общедоступными пакетами. Я делаю это прямо сейчас, когда продаю их и включаю в облачные функции. Для приложений, которые могут быть скомпилированы и развернуты на виртуальной машине, я собираю их отдельно. Это прекрасно работает для меня, однако, боль в разработке этих модулей.
Если я обновляю сигнатуру и имена методов в пакете, я должен отправить свои изменения в github / gitlab (мой путь к пакету похож на gitlab.com/groupName/projectName/pkg/packageName), а затем выполнить go get -u <pacakgeName>
обновить пакет.
Это также, на самом деле, не обновляет его, иногда я застрял со старой версией, не зная, как его обновить. Интересно, есть ли более простой способ работы с этим?
Для ясности:
Экспортированный пакет 1 Путь: gitlab.com/some/name/group/pkg/clients/psql
psql-client
|
|_ pkg
|
|_psql.go
Приложение 1 использует путь клиента psql: gitlab.com/some/name/app1
Приложение 2 использует путь клиента psql: gitlab.com/some/name/app2
2 ответа
Насколько я понимаю, (а) вы используете новую систему модулей Go, и (б) часть проблемы заключается в том, что вы не хотите продолжать вносить изменения в github или gitlab в разные репозитории, когда выполняете локальную разработку.
Другими словами, если у вас есть ваши изменения локально, это звучит так, как будто вы не хотите использовать эти изменения в github/gitlab для того, чтобы эти изменения были видны во всех связанных репозиториях, над которыми вы работаете локально.
Самый важный совет
Ваш рабочий процесс сильно усложняет наличие> 1 модуля в одном хранилище.
Как показано на вашем примере, в общем, почти всегда больше работы на постоянной основе, когда>> 1 модуль в одном репозитории. Это также очень трудно понять правильно. Для большинства людей стоимость почти всегда не стоит того. Кроме того, зачастую выгода не в том, чего ожидают люди, или в некоторых случаях нет практической выгоды иметь> 1 модуль в репо.
Я определенно рекомендую вам следовать общепринятому правилу "1 repo == 1 module", по крайней мере, на данный момент. Этот ответ содержит более подробную информацию о том, почему.
Работа с несколькими репо
Учитывая, что вы используете модули Go, одним из подходов является добавление replace
директива для модуля go.mod
файл, который сообщает модулю Go о расположении других модулей Go на диске.
Пример структуры
Например, если у вас было три репо repo1
, repo2
, repo3
Вы можете клонировать их так, чтобы они все сидели рядом на локальном диске:
myproject/
├── repo1
├── repo2
└── repo3
Тогда, если repo1
зависит от repo2
а также repo3
Вы могли бы установить go.mod
файл для repo1
знать относительное расположение на диске двух других модулей:
repo1 go.mod:
replace github.com/me/repo2 => ../repo2
replace github.com/me/repo3 => ../repo3
Когда вы находитесь внутри repo1
каталог или любой из его дочерних каталогов, go
команда как go build
или же go test ./....
будет использовать версии на диске repo2
а также repo3
,
repo2 go.mod:
Если repo2
зависит от repo3
Вы также можете установить:
replace github.com/me/repo3 => ../repo3
repo3 go.mod:
Если например repo3
не зависит ни от одного из repo1
или же repo2
тогда вам не нужно будет добавлять replace
к его go.mod
,
Дополнительные детали
replace
Директива более подробно описана в разделе " Часто задаваемые вопросы о замене" в вики.
Наконец, это зависит от вашего точного варианта использования, но распространенным решением на данный момент является использование gohack, который автоматизирует некоторые из этих процессов. В частности, он создает изменчивую копию зависимости (по умолчанию в $HOME/gohack
, но местоположение контролируется $GOHACK
переменная). gohack
также устанавливает ваш текущий go.mod
файл, имеющий директиву замены, указывающую на эту изменяемую копию.
go get
является транзитивным, так что вы можете просто добавить его в свой процесс сборки. Типичная сборка проекта Go в основном:
go get -u ./... && go test ./... && go build ./cmd/myapp
Который получает и обновляет зависимости, запускает все тесты проекта, а затем создает бинарный файл.