跳到主要内容

版本控制参考

版本控制允许你在清单文件中确定性地控制项目所使用依赖项的精确修订版本。该功能仅对 清单模式 用户可用。

有关 kmpkg 版本控制算法和高层概念的更多信息,请参阅 版本控制概念

有关带上下文的示例,请参阅我们的 版本控制入门指南

版本方案

kmpkg 中的端口应尽量遵循包作者使用的版本控制约定。因此,声明包版本时应使用相应的版本方案。

每种版本方案都定义了自身的有效版本字符串规则,更重要的是,定义了同一方案下版本的排序规则。

kmpkg 支持的版本方案如下:

清单属性版本控制方案
version适用于点分隔的数字版本
version-semver适用于符合 SemVer 规范的版本
version-date适用于 YYYY-MM-DD 格式的日期版本
version-string适用于任意字符串版本

一个清单中只能包含一个版本声明。

信息

设计上,kmpkg 不比较使用不同方案的版本。例如,使用 version-string: 7.1.3 的包无法与使用 version: 7.1.4 的同一包进行比较,即使转换逻辑看似明显。

version

接受遵循宽松的、点分隔的、类 SemVer 方案的版本字符串。

版本在逻辑上由点分隔(.)的数字段组成,每个段必须是无前导零的正整数。

该版本方案的正则表达式模式为:(0|[1-9]\d*)(\.(0|[1-9]\d*))*

排序规则:比较两个版本时,从左到右逐段比较数字值,直到找到第一个不同的段。在前面所有段均相等的情况下,段数较少的版本优先级高于段数较多的版本。

示例:

0 < 0.1 < 0.1.0 < 1 < 1.0.0 < 1.0.1 < 1.1 < 2.0.0

version-semver

接受遵循 语义化版本规范 中描述的语义化版本约定的版本字符串。

排序规则:按照语义化版本规范中描述的规则排序字符串。

示例:

1.0.0-1 < 1.0.0-alpha < 1.0.0-beta < 1.0.0 < 1.0.1 < 1.1.0

version-date

接受可解析为 ISO-8601 格式 YYYY-MM-DD 日期的版本字符串。允许以点分隔的、无前导零的正整数作为歧义消除标识符。

该方案推荐用于没有固定发布版本的“基于 HEAD 实时构建”(Live at HEAD)库。

该版本方案的正则表达式模式为:\d{4}-\d{2}-\d{2}(\.(0|[1-9]\d*))*

排序规则:首先按日期部分排序,然后按歧义消除标识符的数字值排序。歧义消除标识符遵循宽松版本方案(version)的规则。

示例: 2021-01-01 < 2021-01-01.1 < 2021-02-01.1.2 < 2021-02-01.1.3 < 2021-02-01

version-string

适用于版本字符串不满足其他任何方案的包,接受大多数任意字符串。用于表示端口版本的 # 符号不允许使用。

排序规则:不对版本字符串本身进行排序。但如果字符串完全匹配,则可以比较并排序其端口版本。

示例:

  • appleorangeorange.2orange2 无法比较(<> 表示不可比)
  • watermelon#0 < watermelon#1

port-version

端口版本用于跟踪打包文件(kmpkg.jsonportfile.cmake 等)的变更,而不改变上游库的版本。

端口版本是一个非负整数。

端口版本的规则如下:

  • 端口原始版本的端口版本从 0 开始;
  • 每次对端口进行 kmpkg 特定的变更(未提升包版本)时,端口版本增加 1;
  • 每次更新包版本时,端口版本重置为 0。
信息

kmpkg 采用文本格式 <版本>#<端口版本> 表示完整版本。例如 1.2.0#2 表示版本 1.2.0、端口版本 2。如果端口版本为 0,则省略 #0 后缀(例如 1.2.0 隐含版本 1.2.0、端口版本 0)。

排序规则:如果两个版本的核心版本部分相等,则比较其端口版本的数字值,端口版本较低的优先级更高。

示例:

  • 1.2.0 < 1.2.0#1 < 1.2.0#2 < 1.2.0#10
  • 2021-01-01#20 < 2021-01-01.1
  • windows#7 < windows#8

版本约束

基线(Baselines)

基线定义了所考虑版本的全局最低标准(除非在其他地方指定,否则将使用与该基线关联的版本)。这使得顶层清单能够保持整个依赖项图的更新,而无需为每个直接依赖项单独指定 "version>=" 约束。

每个已配置的注册表都有一个关联的基线。对于未配置任何注册表的清单,"builtin-baseline" 字段定义了内置注册表的基线。如果清单未配置任何注册表且没有 "builtin-baseline",则安装操作将按照经典模式算法执行,并忽略所有版本控制信息。

与其他注册表设置一样,作为依赖项使用的端口会忽略基线。如果传递版本解析过程中需要最低版本,端口应使用 "version>="

示例

{
"name": "project",
"version": "1.0.0",
"dependencies": ["zlib", "fmt"],
"builtin-baseline": "9fd3bd594f41afb8747e20f6ac9619f26f333cbe"
}

要添加初始的 "builtin-baseline",请使用 kmpkg x-update-baseline --add-initial-baseline。要更新清单中的基线,请使用 kmpkg x-update-baseline

version>=

表示最小版本要求,version>= 声明为满足依赖项的版本设置了下限。

信息

kmpkg 会选择满足所有约束的最低版本,因此不需要小于约束(less-than constraint)。

示例:

{
"name": "project",
"version-semver": "1.0.0",
"dependencies": [
{ "name": "zlib", "version>=": "1.2.11#9" },
{ "name": "fmt", "version>=": "7.1.3#1" }
],
"builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}

作为版本约束声明的一部分,可以通过添加后缀 #<端口版本> 指定端口版本。在上面的示例中,1.2.11#9 表示版本 1.2.11、端口版本 9

overrides

声明覆盖(override)会强制 kmpkg 忽略所有其他版本约束,使用覆盖中指定的版本。这对于固定精确版本和解决版本冲突非常有用。

覆盖以包版本声明数组的形式声明。

要使覆盖生效,被覆盖的包必须是依赖项图的一部分。也就是说,该依赖项必须由顶层清单声明,或者是传递依赖项的一部分。

一个给定的包名称只能声明一个覆盖。

{
"name": "project",
"version-semver": "1.0.0",
"dependencies": [
"curl",
{ "name": "zlib", "version>=": "1.2.11#9" },
"fmt"
],
"builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc",
"overrides": [
{ "name": "fmt", "version": "6.0.0" },
{ "name": "openssl", "version": "1.1.1h#3" }
]
}