GLEP 68: 包和类别元数据

作者 Michał Górny <[email protected]>
类型 标准轨
状态 最终版
版本 1.4
创建日期 2016-03-14
上次修改日期 2023-02-22
发布历史 2016-03-16, 2018-02-20, 2022-05-22, 2022-10-07, 2023-02-22
需要 67
替换 34 46 56
GLEP 源代码 glep-0068.rst

摘要

此 GLEP 指定用于描述类别和包元数据的文件格式(metadata.xml).

动机

在撰写本 GLEP 时,类别和包metadata.xml缺乏适当的规范。PMS 附录 A [1] 规定此文件格式超出了其范围,将规范推迟到 DTD 文件。

原始 metadata.dtd 文件 [2](与本规范相关的清理之前的版本)不能很好地用作规范。由于 DTD 格式的技术局限性,它既无法完全执行规范,也无法以可读的形式进行解释。此外,它还缺少一些重要细节,例如<pkg/>条目。

除此之外,格式还进行了许多修改。GLEP 34 为类别描述添加了元数据文件,GLEP 46 添加了上游信息,GLEP 56 添加了 USE 标志描述,GLEP 67 修改了维护者描述。此外,还有一些添加和删除是在没有正式规范的情况下进行的,例如添加插槽描述。

遗憾的是,其中一些 GLEP 与其他规范部分冲突 - 例如,<pkg/>元素在 GLEP 56 中的描述与最初提出的并在 metadata.xml 中使用的元素不同。

因此,本 GLEP 的动机是为类别范围和包范围的 metadata.xml 文件提供统一、清晰和完整的规范。它旨在结合之前的 GLEP、相关讨论和实现,以提供最接近最初预期含义的规范,同时保持与现有工具和数据的最佳兼容性。

规范

元数据文件

此规范提供了两种元数据文件:类别元数据文件和包元数据文件。这两种文件都使用 XML 1.0 文件格式 [3]。它们不能使用外部标记声明,如 XML 规范中所定义。虽然它们可以引用或包含 DTD,但解析器不能获取或处理它。

元数据文件的數據结构在本 GLEP 中定义。元素和属性不使用命名空间。符合规范的文件不能包含本规范中未定义的任何元素或属性。但是,解析器应忽略任何未知元素或属性,以便允许将来扩展。

类别元数据文件命名为metadata.xml并位于 ebuild 存储库中的类别目录内。它们的结构在 类别元数据 部分中描述。

包元数据文件命名为metadata.xml并位于 ebuild 存储库中的包目录内。它们的结构在 包元数据 部分中描述。

文本数据

使用以下文本数据类型

  • 文本数据
  • 多行文本数据。

对于文本数据,元素内部的所有空格都会被规范化(连续的空格序列将被替换为单个 SP)。尾部和前导空格将被剥离。

对于多行文本数据,所有空格(换行符除外)都会被规范化。换行符用于分隔文本行。前导和尾随的文本行(为空或仅包含空格)将被剥离。之后,将剥离所有非空文本行的共同缩进的空格。

可选地,可以在文本中插入<cat/><pkg/>元素。在这种情况下,<cat/>元素用于引用存储库中的类别,并且必须包含有效的类别名称。<pkg/>用于引用包,并且必须包含有效的限定包名称。

通用属性

以下通用属性在多个元素上允许

  • 语言说明符
  • 限制说明符。

语言说明符用于元素支持不同语言的变体的情况。在这种情况下,元素的每次出现都可能包含一个可选的lang=""属性,该属性包含 IETF 语言标签 [4]。如果没有提供lang=""属性,则假定隐式默认值为en

限制说明符用于元素支持限制为特定包版本的情况。在这种情况下,元素的每次出现都可能包含一个可选的restrict=""属性,该属性包含必须与一个或多个包版本匹配的 EAPI 5 依赖关系规范。在这种情况下,元素提供的元数据仅适用于与限制匹配的包版本。

类别元数据

类别元数据文件使用<catmetadata/>顶级元素。此元素可以包含以下内容,顺序任意

  • 零个或多个<longdescription/>元素,包含不同语言的类别描述(每个语言最多一个)。类别描述由多行文本组成,可选地插入<cat/><pkg/>元素。

包元数据

顶级结构

包元数据文件使用<pkgmetadata/>顶级元素。此元素可以包含以下内容,顺序任意

  • 零个或多个<longdescription/>元素,包含不同语言的包描述,可能限制为特定包版本(每个语言和包版本的组合最多一个)。包描述由多行文本组成,可选地插入<cat/><pkg/>元素。
  • 零个或多个<maintainer/>元素,列出包维护者,可能限制为特定包版本。维护者格式在 维护者描述 中详细说明。
  • 零个或多个<slots/>元素,包含不同语言的插槽描述(每个语言最多一个),如 插槽描述 中详细说明。
  • 零个或多个<stabilize-allarches/>元素,可能限制为特定包版本(每个版本最多一个),其存在表示相应的 ebuild 适用于在其中一个架构上进行架构测试后,在所有先前版本已稳定的架构上同时标记为稳定(即,如果该包已知完全独立于架构)。
  • 零个或多个<use/>元素,包含不同语言的 USE 标志描述(每个语言最多一个),如 USE 标志描述 中详细说明。
  • 最多一个<upstream/>元素,提供有关包的上游信息,如 上游描述 中详细说明。

维护者描述

每个<maintainer/>元素描述单个维护者。

The<maintainer/>元素有一个强制性的type=""属性,其值可以是personproject.

The<maintainer/>元素包含以下元素,顺序任意

  • 正好一个<email/>元素,包含维护者的电子邮件地址(用作唯一标识符),
  • 最多一个<name/>元素,包含维护者的可读名称(真实姓名或昵称),
  • 零个或多个<description/>元素,解释维护者在不同语言中的角色(每个语言最多一个<description/>)。

插槽描述

每个<slots/>元素描述包的插槽(以特定语言)。

The<slots/>元素可以包含以下元素

  • 零个或多个<slot/>元素,描述特定的 ebuild 插槽(每个插槽名称最多一个)。该<slot/>元素包含一个强制性的name=""属性,声明描述适用的插槽,并包含插槽描述作为文本。或者,可以将插槽名称用作*来指示应用于所有插槽的单个描述(在这种情况下,不能使用其他<slot/>元素)。
  • 最多一个<subslots/>元素,描述子插槽(所有子插槽)的角色作为文本。

USE 标志描述

每个<use/>元素描述包的 USE 标志(以特定语言)。

The<use/>元素可以包含以下元素

  • 零个或多个<flag/>元素,描述特定的 USE 标志,可能限制为特定包版本(每个 USE 标志名称和包版本的组合最多一个条目)。该<flag/>元素包含一个强制性的name=""属性,声明描述适用的 USE 标志的名称,并包含文本,可选地插入<cat/><pkg/>元素。

上游描述

The<upstream/>元素提供有关包上游的信息。它包含以下元素

  • 零个或多个<maintainer/>元素,列出包的上游维护者,如 上游维护者描述 中描述,
  • 最多一个<changelog/>元素,包含上游变更日志的在线副本的 URL,
  • 零个或多个<doc/>元素,包含不同语言的上游文档的在线副本的 URL(每个语言最多一个),
  • 最多一个<bugs-to/>元素,包含上游错误报告 URL,它可以选择是一个mailtoURL,
  • 零个或多个<remote-id/>元素,列出包标识跟踪器上的包标识。这些元素中的每一个都有一个强制性的type=""属性,该属性与预定义的包标识跟踪器名称匹配,以及一个特定于跟踪器的值。可用跟踪器及其特定标识符的列表不在本规范的范围内。

上游维护者描述

每个<maintainer/>元素在<upstream/>中描述单个上游维护者。

The<maintainer/>元素有一个可选的status=""属性,其值可以是activeinactive。如果未指定,则假定隐式unknown值。

The<maintainer/>元素具有以下属性,顺序任意

  • 最多一个<email/>元素,包含维护者的电子邮件地址,
  • 正好一个<name/>元素,包含维护者的可读名称(真实姓名或昵称)。

基本原理

信息来源

有关当前 metadata.xml 格式的基本信息来源是metadata.dtd截至 2016-03-02 [5]。 DTD 不清晰的地方,参考相应的 GLEP 来推断原始意图。GLEP 不清晰或元素遗漏 GLEP 的地方,则参考原始邮件列表讨论。

已移除的元素

与原始 DTD 相比,以下元素已被移除(在规范和更新后的 DTD 文件中均已移除)

  • package-scope<changelog/>元素已被移除。它可以追溯到原始的 metadata.xml 提案 [5],但从未被实现过 - 相反,使用了纯文本 ChangeLogs。此外,GLEP 46 引入了<changelog/>inside<upstream/>具有不同类型,由于 DTD 的限制,与全局声明冲突。
  • package-scope<natural-name/>元素已被移除。它使用了 1.5 年,之后有四个包提供了它,但没有已知的工具支持或使用它。它仅用于提供具有正确大小写(例如 libressl -> LibreSSL)的包名称副本,因此它提供的信息被认为是冗余的。
  • top-level<packages/>变体已被移除。它从未被使用过,而且它的用途确实不清楚。无论如何,这使得 DTD 更简单。

<pkg/> 值格式

关于<pkg/>元素值的有效格式的争论在撰写此 GLEP 之前就已经存在。DTD 没有指定该值格式的限制,只是建议将其用于跨链接。此外,GLEP 56 将其值重新定义为有效的 CP 或 CPV。实际用途不包括后一种情况;然而,在限定的包名称之后包含 EAPI 1 槽位说明符甚至 EAPI 5 槽位操作符是常见的。

在找到 Doug Goldstein 关于引入 <pkg/> 元素的博客文章 [6] 后,事实证明,最初的意图是允许从 packages.gentoo.org 进行交叉链接/引用。由于后者使用限定的包名称作为标识符,因此决定将<pkg/>元素限制为引用这些。对于包含槽位说明符的条目,建议将槽位说明符从<pkg/>元素中移出。

语言标识符

最初,DTD 使用C的隐式默认值。但是,此值与在metadata.xml中找到的真实语言说明符不一致。后者通常采用 ISO 639-1 语言代码的形式,这些代码不构成有效的(完整的)区域设置标识符,而前者在任何已考虑的标准中都不是有效的语言标识符。此外,由于en通常用于在 metadata.xml 文件中标识英语,并且没有工具依赖于 DTD 中定义的隐式默认值,因此决定将隐式默认值更改为en.

语言标识符后来更新为允许完整的 IETF 语言标签,以便像pt-BRzh-Hant之类的代码可以被表示。

包限制

最初,DTD 将restrict=""属性描述为:此属性的格式等于 ebuild 中 DEPEND 行的格式。此规范基于此定义。但是,出于实际原因,它在此基础上添加了三个澄清

  • 仅允许包依赖项规范(即不允许 USE 条件或多个依赖项规范),
  • 允许 EAPI 5 依赖项规范。虽然metadata.xml没有提供 EAPI 识别机制,但顶级配置文件目录指定了 EAPI 5,并且 Portage 自 2012 年以来就支持 EAPI 5。
  • 仅允许引用相同包的依赖项。

此外,DTD 为*值添加了一个特殊情况,如果不存在其他适用的标签,则适用此值。此行为根本没有使用,并且至少有点令人困惑(与*用于隐含匹配一切的常用用法相比),因此已被移除。

上游块

上游块由 GLEP 46 定义。但是,此 GLEP 最多是模棱两可的。Tiziano Müller(原始作者之一)解释了 GLEP 中大多数元素背后的意图。

具体来说,他确认 GLEP 列出了所有明确允许的元素,并且不打算允许隐式包含。这意味着<maintainer/>元素不允许<description/>.

他同时确认,除非另有说明,否则不允许元素使用超过一次。这影响了<bugs-to/><changelog/>元素。重复<doc/>仅允许是因为 DTD 在技术上不允许在允许使用不同语言的同时限制它们。

在撰写此 GLEP 时,只有一个 Gentoo 包正在使用多个<bugs-to/>元素,并且没有包正在使用多个<changelog/><doc/>元素(或非英语文档)。因此,此 GLEP 强制执行最多一个元素的原始意图。

上游维护者描述的基本原理

<maintainer/>元素中的<upstream/>块中的适当内容在 DTD 中并不清楚,因为技术文件格式限制意味着为 Gentoo 维护人员添加的所有元素和属性也适用于上游维护人员,反之亦然。

DTD 中的注释明确地将属性区分开来 - 即声明type属性仅用于 Gentoo 维护人员,而status属性仅用于上游维护人员。但是,包版本限制和维护人员描述也被隐式地允许使用。由于 GLEP 46 不允许这两者,因此此规范不允许它们。

向后兼容性

此规范没有引入任何与当前 DTD 相比的新元素或属性。因此,所有metadata.xml在符合其规范的情况下创建的文件将被现有工具正确读取,并将符合当前 DTD。

但是,此规范比 DTD 强制执行的规则更严格。因此,并非所有现有的metadata.xml都将符合规范,即使它们根据 DTD 是正确的。新的工具将认为这些文件不正确,并要求开发人员进行修复。

参考实现

解析 metadata.xml

由于此规范提供的 metadata.xml 格式与现有工具兼容,因此读取这些文件不需要新的实现。

检查 metadata.xml 有效性

为了更严格地检查 metadata.xml 文件,Gentoo xml-schema 存储库 [7] 中提供了 XML 模式文件。此模式提供了

  • 元素结构检查,
  • 数据重复检查(例如,同一个标志的多个描述,但请参见下文),
  • 部分值正确性检查。

模式的限制是

  • 使用简单的正则表达式验证值,因此并非所有格式违规都会被捕获(例如,该规则将认为app-foo/bar-1是一个有效的限定包名称,而版本后缀是不允许的),
  • 无法检查交叉引用(包引用、类别引用、URL、项目标识符),
  • <maintainer type=""/>无法检查正确性,
  • 数据重复检查是针对每个restrict=""值进行的,而不是针对与限制匹配的每个包版本进行的。因此,两个不同的restrict=""规则应用于单个包的多个定义将不会被捕获。

metadata.xml 文件示例

<?xml version='1.0' encoding='UTF-8'?>
<pkgmetadata>
  <maintainer type='person'>
    <email>[email protected]</email>
    <name>Example Developer</name>
  </maintainer>
  <maintainer type='person' restrict='dev-libs/foo:11'>
    <email>[email protected]</email>
    <name>Another Developer</name>
    <description>CC only on bugs for libfoo.so.11</description>
  </maintainer>
  <maintainer type='project'>
    <email>[email protected]</email>
    <name>Example Project</name>
  </maintainer>
  <maintainer type='person'>
    <email>[email protected]</email>
    <name>Upstream Developer</name>
    <description>Upstream developer, wishing to be CC-ed on bugs</description>
  </maintainer>
  <longdescription>
    First paragraph of extensive description.

    Second paragraph.
  </longdescription>
  <longdescription lang='de'>
    Erster Absatz mit detaillierter Beschreibung.

    Zweiter Absatz.
  </longdescription>
  <slots>
    <slot name='11'>Compatibility slot providing libfoo.so.11 only.</slot>
    <subslots>
      Match SONAME of libfoo.so.
    </subslots>
  </slots>
  <slots lang='de'>
    <slot name='11'>Kompatibilitäts-Slot, installiert ausschließlich libfoo.so.11.</slot>
    <subslots>
      Subslot ist stets identisch mit dem SONAME von libfoo.so.
    </subslots>
  </slots>
  <use>
    <flag name='foo'>Enables foo feature</flag>
    <flag name='bar' restrict='&lt;dev-libs/foo-12'>Enables bar feature (requires <pkg>dev-libs/bar</pkg>)</flag>
    <flag name='bar' restrict='&gt;=dev-libs/foo-12'>Enables bar feature</flag>
  </use>
  <use lang='de'>
    <flag name='foo'>Konfiguriert das Paket mit Unterstützung für foo</flag>
    <flag name='bar' restrict='&lt;dev-libs/foo-12'>Konfiguriert das Paket mit Unterstützung für bar (benötigt <pkg>dev-libs/bar</pkg>)</flag>
    <flag name='bar' restrict='&gt;=dev-libs/foo-12'>Konfiguriert das Paket mit Unterstützung für bar</flag>
  </use>
  <upstream>
    <maintainer status='active'>
      <email>[email protected]</email>
      <name>Upstream Developer</name>
    </maintainer>
    <maintainer status='inactive'>
      <!-- e-mail unknown -->
      <name>John Smith</name>
    </maintainer>
    <changelog>http://www.example.com/releases.html</changelog>
    <doc>http://www.example.com/doc.html</doc>
    <doc lang='de'>http://www.example.com/doc.de.html</doc>
    <bugs-to>http://www.example.com/issues.html</bugs-to>
    <remote-id type='foohub'>example/foo</remote-id>
  </upstream>
</pkgmetadata>

德语翻译由 tamiko 提供。

参考文献

[1]PMS 附录 A https://projects.gentoo.org/pms/5/pms.html#x1-163000A
[2]原始 metadata.dtd 文件 https://gitweb.gentoo.org/data/dtd.git/tree/metadata.dtd?id=a908a93b5afe295359e0a01814c9bef8b5268bcd
[3]可扩展标记语言 (XML) 1.0(第五版) https://www.w3.org/TR/xml/
[4]BCP 47:“用于识别语言的标签”, https://tools.ietf.org/rfc/bcp/bcp47.txt
[5](1, 2) 原始 metadata.xml 提案:Paul de Vrieze。“重要:metadata.xml 文件的提案”。gentoo-dev 邮件列表,2003-06-27,Message-ID [email protected]https://archives.gentoo.org/gentoo-dev/message/cbcc15e9906c0165976ad66d4343ba7a
[6]Doug Goldstein:USE 标志元数据 https://cardoe.wordpress.com/2007/11/19/use-flag-metadata/
[7]Gentoo XML 模式 https://gitweb.gentoo.org/data/xml-schema.git/