6. 兼容性

兼容性是指,限制你的项目兼容依赖包的版本的能力。如果未给出依赖包的兼容性,则假定项目与该依赖包的所有版本兼容。

Project.toml 文件中输入依赖包的兼容性,例如:

[compat]
julia = "1.6"
Example = "0.5"

将兼容性条目放入项目文件后,up 命令可用于使它生效。

下面详细描述版本说明符的格式。

Info

使用 compat 命令编辑 Pkg REPL 中的兼容条目,或手动编辑项目文件。

版本说明符格式

与其他包管理器类似,Julia 包管理器尊重语义版本控制(semver)。作为示例,假定版本说明符 1.2.3 与版本 [1.2.3 - 2.0.0)) 指非闭合上界)是兼容的。更确切地说,版本说明符要么是插入(caret)说明符,例如 ^1.2.3, 要么是波浪(tilde)说明符,例如 ~1.2.3。插入说明符是默认值,因此 1.2.3 == ^1.2.3。插入符号和波浪号之间的区别将在下一节中描述。多个版本说明符的并集可以通过逗号分隔各个版本说明符来组成,例如

[compat]
Example = "1.2, 3"

将得到 [1.2.0, 3.0.0)。请注意,前导零的处理方式不同,例如 Example = "0.2, 1" 只会得到 [0.2.0 - 0.3.0) ∪ [1.0.0 - 2.0.0)。有关带前导零的版本号的更多信息,请参阅下一节。

带前导零版本号的行为(0.0.x0.x.y)

虽然 semver 规范说所有主要版本为 0 的版本(1.0.0 之前的版本)彼此不兼容,但我们决定仅在主要和次要版本号都为零时应用它。换句话说,0.0.10.0.2 被认为是不兼容的。具有非零次要版本号(0.a.ba != 0)的 pre-1.0 版本,被认为与具有相同次要版本号,以及较小或相等补丁版本号(0.a.cc <= b)的版本兼容;即,版本 0.2.20.2.30.2.10.2.0 兼容。主要版本号为 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)

特别是,当一个包与 0.2.3 相比具有附加功能时,它可能设置 version = "0.2.4",只要它保持与 0.2.0 的向后兼容。另请参见version 字段

插入说明符

插入符号 (^) 说明符允许根据 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)

对于主要版本号为 0 的所有版本,波浪说明符和插入说明符是等效的。

相等说明符

相等说明符可用于指定具体的版本:

[compat]
PkgA = "=1.2.3"           # [1.2.3, 1.2.3]
PkgA = "=0.10.1, =0.10.3" # 0.10.1 or 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)

修复冲突

版本冲突之前是通过 example 介绍的,该冲突是由包 D 被其他两个包 BC 使用产生的冲突。我们对错误消息的分析显示 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,这会修复包错误。但是,您首先需要解决一个主要问题:可能在 Dv0.2 版本中存在和 B 不兼容的更改。在继续之前,您应该更新所有包,然后运行 B​​ 的测试,扫描 pkg> test B 的输出以确保 Dv0.2 版本实际上正在使用 。(可能有一个 D 的额外的依赖关系将其固定到 v0.1,并且您不希望被误导以为您已经在新版本上测试了 B。)如果使用了新版本并且测试仍然通过,您可以假设B不需要任何特性更新以适应 Dv0.2 版本; 您可以安全地将此更改作为拉取请求提交到 B 以便发布新版本。相反,如果抛出错误,则表明 B 需要更广泛的更新以兼容 D 的最新版本。需要完成这些更新,才能同时使用 AB。但是,您可以继续彼此独立地使用它们。