处理版本范围和预发布版本

在开发包并使用版本范围来定义依赖关系时,可能会遇到依赖项的新版本发布了新的预发布版本,而我们希望在它正式发布之前对其进行测试,以便有机会提前验证新版本。

乍一看,可能会期望新版本会匹配我们的范围,如果它与范围相交的话。但是,如版本范围教程中所述,默认情况下,Conan 不会将预发布版本与未明确指定它的范围进行匹配。

Conan 提供了 global.conf 中的 core.version_ranges:resolve_prereleases 配置项,这是一个三态配置选项,用于控制版本范围是否应解析到预发布版本。

当未设置此项时,默认行为是遵循版本范围表达式,并且仅在版本范围明确允许预发布版本时才进行匹配,例如 [>=1 <2, include_prerelease]

如果未指定 include_prerelease 标志,则在此情况下会忽略预发布版本。

当设置为 False 时,即使版本范围表达式允许,也不会匹配预发布版本。

当设置为 True 时,它将全局启用版本范围内的预发布版本匹配,即使版本范围表达式没有明确允许它。这避免了修改和导出依赖图谱中各个包的 recipe,这对于大型依赖图谱来说是不可行的。

此配置项还有一个额外的好处,就是会影响整个依赖图谱。因此,如果我们的任何依赖项也定义了对我们感兴趣的库的需求,那么该新版本也将被它们拾取。

让我们看看实际情况。假设我们有以下(简化的)依赖图谱,其中我们依赖于 libpnglibmysqlclient,它们都通过 [>1.2 <2] 版本范围依赖于 zlib

digraph G { node [fillcolor="lightskyblue", style=filled, shape=box] "app" -> "libpng/1.6.40" "app" -> "libmysqlclient/8.1.0" "libpng/1.6.40" -> "zlib/1.2.13" [label="[>1.2 <2]"] "libmysqlclient/8.1.0" -> "zlib/1.2.13" [label="[>1.2 <2]"] }

如果现在发布了 zlib/1.3-pre,那么只需修改你的 global.conf 文件并添加行 core.version_ranges:resolve_prereleases=True(或者在你的命令调用中添加 CLI 参数 --core-conf core.version_ranges:resolve_prereleases=True),然后运行 conan create,输出将显示预期的 zlib 预发布版本正在被使用。

...

======== Computing dependency graph ========
Graph root
   cli
Requirements
   libmysqlclient/8.1.0#493d36bd9641e15993479706dea3c341 - Cache
   libpng/1.6.40#2ba025f1324ff820cf68c9e9c94b7772 - Cache
   lz4/1.9.4#b572cad582ca4d39c0fccb5185fbb691 - Cache
   openssl/3.1.2#f2eb8e67d3f5513e8a9b5e3b62d87ea1 - Cache
   zlib/1.3-pre#f2eb8e6ve24ff825bca32bea494b77dd - Cache
   zstd/1.5.5#54d99a44717a7ff82e9d37f9b6ff415c - Cache
Build requirements
   cmake/3.27.1#de7930d308bf5edde100f2b1624841d9 - Cache
Resolved version ranges
   cmake/[>=3.18 <4]: cmake/3.27.1
   openssl/[>=1.1 <4]: openssl/3.1.2
   zlib/[>1.2 <2]: zlib/1.3-pre
...

现在我们的包可以针对此新版本进行测试和验证,并且在测试结束后可以移除该配置,以恢复到正常的 Conan 行为。