Есть ли более простой способ обновлять локальные пакеты 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

Который получает и обновляет зависимости, запускает все тесты проекта, а затем создает бинарный файл.

Другие вопросы по тегам