6. Совместимость
Совместимость — это возможность ограничить версии зависимостей, с которыми совместим ваш проект. Если совместимость для зависимости не указана, предполагается, что проект совместим со всеми версиями этой зависимости.
Совместимость для зависимости указывается в файле Project.toml, например так:
[compat]
julia = "1.6"
Example = "0.5"
После того как запись о совместимости помещена в файл проекта, ее можно применять с помощью up.
Формат спецификатора версии подробно описан ниже.
|
Используйте команду |
|
Приведенные ниже правила относятся к файлу |
|
Обратите внимание, что для регистрации в общем реестре Julia требуется, чтобы каждая зависимость имела запись |
Формат спецификатора версий
Как и другие диспетчеры пакетов, диспетчер пакетов Julia соблюдает семантическое управление версиями (semver), с исключением для начальных нулей. Например, спецификатор версии, заданный как 1.2.3, считается совместимым с версиями [1.2.3 - 2.0.0), где ) — неинклюзивная верхняя граница. Более конкретно, спецификатор версии задается либо как спецификатор «курсор», например ^1.2.3, либо как спецификатор «тильда», например ~1.2.3. Спецификаторы «курсор» используются по умолчанию, поэтому 1.2.3 == ^1.2.3. Разница между курсором и тильдой описывается в следующем разделе. Объединение нескольких спецификаторов версий формируется путем разделения запятыми отдельных спецификаторов версий, например
[compat]
Example = "1.2, 2"
приведет к [1.2.0, 3.0.0). Обратите внимание, что начальные нули обрабатываются по-разному, например Example = "0.2, 1" приведет только к [0.2.0 - 0.3.0) ∪ [1.0.0 - 2.0.0). Дополнительные сведения о версиях с начальными нулями см. в следующем разделе.
Поведение версий с начальными нулями (0.0.x и 0.x.y)
Хотя согласно спецификации semver все версии с номером основной версии, равным 0 (версии до 1.0.0), несовместимы друг с другом, мы решили применять этот факт только в тех случаях, когда номера и основной, и дополнительной версий равны нулю. Другими словами, 0.0.1 и 0.0.2 считаются несовместимыми. Версия, предшествующая 1.0, с ненулевым номером дополнительной версии (0.a.b с a != 0) считается совместимой с версиями с тем же номером дополнительной версии и меньшими или равными номерами версий исправления (0.a.c с c <= b); то есть версии 0.2.2 и 0.2.3 совместимы с 0.2.1 и 0.2.0. Версии с нулевым номером основной версии и разными номерами дополнительных версий не считаются совместимыми, поэтому в версии 0.3.0 могут быть изменения, отличные от 0.2.0. В связи с этим запись [compat]:
[compat]
Example = "0.0.1"
приводит к привязке версии Example как [0.0.1, 0.0.2) (что эквивалентно только версии 0.0.1), тогда как запись [compat]:
[compat]
Example = "0.2.1"
приводит к привязке версии Example как [0.2.1, 0.3.0).
В частности, пакет может задать version = "0.2.4", если в нем есть добавления функций по сравнению с 0.2.3, при условии, что он остается обратно совместимым с 0.2.0. См. также The version field.
Спецификаторы «курсор»
Спецификатор «курсор» (^) позволяет выполнять обновление, которое будет совместимым согласно semver. Это поведение по умолчанию, если спецификаторы не используются. Обновленная зависимость считается совместимой, если новая версия не изменяет самую левую ненулевую цифру в спецификаторе версии.
Ниже приведен ряд примеров.
[compat]
PkgA = "^1.2.3" # [1.2.3, 2.0.0)
PkgB = "^1.2" # [1.2.0, 2.0.0)
PkgC = "^1" # [1.0.0, 2.0.0)
PkgD = "^0.2.3" # [0.2.3, 0.3.0)
PkgE = "^0.0.3" # [0.0.3, 0.0.4)
PkgF = "^0.0" # [0.0.0, 0.1.0)
PkgG = "^0" # [0.0.0, 1.0.0)
Спецификаторы «тильда»
Спецификатор «тильда» предоставляет более ограниченные возможности обновления. При указании основной, дополнительной версий и версии исправления или при указании основной и дополнительной версий допускается изменение только версии исправления. При указании только основной версии разрешается обновлять как дополнительную версию, так и версию исправления (~1, таким образом, эквивалентна ^1). Например:
[compat]
PkgA = "~1.2.3" # [1.2.3, 1.3.0)
PkgB = "~1.2" # [1.2.0, 1.3.0)
PkgC = "~1" # [1.0.0, 2.0.0)
PkgD = "~0.2.3" # [0.2.3, 0.3.0)
PkgE = "~0.0.3" # [0.0.3, 0.0.4)
PkgF = "~0.0" # [0.0.0, 0.1.0)
PkgG = "~0" # [0.0.0, 1.0.0)
Для всех версий с нулевым номером основной версией спецификаторы «тильда» и «курсор» эквивалентны.
Спецификатор «равенство»
Можно использовать, чтобы указать точные версии:
[compat]
PkgA = "=1.2.3" # [1.2.3, 1.2.3)
PkgA = "=0.10.1, =0.10.3" # 0.10.1 или 0.10.3
Спецификатор «неравенство»
Можно использовать, чтобы задать диапазоны версий:
[compat]
PkgB = ">= 1.2.3" # [1.2.3, ∞)
PkgC = "≥ 1.2.3" # [1.2.3, ∞)
PkgD = "< 1.2.3" # [0.0.0, 1.2.3) = [0.0.0, 1.2.2]
Спецификаторы «дефис»
Синтаксис с дефисом можно использовать, чтобы задать диапазоны версий: Убедитесь, что по обе стороны от дефиса есть пробелы.
[compat]
PkgA = "1.2.3 - 4.5.6" # [1.2.3, 4.5.6]
PkgA = "0.2.3 - 4.5.6" # [0.2.3, 4.5.6]
Любые неуказанные конечные числа в первой конечной точке считаются нулями:
[compat]
PkgA = "1.2 - 4.5.6" # [1.2.0, 4.5.6)
PkgA = "1 - 4.5.6" # [1.0.0, 4.5.6)
PkgA = "0.2 - 4.5.6" # [0.2.0, 4.5.6)
PkgA = "0.2 - 0.5.6" # [0.2.0, 0.5.6)
Любые неуказанные конечные числа во второй конечной точке считаются подстановочными знаками:
[compat]
PkgA = "1.2.3 - 4.5" # 1.2.3 - 4.5.* = [1.2.3, 4.6.0)
PkgA = "1.2.3 - 4" # 1.2.3 - 4.*.* = [1.2.3, 5.0.0)
PkgA = "1.2 - 4.5" # 1.2.0 - 4.5.* = [1.2.0, 4.6.0)
PkgA = "1.2 - 4" # 1.2.0 - 4.*.* = [1.2.0, 5.0.0)
PkgA = "1 - 4.5" # 1.0.0 - 4.5.* = [1.0.0, 4.6.0)
PkgA = "1 - 4" # 1.0.0 - 4.*.* = [1.0.0, 5.0.0)
PkgA = "0.2.3 - 4.5" # 0.2.3 - 4.5.* = [0.2.3, 4.6.0)
PkgA = "0.2.3 - 4" # 0.2.3 - 4.*.* = [0.2.3, 5.0.0)
PkgA = "0.2 - 4.5" # 0.2.0 - 4.5.* = [0.2.0, 4.6.0)
PkgA = "0.2 - 4" # 0.2.0 - 4.*.* = [0.2.0, 5.0.0)
PkgA = "0.2 - 0.5" # 0.2.0 - 0.5.* = [0.2.0, 0.6.0)
PkgA = "0.2 - 0" # 0.2.0 - 0.*.* = [0.2.0, 1.0.0)
Устранение конфликтов
Конфликты версий были представлены ранее на примере конфликта, возникшего в пакете D, используемом двумя другими пакетами, B и C. Анализ сообщения об ошибке показал, что пакет B использует устаревшую версию пакета D. Чтобы исправить ситуацию, сначала попробуйте pkg> dev B, чтобы изменить пакет B и его требования к совместимости. Если вы откроете его файл Project.toml в редакторе, вы, вероятно, заметите что-то вроде следующего:
[compat]
D = "0.1"
Обычно первым шагом является изменение этого параметра на что-то вроде следующего:
[compat]
D = "0.1, 0.2"
Это указывает на то, что пакет B совместим как с версией 0.1, так и с версией 0.2. При выполнении pkg> up ошибка пакета будет исправлена. Однако есть одна серьезная проблема, которую нужно решить в первую очередь: возможно, в версии v0.2 было внесено несовместимое изменение пакета D, которое приводит к сбою пакета B. Прежде чем продолжить, следует обновить все пакеты, а затем запустить тесты для пакета B, проверив вывод pkg> test B, чтобы убедиться, что версия v0.2 пакета D действительно используется. (Возможно, что дополнительная зависимость пакета D закрепляет его к версии v0.1, и вы не хотите заблуждаться, думая, что протестировали пакет B в более новой версии.) Если использовалась новая версия и тесты по-прежнему проходят, можно считать, что пакет B не нуждается в дальнейших обновлениях, чтобы принять v0.2 для D. Вы можете смело отправить это изменение в качестве запроса на вытягивание для B, чтобы вышел новый выпуск. Если же возникает ошибка, это указывает на то, что пакет B требует более всестороннего обновления для совместимости с последней версией пакета D. Эти обновления должны быть завершены, прежде чем станет возможным одновременное использование пакетов A и B. Однако вы можете продолжать использовать их независимо друг от друга.