GLEP 67:软件包维护结构

作者 Michał Górny <[email protected]>
类型 标准规范
状态 最终版
版本 1.1
创建日期 2015-12-13
上次修改日期 2021-02-28
发布历史 2015-11-03, 2016-05-29, 2021-02-28
GLEP 源码 glep-0067.rst

摘要

在本 GLEP 中,解释了当前软件包维护者描述系统存在的问题,并提出了一个旨在解决这些问题的新系统。当前复杂的结构被替换为两种定义明确的维护者类型——人员和项目。Herd 被移除,取而代之的是项目,并且项目成员列表以 XML 格式提供。维护者列表在metadata.xml中变得统一,可以直接用于分配 Bug。

变更日志

v1.1
添加了代理属性到软件包<maintainer/>.

动机

简介

当前用于在 Gentoo 中声明维护者的系统多次受到批评。许多邮件列表主题提出了与之相关的各种问题,并提出了替代方案。该主题已提交给委员会,并在 2015 年 10 月 25 日的委员会会议上进行了讨论(延续自 2015 年 10 月 11 日)。

委员会会议做出了两个重要决定

  1. Herd将被弃用并最终删除,无论是在定义中还是在机器使用中。
  2. 替换结构不能临时投票,因此需要编写一个新的 GLEP 来提供完整的提案。

本 GLEP 是对第二个决定的回应,旨在提供一个新的维护结构,其目标是简单性、灵活性以及良好的向后兼容性。

当前系统的概述

当前系统在metadata.xml中使用两个元素来描述维护者

  1. <maintainer/>元素,它由电子邮件地址标识,并且可以具有可选的名称和描述,
  2. <herd/>元素,它由简短的 Herd 名称标识,并且不包含任何额外信息。

该系统规定<maintainer/>元素始终优先于<herd/>,除非维护者描述中另有说明。

这导致列出了四种不同类型的维护者

  1. 普通人员(开发者和代理维护者),使用<maintainer/>,
  2. 具有匹配 Herd 的项目,使用<herd/>, <maintainer/>或两者都描述,
  3. 从属于项目或独立于项目的 Herd,使用<herd/>,
  4. 没有匹配 Herd 的项目和其他电子邮件别名,使用<maintainer/>.

使用<herd/>标签声明的 Herd 对应于herds.xml文件中的 Herd 维护者列表。在过去,此文件可以显式列出 Herd 维护者,也可以从项目中复制它们;但是,将项目迁移到 Wiki 后,后者已失效。

使用<maintainer/>标签声明的维护者没有任何显式的类型指示符。通常,项目 Wiki 页面或电子邮件别名目标用作参考维护者列表。

有一个特殊情况是[email protected]电子邮件地址,当用作维护者时,表示该软件包没有活跃的维护者。

当前系统的问题

迄今为止表达的当前系统的问题包括

  1. 结构中的冗余和复杂性。维护者可以分组为 Herd 维护者、项目或与两者都不对应的电子邮件别名。Herd 可以是等价的、从属的或独立于项目的。
  2. 成员列表中的冗余。不再能够将项目成员隐式复制到 Herd 维护者,反之亦然。因此,对应于项目的 Herd 的维护者必须列出两次——在herds.xml和项目 Wiki 页面中。这两个列表都需要保持同步。
  3. 维护者列表中的冗余。通过使用两个不同的元素来表达维护者,Herd 维护可以以多达三种不同的方式表达。
  4. 维护者列表中的隐式排序规则。维护者的重要性由描述、使用的元素以及实际出现的顺序决定。它不是完全机器可读的。
  5. Bug 分配的不必要间接性。如果一个软件包属于一个 Herd,则需要解析herds.xml以获取与 Herd 名称对应的 Bug 分配电子邮件地址。
  6. 不明确且复杂的成员扩展规则。Herd 的维护者可以使用herds.xml确定,除非 Herd 对应于在 Wiki 页面上具有不同成员列表的项目。非 Herd 维护者可以是人员、项目(来自 Wiki 页面的成员)或其他无法明确获取成员列表的组。
  7. 跨存储库含义不明确。在多个存储库链中,herds.xml的定义并不明确,而metadata.xml则明确。

规范

软件包维护

每个软件包定义零个或多个维护者。每个维护者可以是人员项目。每个维护者都由一个唯一的电子邮件地址标识,该地址必须对应于一个活动的 bugs.gentoo.org 帐户。可选地,每个维护者可以定义一个人类可读的名称和维护说明。

维护者使用 metadata.xml<maintainer/>元素进行描述。维护者的类型由type元素的<maintainer/>属性定义。电子邮件地址、人类可读的名称和维护说明分别放置在<email/>, <name/><description/>子元素中。

可选地,可以指定一个代理属性,该属性可以具有三个可能值中的一个

  • yes表示维护者是代理维护者(即无法直接推送更改)
  • no表示维护者是真实维护者(即可以直接推送更改)
  • proxy表示列出的开发者仅作为其他维护者的代理

如果未指定该属性,则假定默认值为no。如果至少一个维护者被列为代理维护者(proxied="yes"),则至少应将另一个维护者列为代理(proxied="proxy"),反之亦然。

<pkgmetadata>
  <maintainer type="person" proxied="yes">
    <email>[email protected]</email>
    <name>Foo Barsky</name>
  </maintainer>
  <maintainer type="person">
    <email>[email protected]</email>
    <name>Example Developer</name>
  </maintainer>
  <maintainer type="project" proxied="proxy">
    <email>[email protected]</email>
  </maintainer>
</pkgmetadata>

项目结构

GLEP 39 定义了基本项目结构。但是,将要维护软件包的项目必须满足具有唯一电子邮件地址以及相应的 bugs.gentoo.org 帐户的附加要求。

每个项目可以有零个或多个子项目,它可以从中选择性地继承成员。项目是否可以有多个父项目尚不清楚。但是,完整的项目层次结构必须形成一个无环有向图。

项目结构从 wiki.gentoo.org 导出到projects.xml文件中。该文件由根<projects/>元素组成,该元素包含一个或多个<project/>元素。每个<project/>元素包含以下子元素

  • <email/>元素,声明项目联系电子邮件(必须在 bugs.gentoo.org 上注册),
  • <name/>元素,声明人类可读的项目名称,
  • <url/>元素,声明项目主页 URL,
  • <description/>元素,简要描述项目,
  • 零个或多个<subproject/>元素,列出特定项目的子项目,
  • 零个或多个<member/>元素,列出直接项目成员。

每个<subproject/>元素具有以下属性

  • 必填ref=""属性,通过电子邮件地址引用子项目(电子邮件地址必须等于<email/>元素的值,且仅存在于一个其他<project/>),
  • 可选inherit-members=""属性,其非空值表示子项目成员也应被视为父项目的成员。

每个<member/>具有以下子元素

  • <email/>声明成员的电子邮件地址,
  • 可选<name/>声明成员的人类可读名称,
  • 可选<role/>声明成员在团队中的角色。

此外,<member/>可以具有可选的is-lead=""属性,其非空值表示该特定成员是项目的负责人。

<projects>
  <project>
    <email>[email protected]</email>
    <name>Portage package manager</name>
    <url>https://wiki.gentoo.org/wiki/Project:Portage</url>
    <description>Something about Portage</description>
    <member is-lead="1">
      <email>[email protected]</email>
      <name>Example Developer</name>
      <role>Lead</role>
    </member>
    <member>
      <email>[email protected]</email>
      <name>Another Developer</name>
    </member>
    <!-- members are not inherited, purely organizational hierarchy -->
    <subproject ref="[email protected]"/>
  </project>
  <project>
    <email>[email protected]</email>
    <name>Portage-related utilities</name>
    <url>https://wiki.gentoo.org/wiki/Project:Tools-Portage</url>
    <description>Maintainers of various common Portage tools</description>
    <member is-lead="1">
      <email>[email protected]</email>
      <name>Another Developer</name>
      <role>Lead</role>
    </member>
    <member>
      <email>[email protected]</email>
      <name>Example Developer</name>
    </member>
    <!-- members are inherited -->
    <subproject ref="[email protected]" inherit-members="1"/>
  </project>
  <project>
    <email>[email protected]</email>
    <name>Portage-related utility of some kind</name>
    <url>https://wiki.gentoo.org/wiki/Project:Some-Portage-Tool</url>
    <description>My random Portage tool</description>
    <member is-lead="1">
      <email>[email protected]</email>
      <name>Me!</name>
      <role>Lead</role>
    </member>
  </project>
</projects>

projects.xml 分发

projects.xml文件位于存储库内的metadata目录中,并应用于存储库以及将该文件指定为其主存储库(直接或间接)的所有存储库。相应地,当为软件包执行项目查找时,将首先扫描包含该软件包的存储库中的projects.xml,然后递归扫描其主存储库。

每个项目在应用于存储库的有效projects.xml文件集中不得指定多次。特别是,无法在子存储库中更改或重新定义继承的项目。建议每个存储库对其项目使用单独的命名空间(例如电子邮件地址的主机名部分)。

Bug 分配

包元数据描述对于错误分配是完全自足的。元素出现的顺序(应用限制后)指示责任链。<maintainer/>错误被分配给第一个维护者,而所有其余的维护者都被抄送。

对于没有维护者的包,将应用存储库特定的错误分配规则。特别是,没有维护者的 ::gentoo 包将分配给[email protected].

维护者扩展

为了确定维护者的有效列表,将使用projects.xml扩展所有项目类型维护者。每个项目都通过电子邮件地址匹配,并替换为一个或多个维护者对象。项目成员形成人员类型维护者,项目负责人(如果有)拥有对其余项目成员的权限。子项目形成项目类型维护者,这些维护者将被递归扩展。

基本原理

<herd/> 与 <project/> 与 <maintainer/>

使用<herd/>元素指示群体维护已被理事会于 2015 年 10 月 25 日弃用,作为弃用群体概念的扩展。作为替代方案,建议引入<project/>元素或修改<maintainer/>元素。

新的<project/>元素已被拒绝,因为它意味着以不同的名称重新引入相同的结构,但问题相同。使用<maintainer/>元素指示所有维护者具有以下优点

  1. 简洁的数据库结构。由于人员类型和项目类型维护者实际上都是维护者,因此它们应该从单个元素派生,而不是两个不相交的元素。
  2. 简洁的错误分配顺序。之前,这两个元素被分配了权重,其中考虑<maintainer/><herd/>更重要,违背了它们的常规顺序。即使引入新的元素没有这种隐式权重,开发人员也会错误地回忆旧规则并继续应用它们。
  3. 更一致的记录格式。过去,一些群体/项目使用<herd/>元素描述,一些使用<maintainer/>元素描述,甚至有些同时使用两者。使用单个元素避免了这种不一致。
  4. 向后兼容性。重新使用现有的、得到良好支持的元素意味着保持与现有工具的向后兼容性。虽然它们的功​​能将受到限制,直到它们更新以适应新的项目结构,但至少它们不会完全崩溃。

电子邮件地址作为项目标识符

曾讨论过项目是否应该由短标识符(类似于群体)或其电子邮件地址来识别。由于以下优点,选择了电子邮件地址

  1. 重用现有标识符。由于群体已被弃用且旧的项目页面已删除,因此不再有任何官方的项目短标识符。Wiki 上使用的标识符强制区分大小写,当然也不短。仅仅为了映射元数据而引入额外的标识符似乎没有必要。
  2. 元数据的独立意义。使用电子邮件地址直接在元数据中提供有意义的信息(例如,用于联系或错误分配)。使用其他类型的标识符意味着需要进行某种转换或映射。
  3. 跨项目正确性。电子邮件地址是全局唯一的。这意味着非 Gentoo 项目可以拥有自己的存储库,并声明自己的项目,而无需担心短名称冲突。
  4. 向后兼容性。虽然当前的工具无法识别项目类型维护者作为事实上的项目,但它们仍然能够正确识别其电子邮件地址。

需要维护者的软件包的情况

在以前的系统中,[email protected]电子邮件地址用于标记缺乏活跃维护者的包。此解决方案不再适合新系统,因为maintainer-needed既不是人,也不是项目。

虽然纯技术上可以创建一个新的maintainer-needed项目,但它实际上并不适合传统的项目结构。此外,它仍然会带有特殊规则,指示此项目的拥有权实际上表示没有维护者。

相反,没有活跃维护者的情况通过不列出任何维护者来表示,这在语义上更清晰。错误分配给[email protected]是通过适当的错误分配规则进行的。

项目结构

项目结构由 GLEP 39 定义,因此不在本规范的范围内。该projects.xml映射尝试提供存储在 Gentoo Wiki 上的项目信息的脱机副本,格式类似于用于herds.xml.

该格式的基本目标是提供获取有效项目成员列表的方法。

子项目结构旨在定义集体项目,其中特定项目的成员包括所有子项目的成员。这曾经被定义为<membersof/>herds.xml<subproject inheritmembers=""/>旧项目 XML 文件中的属性。

指定 type="" 与引用 projects.xml

有人指出,指定type=""维护者的类型是多余的,因为可以通过将维护者的电子邮件地址与projects.xml.

匹配来确定维护者类型。明确添加此信息是为了提高可读性并避免对非项目维护者进行不必要的项目数据库查找。此外,项目数据库和元数据维护者类型之间出现不同步的可能性很小,因为人员和项目是不可互换的,并且我们无法期望人员的电子邮件地址被重新用于新项目,反之亦然。

指定维护者姓名与引用其他 XML

有人指出,在metadata.xml中指定全名是多余的,因为每个维护者都有一个唯一的名称,通常在所有<maintainer/>出现中共享。相反,可以使用额外的数据库(字典)将维护者的电子邮件地址映射到真实姓名——或者完全删除真实姓名。

从旧系统保留了对可选维护者名称的支持。指定名称完全可选,并被视为便利/尊重问题,而不是技术上重要的信息。此外,与电子邮件地址不同,名称很少更改。在代理维护者的情况下,在查找新维护者的电子邮件地址时,引用真实姓名并不少见。

虽然维护者名称的外部数据库允许一致地将真实姓名分配给维护者,但这似乎有点过头了。此外,此数据库很可能被迫驻留在存储库之外,这会导致更多同步问题并使代理维护者工作流程更加困难。特别是,当前代理维护者可以将自己添加到metadata.xml在一个提交到存储库的操作中。如果使用外部数据库,则除了存储库提交之外,还需要更新数据库。

代理维护者

从 1.1 版开始,一个额外的代理属性已添加到<maintainer/>包维护者的元素中。这用于明确区分常规开发人员、代理维护者和代理。

主要目的是解决用于报告剩余代理维护项目实例的 QA 报告中的误报,以及改进对没有代理的维护者的检测。目前,这些检查无条件地假设所有 Gentoo 开发人员都具有提交访问权限,而其他所有人都是代理维护者。这没有考虑到没有提交访问权限但通过代理维护包的开发人员。

该属性作为单独的属性添加,以确保向后兼容性。

向后兼容性

新的 metadata.xml 格式

GLEP 保留了与当前metadata.xml格式几乎完全的向后兼容性,以下更改

  1. <herd/>元素已删除。由于它是完全可选的,因此没有任何工具被破坏。
  2. <maintainer/>用于描述项目和人员。这种情况之前有时已经存在,但工具无法扩展项目成员的限制。此限制扩展到现有工具中的所有项目,并且可以通过更新工具以支持projects.xml.
  3. <maintainer/>赋予新的type=""属性。没有已知的工具拒绝metadata.xml规范,只要提供了更新的 DTD,这些规范具有多余的属性。

projects.xml 和 herds.xml

projects.xml文件提供herds.xml的替代方案,符合新结构。由于使用了新文件,因此更改与现有软件完全兼容。该herds.xml文件必须保留一段时间,直到所有<herd/>出现都被删除。

删除herds.xml应该只会导致非常有限的破坏。使用例如 CVS 检出的 Gentoo 系统已经缺少该文件,因此工具需要优雅地处理这种情况。为了提高兼容性,可以在额外的过渡期内分发一个herds.xml文件,其中不列出任何群体。

新的projects.xml文件格式与herds.xml文件格式提供部分兼容性,旨在在迁移到新系统时减少工作量。

从当前系统转换

迁移到新系统将需要两个准备步骤

  1. 必须确保所有现有项目都具有唯一的电子邮件地址。共享相同电子邮件地址的项目需要合并,或者需要赋予唯一的电子邮件地址。
  2. 所有群体都需要转换为项目、子项目或解散(由人员类型维护者替换)。

之后,projects.xml可以从 Wiki 正确生成,并且可以替换herds.xml.

为了使当前的metadata.xml文件符合新格式,需要执行两步转换

  1. 所有<herd/>元素需要替换为相应的<maintainer/>元素,并且需要正确调整元素顺序。特别是,新的<maintainer/>元素必须放置在现有<maintainer/>元素之后,除非维护者描述请求其他操作。在过渡期内,<herd/>元素可能仍然受支持。
  2. 所有<maintainer/>元素都需要赋予相应的type=""。这可以通过将<maintainer/>电子邮件地址与项目地址匹配来完成,并假设项目只要有匹配,人员否则。

参考实现

DTD 文件

本 GLEP 中指定的 XML 文档的参考文档类型定义文件存储在data/dtd.git存储库 [1] 中。的 DTDprojects.xml存储为projects.dtd在存储库的主分支中 [2]。的更新后的 DTDmetadata.xml存储为metadata.dtd在存储库的 glep67 分支中 [3]

projects.xml 生成

生成 projects.xml 文件的代码存储在 semantic-data-toolkit 仓库中 [4]。生成的项目文件可从 api.gentoo.org 获取 [5]

metadata.xml 迁移

用于将现有的 metadata.xml 文件迁移到新格式的工具由 herdfix 项目提供 [6]。当前的迁移结果可以在 Gentoo GitHub PR #559 上查看 [7]

迁移过程分四个步骤进行,每个步骤使用单独的脚本。

  1. 初步清理(由于 lxml 不会保留原始的单引号和双引号使用方式,因此需要进行此步骤),
  2. 替换所有<herd/>元素,
  3. 移除剩余的[email protected]条目(现在将隐式表示为空的维护者列表),
  4. 设置type=到所有<maintainer/>项目上。

每个<herd/>将被替换,基于 Herd 维护者的决定或缺乏决定,替换为

  1. 项目维护者,
  2. 当前 Herd 维护者的单独内联列表,
  3. 无维护者(实际上将软件包留给其他维护者或将其降级到 maintainer-needed)。

Portage

由于具有很高的向后兼容性,因此使用新系统无需对 Portage 进行任何更改。但是,mgorny 的 Portage 分支的 glep67 分支 [8] 包含了对 GLEP 67 支持的改进。特别是,该分支添加了显式的maint_type属性到_Maintainer对象,并删除了herds.xmlrepoman 检查(由于已删除herds.xml因此这些检查将处于非活动状态)。

metadata.xml一旦更新,将隐式检查对新系统的符合性。metadata.dtd将来可以添加其他 type-to-projects.xml 检查。