注册表概念
概述
kmpkg 在 https://github.com/kumose/kmpkg 上托管了一系列打包为 端口(ports) 的库,这个端口集合被称为精选注册表(curated registry)。但 kmpkg 并不局限于该精选注册表,用户可通过创建自定义注册表来扩展端口选择范围。
注册表是按特定结构组织的端口和辅助文件集合。遵循该注册表结构后,注册表中的端口可享受与精选注册表端口相同的功能,包括 版本控制、二进制缓存 等。
目前支持三种类型的注册表:
通过 kmpkg-configuration.json 文件,可指示 kmpkg 识别自定义注册表中的端口。有关如何在项目中使用自定义注册表的教程,请参阅教程:从基于 Git 的注册表安装依赖项。
注册表结构
kmpkg 要与注册表交互,注册表必须遵循以下结构:
- 名为
ports的目录包含所有端口,每个子目录对应一个特定端口,子目录名称与端口名称一致。例如,端口foo的文件位于ports/foo。 - 名为
versions的目录包含构成版本数据库的文件。
示例:注册表结构
ports/
foo/
portfile.cmake
kmpkg.json
versions/
f-/
foo.json
baseline.json
版本数据库
所有注册表的根目录下均包含 versions 目录,该目录即为版本数据库(versions database)。
版本数据库包含两个组成部分:
- 基线文件(baseline file)
- 版本文件(versions files)
基线文件是名为 baseline.json 的 JSON 文件,位于 versions 目录的根目录。
版本文件是与可用端口名称相同的 JSON 文件,必须存储在 versions/<prefix>/<port name>.json 路径下,其中 <prefix> 为端口名称的首字母加连字符。例如,端口 foo 的版本文件路径为 versions/f-/foo.json。
版本文件的作用有两点:
- 列出每个端口的所有可用版本
- 指向每个版本的获取位置
版本文件的格式因注册表类型而异。
基线文件
无论哪种类型的注册表,均需在 versions/baseline.json 路径下包含 baseline.json 文件。
基线文件的作用是描述注册表中所有端口的“最新版本集”。每次向注册表添加端口的新版本时,都应更新该文件。
该文件是一个 JSON 文件,包含一个顶层对象,其属性为“命名基线对象”。每个命名基线对象的属性为端口名称,属性值为版本条目。注册表参考文档 详细描述了基线文件的结构。
每个基线版本条目是一个包含以下属性的对象:
baseline:值为该端口在对应的kmpkg.json文件中声明的版本。port-version:值为该端口在对应的kmpkg.json文件中声明的port-version。
示例基线文件
{
"default": {
"foo": { "baseline": "1.0.0", "port-version": 0 },
"bar": { "baseline": "2024-08-01", "port-version": 1 },
"baz": { "baseline": "vista-xp", "port-version": 0 }
}
}
有关详细信息,请参阅参考文档:
版本文件
注册表中的每个端口都有对应的版本文件。版本文件存储在 versions/<prefix>/<port name>.json 路径下,其中 <prefix> 为端口名称的首字母加连字符。例如,端口 foo 的版本文件路径为 versions/f-/foo.json。
版本文件的作用有两点:
- 列出每个端口的所有可用版本
- 指向每个版本的获取位置
版本文件的结构为:顶层对象包含一个 "versions" 数组,数组中的每个条目为一个版本对象。版本对象必须包含以下属性:
- 版本属性:属性名和属性值必须与端口在其
kmpkg.json文件中使用的一致。属性名必须是version、version-semver、version-date或version-string中的一个;属性值为端口清单文件(kmpkg.json)中声明的版本。 port-version:值为端口在其kmpkg.json文件中声明的port-version。git-tree:(仅 Git 注册表)值为对应端口目录的 Git 树哈希值(git-tree SHA)。该哈希值通过对端口目录内容进行哈希计算得到;Git 可通过该 git-tree SHA 检索对应版本的端口内容。这使得 kmpkg 能够从注册表的 Git 历史中获取端口的旧版本。有关如何为任意端口版本获取该值,请参阅 Git 注册表 部分。path:(仅文件系统注册表)值为包含该特定版本端口文件的目录的完整路径。
示例:文件系统注册表的版本文件
{
"versions": [
{
"path": "$/ports/foo/1.2.0",
"version": "1.2.0",
"port-version": 0
},
{
"path": "$/ports/foo/1.1.0",
"version": "1.1.0",
"port-version": 0
},
{
"path": "$/ports/foo/1.0.0",
"version": "1.0.0",
"port-version": 0
}
]
}
有关详细信息,请参阅参考文档:
内置注册表
内置注册表是一种特殊类型的注册表,是 经典模式 下的默认注册表。在 清单模式 下,若未指定 默认注册表,kmpkg 会隐式使用内置注册表。
内置注册表指的是当你通过 git clone 从 https://github.com/kumose/kmpkg 克隆 kmpkg 仓库后,在本地生成的精选注册表副本。部分操作要求 KMPKG_ROOT 环境变量 指向内置注册表。
若通过“单行命令”或 Visual Studio 安装程序获取 kmpkg,则内置注册表将等效于一个指向 https://github.com/kumose/kmpkg 仓库的 Git 注册表。
Git 注册表
Git 注册表是遵循注册表结构的 Git 仓库,利用 Git 的功能为注册表中的端口提供版本控制。https://github.com/kumose/kmpkg 上的精选注册表就是 Git 注册表的一个实现。
Git 注册表可托管在任何 Git 仓库提供商上,允许你使用所选的 Git 托管服务控制对自定义注册表的访问,同时便于共享注册表。
Git 注册表是实现自定义注册表的推荐方式。由于其版本控制机制与精选注册表相同,Git 注册表可使用 x-add-version 命令管理版本数据库文件。
有关 Git 注册表的实现细节,请参阅 注册表参考文档。
向 Git 注册表添加新版本
可使用 x-add-version 命令向注册表添加新端口或新版本。使用该命令添加版本时,需注意以下几点:
添加新版本时,请务必将端口声明的版本更新为尚未发布的版本,避免重写版本历史。
修改端口时,第一步应在 kmpkg.json 文件中更新其版本:
- 若修改包含更新包的 上游版本,请将
port-version设为0; - 否则,请将
port-version加 1。
示例:向 Git 注册表添加新端口版本
git add ports/foo/.
kmpkg x-add-version --x-builtin-ports-root=./ports --x-builtin-registry-versions-dir=./versions foo
added version 1.0.0#1 to path/to/registry/versions/f-/foo.json
added version 1.0.0#1 to path/to/registry/versions/baseline.json
重定向选项 --x-builtin-ports-root 和 --x-builtin-registry-versions-dir 应分别指向注册表的 ports 目录和 versions 目录。
x-add-version 命令执行成功后,添加并提交更改:
git add ./versions
git commit -m "Update foo to new version"
文件系统注册表
文件系统注册表是存储在文件系统中的注册表实现,遵循通用注册表结构,但不依赖 Git 提供版本控制功能。相反,它通过为每个端口版本分配不同的路径来实现简单的版本控制。
这种类型的注册表适合作为端口的测试环境,或为非 Git 版本控制系统中的注册表提供替代方案。不建议将文件系统注册表用于大量端口集合,且 kmpkg 未提供用于操作此类注册表版本数据库文件的工具。
有关如何实现文件系统注册表的详细信息,请参阅 注册表参考文档。
使用注册表
要在项目中使用自定义注册表,需在项目的 清单文件(kmpkg.json) 旁创建一个配置文件(kmpkg-configuration.json)。
默认注册表
在 解析端口名称 时,若端口名称与 registries 数组 中其他注册表声明的包模式均不匹配,默认注册表将作为 fallback。
为方便未使用自定义注册表的用户,kmpkg 会隐式将 内置注册表 设为默认注册表。可通过 default-registry 属性将默认注册表修改为任意注册表,或完全禁用默认注册表。
示例:将自定义注册表设为默认
kmpkg-configuration.json
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/kumose/kmpkg",
"baseline": "84a143e4caf6b70db57f28d04c41df4a85c480fa"
}
}
示例:禁用默认注册表
kmpkg-configuration.json
{
"default-registry": null
}
注册表数组
要扩展 kmpkg 可安装的端口范围,可通过 registries 数组 指定额外的注册表。
示例:向配置中添加自定义注册表
不同类型的注册表在
registries数组中所需的配置信息不同。有关每种注册表类型所需的属性,请参阅kmpkg-configuration.json参考文档。
kmpkg-configuration.json
{
"default-registry": {
"kind": "git",
"repository": "https://github.com/kumose/kmpkg",
"baseline": "84a143e4caf6b70db57f28d04c41df4a85c480fa"
},
"registries": [
{
"kind": "git",
"repository": "https://my.privateregistry.git",
"baseline": "caf6b70db5784a143e4f28d05c480fa4c41df4a8",
"packages": [ "foo" ]
},
{
"kind": "filesystem",
"path": "C:/path/to/registry",
"baseline": "baseline1",
"packages": [ "bar" ]
}
]
}
注册表的推荐实践
不要重写版本历史
版本一旦发布到版本文件中,请勿修改 Git 注册表中其关联的 git-tree 或文件系统注册表中其关联的目录。
kmpkg 的设计原则之一是:已安装依赖项的版本不会在用户未干预的情况下变更。通过修改 git-tree 条目重写版本文件历史,会违反这一原则。
若现有版本存在问题,建议创建新的 port-version。
不要删除版本文件
本节仅适用于 Git 注册表
从注册表中移除端口时,可删除其在 ports 目录中的内容及其在基线文件中的条目,但不要删除其关联的版本文件。
即使端口已从注册表中移除,只要版本文件仍然存在,该端口的用户仍可通过 版本覆盖 安装旧版本。
后续步骤
你可尝试以下任务: