版本范围¶
在上一节中,我们得到了多个版本的 pkg
包。让我们删除它们并创建以下简单项目
from conan import ConanFile
class pkgRecipe(ConanFile):
name = "pkg"
from conan import ConanFile
class appRecipe(ConanFile):
name = "app"
requires = "pkg/1.0"
让我们创建 pkg/1.0
并安装 app
,以查看它需要 pkg/1.0
$ conan remove "pkg*" -c
$ conan create pkg --version=1.0
... pkg/1.0 ...
$ conan install app
...
Requirements
pkg/1.0
然后,如果我们创建了一个新版本的 pkg/1.1
,它将不会被 app
自动使用
$ conan create pkg --version=1.1
... pkg/1.0 ...
# Note how this still uses the previous 1.0 version
$ conan install app
...
Requirements
pkg/1.0
因此我们可以修改 app
的 conanfile 以显式使用新的 pkg/1.1
版本,但我们可以改为使用以下版本范围表达式(由 [expression]
括号引入)
from conan import ConanFile
class appRecipe(ConanFile):
name = "app"
requires = "pkg/[>=1.0 <2.0]"
现在,当我们安装 app
的依赖时,它将自动使用范围内的最新版本,即使我们创建了一个新版本,也无需修改 app
的 conanfile
# this will now use the newer 1.1
$ conan install app
...
Requirements
pkg/1.1
$ conan create pkg --version=1.2
... pkg/1.2 ...
# Now it will automatically use the newest 1.2
$ conan install app
...
Requirements
pkg/1.2
只要新版本在定义的范围内,此规则就有效。如果我们创建了 pkg/2.0
版本,app
将不会使用它
$ conan create pkg --version=2.0
... pkg/2.0 ...
# Conan will use the latest in the range
$ conan install app
...
Requirements
pkg/1.2
使用版本范围时,缓存中的版本优先于远程版本,因此,如果您有一个本地的 pkg/1.2
包,它将被使用而不是远程包,即使远程包更新。为了确保您使用最新的可用版本,您可以在 install
/create
命令中使用 --update
参数。请注意,--update
参数将检查命令中指定的所有远程仓库以查找可能的新版本,并且不会在找到第一个新版本时停止。
版本范围可以在多个位置定义
在
conanfile.py
配方中的requires
、tool_requires
、test_requires
、python_requires
在
conanfile.txt
文件中的[requires]
、[tool_requires]
、[test_requires]
部分在命令行参数中,例如
--requires=
和--tool_requires
。在配置文件
[tool_requires]
部分
语义版本控制¶
语义版本控制规范,或 semver,规定包应始终使用三个点分隔的数字进行版本控制,例如 MAJOR.MINOR.PATCH
,每个数字都有非常特定的含义。
Conan 将 semver 规范扩展到任意数量的数字,并且还允许在其中包含小写字母。这样做是因为在 1.X 期间收集了大量用户经验和反馈,并且显而易见,在 C++ 中,版本控制方案通常更复杂,用户要求更高的灵活性,允许像 1.2.3.a.8
这样的版本(如果需要)。
Conan 版本中的非数字标识符遵循与包名称相同的规则,它们只能包含小写字母。这是为了避免 1.2.3-Beta
与 1.2.3-beta
是不同的版本,这可能会带来问题,甚至是安全风险。
必要时(例如决定版本范围内的最新版本),版本的排序是通过从左到右,单独比较版本中每个点分隔的实体来完成的。数字将进行数值比较,因此 2 < 11,包含字母的条目将按字母顺序比较(即使它们也包含一些数字)。
与 semver 规范类似,Conan 可以管理 预发布版本 和 构建版本,形式为:VERSION-prerelease+build
。Conan 也会根据相同的规则对预发布版本和构建版本进行排序,并且它们中的每一个也可以包含任意数量的项,例如 1.2.3-pre.1.2.1+build.45.a
。请注意,semver 标准不对构建版本应用任何排序,但 Conan 会这样做,并使用与排序主版本和预发布版本相同的逻辑。
重要
请注意,预发布版本的排序有时可能令人困惑。预发布版本的时间比其所限定的发布版本要早。因此 1.1-alpha.1
比 1.1
更旧,而不是更新。
范围表达式¶
范围表达式可以包含用于下限和上限的比较运算符,以空格分隔。此外,也允许单独使用下限和上限,尽管在正常的版本控制方案中通常不建议这样做,特别是只使用下限。requires = "pkg/[>=1.0 <2.0]"
将包含像 1.0、1.2.3 和 1.9 这样的版本,但不会包含 0.3、2.0 或 2.1 版本。
波浪号 ~
运算符可用于定义“大约”相等的版本范围。requires = "pkg/[~1]"
将包含版本 1.3 和 1.8.1,但将排除像 0.8 或 2.0 这样的版本。同样,requires = "pkg/[~2.5]"
将包含 2.5.0 和 2.5.3,但排除 2.1、2.7、2.8。
插入符号 ^
运算符与波浪号非常相似,但允许在最后一个定义的数字上变化。requires ="pkg/[^1.2]"
将包含 1.2.1、1.3 和 1.51,但将排除 1.0、2、2.0。
也可以使用 OR 运算符应用多个条件,例如 requires = "pkg/[>1 <2.0 || ^3.2]"
,但这种复杂的表达式在实践中不建议使用,并且只应在非常极端的情况下使用。
可以使用字符串末尾的字符串匹配来简化某些范围,否则这些范围将需要更复杂的条件(此功能是实验性的)。定义 requires=pkg/[1.2.3.*]
将匹配任何以 1.2.3.
开头的版本,并丢弃其他版本。例如,它将匹配 1.2.3.5
和 1.2.3.abc
,但它将丢弃 1.2.3
(因为它没有最后一个点)。
最后,请注意,预发布版本默认不被解析。将它们包含在范围内的G 方法是使用 include_prerelease
选项 (requires = "pkg/[>1 <2, include_prerelease]"
),或通过 core.version_ranges:resolve_prereleases=True
配置显式启用它们。在此示例中,1.0-pre.1 和 1.5.1-pre1 将被包含,但 2.0-pre1 将被排除。
注意
虽然可以将 include_prerelease
硬编码到 requires
版本范围中,但通常不推荐这样做。预发布版本应该是选择加入的,并由用户控制,由用户决定是否使用预发布版本。此外,请注意,include_prereleases
不接受任何参数,因此无法使用 include_prerelease=False
停用预发布版本。
有关有效范围表达式的更多信息,请参阅 Requires 参考