$ git clone git://github.com/clojure/clojure.git
$ cd clojure
如果您有兴趣提供补丁或为 Clojure 贡献代码,请参阅开发概述.
如果您在开始编写代码之前考虑以下事项,您将能够开发出更容易评估且更有可能被接受的补丁。
您试图解决什么问题?在您进行任何补丁之前,您应该有一个问题陈述,并且该问题陈述应该包含在补丁的描述中。
您的解决方案方法是什么?请在描述中明确说明,以便不用从代码中推断出来。
您是否与社区验证了您的想法?如果您能的话,请在 Slack 或邮件列表中与核心团队成员讨论。(对于一些内容,例如拼写错误,则无需这样做。)
列出您考虑过的替代方案,以及它们的权衡。描述为什么您选择的解决方案是最佳选择。
您将如何向其他人证明您的补丁有效?计划包含测试。基于示例的测试是可以的,但首选生成式测试。
在工单中记录补丁中的更改。任何可以帮助筛选者了解您所做的更改及其原因的信息,都会使他们的工作更容易。
不要做太多!提交解决特定问题的较小补丁,不要添加任何额外内容,即使(特别是!)“清理”附近代码。这只会使补丁的目的变得模糊。
随着评论的增加,请保持描述的最新状态。通过阅读评论线程来重建工单的当前状态非常耗时。
争取支持。投票很好,来自其他用户对工单的评论更好。
随着工单的增长,请确保您清楚地记录哪些补丁是活动的。不要通过删除旧补丁来做到这一点,只需在评论中按名称引用补丁即可。
当您准备好编写代码时,您首先需要克隆 Clojure 或相应的存储库。以下示例适用于 Clojure 项目,用于向 Clojure 本身提交补丁。
$ git clone git://github.com/clojure/clojure.git
$ cd clojure
接下来,为自己创建一个新分支
$ git checkout -b fixbug42
Switched to a new branch "fixbug42"
现在您准备好开始编码了。在开始工作之前,请确保所有现有的回归测试都仍然通过,例如:对于 Clojure,使用 Maven
$ mvn clean test
...lots of output...
test:
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:26 min
[INFO] Finished at: 2018-12-05T14:36:54-06:00
[INFO] ------------------------------------------------------------------------
完成更改后,您需要提交它们。请使用以 JIRA 编号(CLJ-xyz)开头的提交消息,并包含关于更改所服务的解决的问题或增强功能的陈述!
$ git commit -a -m "CLJ-932 fixed annoying bug"
Created commit 8f7c712: fixed annoying bug
1 files changed, 0 insertions(+), 1 deletions(-)
现在您已经完成了更改,是时候将它们合并到补丁中了。您需要更新存储库并修复您遇到的任何冲突。
$ git checkout master
Switched to branch "master"
$ git pull
...
$ git checkout fixbug42
Switched to branch "fixbug42"
$ git rebase master
修复完任何冲突后,您就可以创建补丁了
$ git format-patch master --stdout -U8 > clj-932-1.patch
现在您可以将该补丁文件附加到 JIRA 工单。在页面顶部的“更多操作”菜单中,选择“附加文件”。在撰写有关您附加的补丁的评论时,请阅读并遵循以下建议。筛选者在筛选时时间有限。如果您能尽可能清楚地说明,并尽可能提高他们的工作效率,您的补丁更有可能被批准。
请使用 .patch 或 .diff(而不是 .txt)作为补丁文件的扩展名。
在附加补丁文件之前,请阅读它。如果您看到与您修改的代码部分无关的空白更改,请编辑并删除这些更改,然后重新生成补丁。此外,虽然在开发过程中进行多个连续的提交并在每个提交中添加说明是很好的,但补丁审核者通常更喜欢将所有更改压缩到一个提交中进行审核。
使用“git add --patch”来暂存您的更改将更容易避免提交无关的更改。
请使用与工单上所有现有附件不同的名称。JIRA 允许您添加具有相同名称的多个附件,但后面的附件不会替换前面的附件。这会导致在按名称引用补丁时产生混淆。
在任何引用补丁的评论中,包含补丁的文件名和日期。可以通过日期和时间匹配评论和补丁,但这样做既繁琐又容易出错。
为了在每次工单更新时收到电子邮件,请点击页面右上角的“关注”一词。这可以帮助您了解何时有人评论您的补丁或创建新的补丁等。如果您想停止接收有关工单的更新电子邮件,请点击“正在关注”。您可能需要验证自动电子邮件是否通过您的垃圾邮件过滤器。电子邮件将发送到与您的 JIRA 帐户关联的地址,并将来自地址[email protected].
如果您创建了一个包含一个或多个先前补丁的新补丁,请将它们全部合并到一个补丁文件中,并在您的评论中说明您已经这样做了(包含您要替换的补丁的文件名和日期)。对此的唯一例外是当来自多人的重要且大部分独立的贡献(例如,一个人做了代码更改,另一个人编写了测试)并且他们都希望获得认可时。在这种情况下,一个包含多个提交的单个补丁文件是可以的。但是,我们希望避免重复修改相同代码的多个补丁。
通过编辑“补丁”字段来标记工单为已准备好筛选。点击工单页面左上角的“编辑”按钮。在下一页中找到标题“补丁”,它旁边有一个弹出菜单。从该菜单中选择“代码”或“代码和测试”,然后点击页面底部的“更新”按钮。如果您没有看到工单页面的“编辑”按钮,并且您已签署了 CA,请在开发者的电子邮件列表或 Clojurians Slack 中的 #clojure-dev 频道中要求获得编辑 Jira 工单的权限。
要删除补丁(例如,因为它不再相关),请转到工单页面,并查找“描述”文本下面的“附件”标题。最右边有一个加号和一个三角形。点击三角形,然后从菜单中选择“管理附件”。仔细考虑要删除哪一个,然后点击它旁边的垃圾桶图标。注意:大多数人有权删除自己的附件,但不能删除其他人添加的附件。
一般来说,您不需要删除旧的补丁。让它们累积,并在工单描述中跟踪最相关的补丁。
过时的补丁是指曾经可以干净地应用到最新 Clojure 主分支版本上的补丁,但由于自补丁创建以来提交的更改,它不再适用。特别是,以下命令的输出
$ git am --keep-cr -s --ignore-whitespace < patch_file.patch
包含“补丁失败”和“要恢复原始分支并停止打补丁,请运行“git am --abort”。您应该执行“git am --abort”以摆脱上述命令留下的失败补丁尝试状态。
“git am”非常“脆弱”,这意味着如果补丁文件是用一个版本的源代码创建的,那么即使补丁文件中的任何上下文行发生更改,该命令都会失败,即使它不是补丁正在更改的行之一。这对于包含单元测试的文件尤其常见,因为人们通常在这样的文件的末尾添加新的测试,因此如果两个不同的补丁在同一个文件的末尾添加新的测试,那么新测试之前的上下文行就会发生更改。
要应用这样的补丁,请使用 --reject 标志
$ git apply --reject patch_file.patch
输出将为您提供一些提示,说明补丁文件的每个“块”是否成功或失败。如果它们都成功,那么补丁文件可能唯一的问题是几个上下文行发生了更改。如果任何块失败,补丁会创建以“.rej”结尾的文件,其中包含未应用的拒绝块,您可以将注意力集中在这些块上,因为这些块可能是源代码发生更显着更改的地方。类似这样的命令将找到所有这些文件
$ find . -name '*.rej'
您需要查看这些拒绝块,可能需要思考一下它们,看看它们是否以及如何仍然适用,并通过手动编辑源代码来应用它们。
当使用以下命令创建新的 git 补丁时
$ git format-patch master --stdout -U8 > patch_file.patch
它将您的姓名和当前日期放在文件的顶部附近。如果您所做的唯一更改是在上下文行中,请保留原始作者的署名,方法是从您开始使用的原始补丁中复制姓名和日期,然后上传该补丁。
如果您编写了原始补丁中没有的单元测试,但没有对原始补丁进行其他修改,并且您希望在提交日志中为您的工作署名,请创建一个包含测试添加的单独补丁,并用您的姓名署名,将原始作者的姓名保留在更新的补丁中。
如果您是筛选补丁的筛选者,您可以创建一个新分支并将补丁应用到该分支以开始使用它
$ git checkout -b testxyz
$ git am --keep-cr -s --ignore-whitespace < patch_file.patch
当您完成时,可以丢弃该分支
$ git checkout master
$ git branch -D testxyz
$ mvn clean test
要将伪随机生成的生成式测试的持续时间从 60 秒缩短到 1 秒(例如),请编辑文件 src/script/run_test_generative.clj 并更改 60000 编号。只需小心不要将此类更改包含在您提交的任何补丁中。(该文件在 Clojure 1.6.0 及更早版本中被称为 src/scripts/run_tests.clj)
首先,构建最新的 Clojure,但不运行任何测试
$ mvn -Dmaven.test.skip=true clean package
# If no compilation errors, mvn command above creates target/clojure-VERSION-master-SNAPSHOT.jar
上面的命令构建了 Clojure jar 文件,但既不编译也不运行测试。
创建一个 deps.edn 文件来描述您可能需要的依赖项
{:paths ["test"]
:deps
{org.clojure/clojure {:mvn/version "RELEASE"}
org.clojure/test.check {:mvn/version "0.9.0"}
org.clojure/test.generative {:mvn/version "0.5.2"}}
:aliases
{:dbg {:classpath-overrides {org.clojure/clojure "target/classes"}
:extra-deps {criterium/criterium {:mvn/version "0.4.4"}}}}}
使用 clj 启动 repl,并从中运行单个测试
$ clj -A:dbg
Clojure ...
;; We're testing with clojure.test
=> (require 'clojure.test)
nil
;; Load a test file
user=> (require 'clojure.test-clojure.data)
nil
;; Run it
user=> (clojure.test/run-tests 'clojure.test-clojure.data)
Testing clojure.test-clojure.data
Ran 1 tests containing 17 assertions.
0 failures, 0 errors.
{:type :summary, :pass 17, :test 1, :error 0, :fail 0}
启动 repl 并从其中运行生成式测试
生成式测试使用额外的测试 jar 包(在您运行 ./antsetup.sh 时安装)。因此,您需要一些额外的类路径,antsetup.sh 将将其保留在 maven-classpath 文件中。如果您使用的是 *nix,那么最简单的利用此文件的方法是
$ clj -A:dbg
Clojure ...
;; Install some clojure.test extensions
user=> (require 'clojure.test-helper)
nil
;; Load a test file that uses test.generative
user=> (require 'clojure.test-clojure.reader)
nil
;; Load the test.generative runner ns
user=> (use 'clojure.test.generative.runner)
nil
;; Test a specification on 1 thread for 200 ms
user=> (run 1 200 #'clojure.test-clojure.reader/types-that-should-roundtrip)
{:iter 60, :seed 1255541066, :test clojure.test-clojure.reader/types-that-should-roundtrip}
nil
默认情况下,Clojure 是使用启用直接链接的方式构建的。虽然这提高了性能,但它意味着如果一个函数 A 调用另一个函数 B,两者都在 Clojure 中,那么使用 spec 来检测 B 将会导致 A 仍然调用原始函数 B,而不是检测到的版本。如果您希望检测 B 并让 Clojure 中的其他函数调用检测到的版本,一种方法是不启用直接链接来构建 Clojure。
编辑文件 build.xml,在以下行中将“true”替换为“false”,该行位于以“target name="compile-clojure"”开头的部分。
<sysproperty key="clojure.compiler.direct-linking" value="true"/>
然后使用您喜欢的从源代码构建 Clojure 的方法,例如:
$ mvn -Dmaven.test.skip=true clean install