Есть ли более простой способ обновлять локальные пакеты Go?

Я использую несколько пакетов, которые импортирую в разные проекты, от пользовательских адаптеров для моей бизнес-логики, которые используются функциями лямбда-выражения и облачных вычислений 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-client: gitlab.com/some/name/app1

Приложение 2 использует путь psql-client: gitlab.com/some/name/app2


person automaticAllDramatic    schedule 08.08.2019    source источник
comment
Какую ошибку вы получаете при выполнении команды go get -u? При использовании go get концепция версий отсутствует, так что же значит оставаться на более старой версии?   -  person Charlie    schedule 08.08.2019


Ответы (2)


Насколько я понимаю, (а) вы используете новую систему модулей Go, и что (б) часть проблемы заключается в том, что вы не хотите продолжать продвигать изменения в github или gitlab в разных репозиториях, когда вы выполняете локальную разработку.

Другими словами, если у вас есть локальные изменения, похоже, вы не хотите возвращать эти изменения через github / gitlab, чтобы эти изменения были видны в ваших связанных репозиториях, над которыми вы работаете локально.

Самый важный совет

Наличие> 1 модуля в одном репозитории значительно усложняет ваш рабочий процесс.

Как показано в вашем примере, в общем, почти всегда больше работы на постоянной основе иметь> 1 модуль в одном репозитории. Это также очень сложно сделать правильно. Для большинства людей цена почти всегда не окупается. Кроме того, часто выгода - это не то, что люди ожидают, или в некоторых случаях нет практической пользы от наличия> 1 модуля в репо.

Я определенно рекомендую вам следовать общепринятому правилу «1 репо == 1 модуль», по крайней мере, на данный момент. В этом ответе содержится более подробная информация о том, почему.

Работа с несколькими репозиториями

Если вы используете модули 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 более подробно описана в заменить FAQ в вики по модулям.

Наконец, это зависит от вашего конкретного варианта использования, но распространенным решением на данном этапе является использование gohack, что автоматизирует часть этого процесса. В частности, он создает изменяемую копию зависимости (по умолчанию в $HOME/gohack, но местоположение контролируется переменной $GOHACK). gohackтакже устанавливает для текущего go.mod файла заменить директиву, чтобы указать на эту изменяемую копию.

person typical182    schedule 08.08.2019
comment
Я уже использую replace и использую расположение на диске, однако мой файл go.mod выглядит так: `` replace github.com/me/parent-repo v0.0.0-20190808145620-8465703829e1 = ›../../ `` Думаю, вместо того, чтобы использовать замену для дочернего пакета, я использовал замену для родительского, что как-то имело для меня смысл тогда - person automaticAllDramatic; 08.08.2019
comment
Я отмечаю это как принятый ответ, потому что он в некотором роде отвечает на запрос. У меня все еще есть проблема, потому что у меня много внутренних зависимостей, которые, как мне кажется, мне нужно решить, лучше структурируя свой пакет. - person automaticAllDramatic; 08.08.2019
comment
Один вопрос: сколько у вас репозиториев и модулей? У вас есть один модуль на репозиторий или у вас есть репозитории с более чем одним файлом module / go.mod? - person typical182; 09.08.2019
comment
Я спрашиваю, сколько модулей у вас в одном репо, потому что иногда люди помещают ›1 модуль в репо, и это обычно сильно усложняет рабочие процессы. Практически всегда проще следовать общему правилу: 1 репо == 1 модуль. - person typical182; 09.08.2019
comment
да, у меня есть родительский модуль, который определяет мои типы и два дочерних модуля в них (если я могу их так назвать), тогда есть другие репозитории, которые импортируют типы и модули из этого репозитория - person automaticAllDramatic; 09.08.2019
comment
Постоянно иметь ›1 модуль в одном репозитории - это почти всегда больше работы. Это также очень сложно сделать правильно. Для большинства людей цена почти всегда не окупается. Кроме того, часто выгода не соответствует ожиданиям людей, а в некоторых случаях наличие 1 модуля в репо не приносит никакой практической пользы. Я определенно рекомендую вам следовать общепринятому правилу 1 репо == 1 модуль, по крайней мере, на данный момент. В этом ответе содержится более подробная информация о том, почему. - person typical182; 09.08.2019

go get является транзитивным, поэтому вы можете просто добавить его в процесс сборки. Типичная сборка проекта Go в основном:

go get -u ./... && go test ./... && go build ./cmd/myapp

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

person Adrian    schedule 08.08.2019