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
. Однако вы можете продолжать использовать их независимо друг от друга.