Clojure

筛选票证

如果您有兴趣提供补丁或为 Clojure 贡献代码,请参阅 开发概述.

筛选工作旨在创建一个高质量的问题和解决方案流,以便 BDFL 可以有效地审查并考虑将它们包含在内。虽然此页面使用通用术语“筛选”,但实际上在 工作流程 中的步骤中,社区和 Clojure 核心团队可以在多个特定位置提供价值。

  • 分诊 - 评估传入的票证(通常是针对 Ask Clojure 问题的票证)

  • 审核 - 使票证代表良好的 **问题**

  • 筛选 - 评估票证和补丁的 **解决方案**

这些不同的流程在重点上有所不同,但都具有使票证讲述一个关于所遇到的问题、所考虑的解决方案以及最终选择的解决方案(带补丁)的良好故事的共同目标。

一个好的“bug”票证是什么样子的?

在 JIRA 中标记为 bug 的票证应描述 Clojure 运行不正常的问题,通常是根据文档字符串或其他文档产生错误的结果。一个好的 JIRA bug 应该有

一个描述问题的摘要(标题)(而不是建议的解决方案)和一个描述,其中包含以下所有适用的内容

  • 症状 - 用户看到的问题的迹象 - 通常从顶部开始,但可能会在了解实际问题时移动到评论中以供历史保存

  • 问题 - 如果已知,则对问题的陈述

  • 实际结果 - 发生了什么

  • 预期结果 - 应该发生什么

  • 重现 - 简洁的内联重现(最好不是 github 仓库,或 gist,或链接)

  • 原因 - 为什么发生了意外的事情

  • 替代方案 - 可能的解决问题的方法以及它们之间的权衡

  • 建议 - 建议的解决方案以及任何筛选注意事项

  • 补丁 - 实现建议的补丁的名称

预期的是,一个新的读者应该能够从上到下阅读此票证,并了解为什么提交此 bug、问题、解决方法的思考以及在补丁中选择的解决方案。

一个好的“改进”或“新功能”票证是什么样子的?

改进票证通常应该类似于“bug”票证,但可能缺少重现,因为这要求进行增强。您应该重点关注的是为什么这种增强很重要或值得拥有。一般来说,我们关注的是为用户提供他们需要完成目标的新功能,因此请说明您想做什么以及为什么现有功能无法做到这一点。

“改进”和“新功能”之间的界限有些模糊,不要过分强调。

如果建议一个在野外(在流行的实用程序库中)已经存在的函数或实用程序,则票证应包含对现有实现的研究 - 它们有什么不同,它们有多流行,它们的性能如何等等。

改进票证越能关注问题而不是“添加东西”,就能提出越多的替代方案,最终的解决方案也会越好。

如何“接手”一张票

如果您打算处理分诊、预筛选或筛选的票证,请将“受理人”字段设置为您的姓名。如果“受理人”字段已经设置为某人,请在票证系统之外与他们联系,或者评论并询问他们是否仍在查看它。如果您在几天内没有看到回复,您可以更改受理人。完成后,请确保取消设置“受理人”字段。

分诊流程

这里的大问题是:“这是否是一个有效的错误/请求?”

分诊清单

  • 问题是否正确分类为 Bug(现有功能中的问题)、Improvement(现有功能的扩展)或 New Feature(新功能)?

  • (改进)票证是否表明了建议的重要性以及影响范围?例如,使用像 https://grep.app 这样的工具研究公共代码库中所建议的实用程序函数的频率。

  • (错误)票证是否包含一个带有预期结果和实际结果的重现?

  • 您可以在 Clojure 的当前版本上重现问题吗?

  • 这是否与现有问题重复?

  • 问题实际上是否是多个问题?

  • 标签是否正确?请使用现有标签,并将新建标签作为最后的手段。

可用操作

  • 写一个评论并说明您认为应该做什么

  • 修改票证字段以解决上述问题

  • 如果是多个问题,请创建新的票证并将它们分成多个票证,并将它们适当地链接起来

  • 如果没有问题,请将“批准”字段标记为“已分诊”(并在评论中说明)

准备好分诊的票证:CLJ 已打开

审核流程

这里的大问题是:“这是一个陈述良好的问题吗?”

审核清单

  • 分诊清单中的所有内容(以防万一没有完成)

  • 是否有问题陈述?

  • 所陈述的问题真的是一个问题,而不是要做的事情或解决方案?

  • 描述是否很好地分成问题/仓库/原因/替代方案/建议/补丁?

  • 检查“优先级”字段 - 应该更高还是更低?有多少人受到影响?如果受到影响,严重程度是什么?是否有解决方法?

  • 如果问题有性能方面,是否有揭示问题的基准和时间?(应该有足够的信息来重现以后的任何时间)

可用操作

  • 写一个评论 - 如果你认为它已经准备好审核,请在评论中说明。如果需要因范围/严重程度而引起注意,请在评论中提出。

  • 修改描述或其他字段以解决上述问题

需要查看的票证

筛选/预筛选流程

这里的大问题是:“这是一个解决问题的良好解决方案吗?”

有时我们会通过考虑它在 Rich 审核之前是否是一个好的解决方案来“预筛选”一张票。这有时可以通过预加载此工作来使问题快速通过流程的后期部分。

注意:如果您编写了补丁,您不应该预筛选或筛选票证!我们希望有不同的眼睛看待它。

筛选清单

  • 审核清单中的所有内容

  • 原因 - 一旦了解了问题,请尽量清楚地说明问题的根源

  • 替代方案 - 您应该尝试为任何问题想出多个替代解决方案(特别是对于新功能)。不要忘记始终存在的另一种替代方案:不做任何事。使用问题来发现可以比较替代方案的维度。考虑以下因素:性能、向后兼容性、更改发生的位置等等。

  • 建议的解决方案 - 详细说明所选的替代方案以及为什么它在所考虑的维度上是最好的。建议的解决方案部分应涵盖补丁的各个方面,以便审查者在查看代码时不会感到意外。

  • 补丁 - 请参阅下面的 补丁评估

  • 性能 - 票证是否包含足够的性能考虑?如果需要基准,请包含基准以及之前/之后的计时。如果包含这些数据,请在自己的机器上验证它们。

  • 建议部分是否完全解释了后续审查者将在补丁中看到的全部内容?

  • 补丁 - 是否列出了建议的补丁的名称?(这看起来很明显...直到它不是,所以始终显式列出它,即使它只是唯一的补丁)

需要查看的票证

补丁评估

要应用某人的更改,最好创建一个分支并在那里应用更改

$ git checkout -b freds_fixbug42
$ git am --keep-cr --ignore-whitespace < their-patch-file.patch
  • --keep-cr 在被修补的文件包含 DOS CR/LF 行结尾时很有帮助。它在不需要时似乎是无害的,但如果怀疑它会导致问题,请将其关闭或使用 --no-keep-cr。

  • --ignore-whitespace 在自补丁创建以来 master 中唯一的更改是上下文行中的空格时很有帮助。没有这个选项,一些补丁将无法应用。有了这个选项,筛选者可以帮助避免让贡献者仅仅因为 master 中的一些空格发生变化而更新补丁。

  • 如果您遵循此流程以最终确定 contrib 库的贡献,请改用

$ git am --keep-cr -s --ignore-whitespace < their-patch-file.patch

其中 -s 表示您在提交上签字。这对于筛选来说是不必要的。

补丁评估清单

  • 它是一个 .patch 文件(不是 .diff 文件)吗?

  • 补丁作者是 贡献者 吗?如果不是,我们无法考虑该补丁。

  • 补丁是否有良好的提交评论?应该采用“CLJ-1234 - 描述”的形式,其中描述应以问题为中心。如果包含有关解决方案的更多详细信息,它应该在标题行之后。一般来说,我们依赖于 jira 作为放置所有这些详细信息的地方,而不是提交评论,但这些也可以(假设它们是正确的!)。

  • 使用 git apply 在本地应用补丁(是否有任何空格警告?不一定是件大事,但请考虑一下)

  • 运行 mvn clean test - 所有测试都应该通过

  • 补丁是否包含它可以/应该包含的测试?

  • 默认情况下,测试代码使用直接链接编译。如果更改可能在没有直接链接的情况下出现问题,也请运行 mvn -Ptest-no-direct clean test

  • 测试是否过多了(引入了对实现细节的依赖)?

  • 如果有新的命名空间(在 src 或 test 中),可能需要将它们添加到编译列表中 - 更新 build.xml

  • 对现有核心宏的更改不应该调用新的函数(这会给在较旧的运行时上运行的较新编译代码带来兼容性问题)

  • 对现有核心宏的更改可能会影响规范 - 如果是这样,应该考虑这一点,并且可能需要一个单独的 core.specs 修补程序。

  • 任何涉及 Java 交互的更改都应检查 Java 反射(通常建议在任何具有交互的 Clojure 命名空间的顶部添加 (set! warn-on-reflection true))。

  • 任何新的公共函数都应具有 :added 元数据。

  • 返回原始重现并重新运行它,并应用修补程序 - 修补程序是否解决了问题?

  • 阅读差异,无论是隔离的还是应用的。验证它是否与建议的解决方案匹配。如果有任何令人惊讶和新的东西,则应更新票证或修补程序。

  • 修补程序是否与周围代码和 编码指南 的样式匹配?(这些是指南,而不是宇宙的固定规律。)

  • 文档是否仍然正确?

  • 在正文中具有类型提示的内联函数也需要在内联函数中添加一些内容。