воскресенье, 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 версии указывает на то, что проблемы при обновлении более вероятны при обновлении этой зависимости, так как нет ожиданий совместимости для них.


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


Комментариев нет:

Отправить комментарий