6. 兼容性
兼容性是指,限制你的项目兼容依赖包的版本的能力。如果未给出依赖包的兼容性,则假定项目与该依赖包的所有版本兼容。
在 Project.toml
文件中输入依赖包的兼容性,例如:
[compat]
julia = "1.6"
Example = "0.5"
将兼容性条目放入项目文件后,up
命令可用于使它生效。
下面详细描述版本说明符的格式。
使用 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.x
和 0.x.y
)
虽然 semver 规范说所有主要版本为 0 的版本(1.0.0
之前的版本)彼此不兼容,但我们决定仅在主要和次要版本号都为零时应用它。换句话说,0.0.1
和 0.0.2
被认为是不兼容的。具有非零次要版本号(0.a.b
且 a != 0
)的 pre-1.0
版本,被认为与具有相同次要版本号,以及较小或相等补丁版本号(0.a.c
且 c <= b
)的版本兼容;即,版本 0.2.2
、0.2.3
与 0.2.1
、0.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
被其他两个包 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
,这会修复包错误。但是,您首先需要解决一个主要问题:可能在 D
的 v0.2
版本中存在和 B
不兼容的更改。在继续之前,您应该更新所有包,然后运行 B
的测试,扫描 pkg> test B
的输出以确保 D
的 v0.2
版本实际上正在使用 。(可能有一个 D
的额外的依赖关系将其固定到 v0.1
,并且您不希望被误导以为您已经在新版本上测试了 B
。)如果使用了新版本并且测试仍然通过,您可以假设B不需要任何特性更新以适应 D
的 v0.2
版本; 您可以安全地将此更改作为拉取请求提交到 B
以便发布新版本。相反,如果抛出错误,则表明 B
需要更广泛的更新以兼容 D
的最新版本。需要完成这些更新,才能同时使用 A
和 B
。但是,您可以继续彼此独立地使用它们。