Contrib 库的自述文件应该包含以下内容
将库作为依赖项包含在 Maven / Leiningen 中的说明
指向库在 Jenkins 和 JIRA 上页面的链接
指向 Maven Central 和 oss.sonatype.org 上可用版本的链接
指向生成的 API 文档的链接(如果适用)
一般使用说明(应提及要使用/要求哪个命名空间)
开发者信息:指向 GitHub 项目、Bug 追踪器、持续集成、兼容性测试矩阵的链接
所有版本的变更日志(也可以在单独的文件中)
如果您是 Clojure Contrib 贡献者,您应该做以下事情
维护您的库并响应出现的任何问题/疑问
在主分支上完成您的工作,或者(如果您正在处理一个您想暂时分开的大块工作)在您自己创建的特定于功能的分支上工作
使用 GitHub 的“按需发布”操作来进行发布
在更改其他贡献者的库之前与其他贡献者协调
仅当其他人 签署了 CA 时才接受他们的贡献
需要避免的事项
请不要推送到发布分支(名称如 1.2.x)
不要接受非贡献者的补丁
请不要接受来自贡献者的拉取请求。仅接受补丁。
不要更改 pom.xml 中的版本号 - 使用上面提到的 Maven 发布流程
以下是成为贡献者的流程概述
将您的 CA 归档
加入 clojure-dev 邮件列表
创建 JIRA 账户
让 Clojure 核心团队知道您的 GitHub 用户名和 JIRA 用户名,以便他们可以设置正确的权限
Clojure 核心团队还需要在 build.clojure.org 上创建您的账户 - 请参见下文
将现有项目移入 contrib
所有过去的贡献者必须
提交 Clojure 贡献者协议
向 clojure-dev 邮件列表发送一封电子邮件,授予许可,例如:"我,(NAME),授权根据 Clojure 贡献者协议发布我对 (PROJECT) 的贡献。"
设置新的 contrib 项目
向 clojure-dev 邮件列表发送电子邮件,以获得新项目的批准以及 GitHub、Jira 和 Jenkins 中的管理员权限。
在 clojure 组织 下请求一个新的 GitHub 仓库
指定项目名称(必须经 Clojure 核心批准)
指定描述
合作者 - 添加团队:Contrib 贡献者,其中包括
clojure-build - 用于 Jenkins 标记版本、构建自动文档等
禁用问题选项卡(我们使用 JIRA 代替)
项目结构(请参阅现有项目以获取示例)
/README.md - 自述文件,请参见上文
/CHANGES.md - 变更日志
/CONTRIBUTING.md - 示例
/epl.html - EPL 许可证信息
/pom.xml - 按照 build.poms 说明 - 用于构建/部署
/src/main/clojure - Clojure 源代码
/src/test/clojure - Clojure 测试
/src/main/cljs - ClojureScript 源代码
/src/test/cljs - ClojureScript 测试
/src/main/java - Java 源代码(如果需要)
创建一个新的 JIRA 项目(需要 JIRA 管理员权限)
指定名称(与 GitHub 项目名称相同)
指定键(由 Clojure 核心批准,从项目名称派生) - 通常应该由第一部分的首字母和第二部分最多 5 个字符组成 - TBENCH、DJSON 等。
指定项目负责人的 JIRA 账户
编辑项目以添加 URL 和描述(与 GitHub 项目相同)
设置通知方案 - 通常为 "默认方案加通知项目负责人"
设置构建(需要 Jenkins 管理员权限,但步骤 2 除外)
为作者创建 Jenkins 用户账户
编辑 build.ci 仓库中的 ci_data.clj 文件,添加新项目 / 更新作者(以便他们可以运行构建 / 发布版本)
在 clojure-dev 邮件列表上请求运行 build.ci Jenkins 作业 - 这将重新创建所有 Jenkins 作业定义文件!
强制 Jenkins 重新加载其配置文件
自动文档
进行中
执行发布
每次作业构建时(由任何源代码更改触发)都会自动创建快照版本
要使用快照版本,请参阅 Maven 设置和仓库
按照下面的“如何进行发布”部分中的说明进行发布
准备工作
您的项目必须有一个 pom.xml 文件,其中包含 -SNAPSHOT 版本
pom.xml 文件必须指定一个父级,即 pom.contrib 的最新发布版本,位于 build.poms 中
如何进行 -SNAPSHOT 发布
您的项目必须有一个 pom.xml 文件,其中包含 -SNAPSHOT 版本
推送到 GitHub 的 "master" 分支
Jenkins 会轮询 GitHub 并自动构建
或者您也可以在项目页面上点击 "立即构建"
Jenkins 会构建并上传一个唯一编号的 JAR 文件到 Sonatype OSS 快照仓库
如何进行编号发布
GitHub 中的 "master" 分支必须有一个 pom.xml 文件,其中包含 -SNAPSHOT 版本,而不是一个裸的版本号
登录 Jenkins
导航到您的项目的作业
点击左侧的 "执行 Maven 发布" 链接
在 "执行 Maven 发布" 页面上
选择 "为所有模块指定一个版本"
在 "发布版本" 字段中,输入该版本的项目版本号
这通常是当前开发版本,删除了 "-SNAPSHOT" 后缀
在 "开发版本" 字段中,输入项目后续开发版本的版本号
这将以 "-SNAPSHOT" 结尾
点击 "计划 Maven 发布构建"
构建成功完成后
在您的开发机器上执行 git pull
以获取新的发布标签
发布的 JAR 文件将上传到 Sonatype OSS 暂存仓库
发布将在 24 小时内(通常在 15 分钟内)自动复制到 Maven Central 仓库
不要忘记更新项目的自述文件,如果它向用户推荐了一个版本。
Contrib 版本编号策略
主版本.次版本.修订版本
尽可能遵循累积和固定的原则,而不是破坏性的原则
免责声明
规则是为了打破而制定的。了解标准,但不要将它们视为绝对真理。
标准
确保名称和签名正确。Rich 深刻尊重 Java 对不破坏现有代码的承诺。在实践中,这意味着我们可以永远调整实现,但一旦我们发布了一个名称和签名,我们就需要坚持使用它。(在实践中我认为这意味着我们希望许多人审查名称和签名,即使他们没有审查实现细节。)
对可能在关键代码中的函数使用类型提示;否则保持代码简单,不使用提示。
只使用有意义的类型提示。如果您不确定类型提示是否有帮助,请不要添加它。
使用良好的名称,不要害怕与其他命名空间中的名称冲突。这就是灵活的命名空间支持存在的意义。
另一方面,使用相同的名称但具有不同的签名或语义,就让人怀疑其中一个是否不够理想。
明确且最小化地依赖其他包。(优先使用 :require :refer 而不是 :use)
如果函数可以完成任务,请不要使用宏。如果宏对于易用性很重要,也请公开函数版本。
如果您确定在编译时拥有所有信息,请在可以提高性能敏感代码的情况下使用宏。
提供库级文档字符串。
提供自动测试。
对谓词使用 '?' 后缀,并返回布尔值。
对解构目标和将被当前代码忽略其值的正式参数名使用 '_'。
包含文档字符串。
如有疑问,请公开高性能版本。Clojure 做出了巨大的努力,以便在您需要时能够实现性能,库也应该如此。(这就是为什么我们在核心代码中没有多方法 + 的原因,例如)。用户始终可以在自己的代码中创建更多多态 API,如果他们愿意,可以劫持符号。
如果您使用了一个与核心代码冲突的良好名称,请确保您的语义是平行的(可能不包括惰性)。字符串函数的良好示例,它们与核心代码的 seq 函数冲突。
使用 assert 以及前置条件和后置条件。
尽可能使用惰性。
遵循 clojure.core 的示例,使用诸如 pred 和 coll 之类的惯用名称。
在函数中
f、g、h - 函数输入
n - 整数输入,通常是一个大小
index - 整数索引
x、y - 数字
s - 字符串输入
coll - 集合
pred - 谓词闭包
&更多 - 可变参数输入
在宏中
expr - 表达式
body - 宏体
binding - 宏绑定向量
不要遵循 clojure.core 的序言代码中的惯例。该代码在有限的环境中运行,因为 Clojure 尚未启动。
分解组件。如果您不是 Rich,请不要编写与 doseq 的定义一样长的形式。
使用关键字优先语法访问对象上的属性:(:property object-like-map)
使用集合优先语法从集合中提取值(或者如果集合可能为 nil,则使用 get):(collection-like-map key)
或 (get collection-like-map key)
。请注意,并非所有集合都以关键字为键。
惯用代码大量使用解构。但是,只有当您想将子结构作为调用者契约的一部分进行传达时,才应该在参数列表中进行解构。否则,请在第一行的 let 中进行解构。
优先使用更新而不是设置。原因很多:统一的更新模型提供了一种简单标准的方式来执行此操作。帮助您发现可交换操作。减少了您对要更新的对象所做的假设的范围。
不要在错误的集合类型上进行操作。如果您的算法仅在随机访问的情况下有效,则需要一个具有随机访问权限的参数。
仅将 *earmuffs* 用于旨在重新绑定的内容。不要使用特殊符号表示常量;除非另有说明,否则所有内容都被认为是常量。
仅将感叹号用于在 STM 事务中不安全的项目。
优先使用序列库组合而不是显式循环/递归。
可重新绑定的变量应与作用域宏配对,例如 in 和 with-in-str。
延迟序列应公开为仅保存最少状态的函数,即“放下头”。让调用者决定要使用多少本地内存。
使用 Klass/staticField、(Klass/staticMethod)、(Klass.) 和 (.method obj) 交互样式,唯一的例外是在代码生成代码中,其中较旧的 (. obj method) 样式可能更容易生成。
如果您提供一个通过动态绑定隐式传递参数的接口(例如 sql 中的 db),也提供一个相同的接口,但参数显式传递。
在为 cond 提供默认情况时,使用关键字 :else 作为条件而不是 true。
要访问私有变量(例如用于测试),请使用 @#'some.ns/var 形式。
协议
只有当您拥有类型或协议时,才能将协议扩展到类型。
如果违反了前面的规则,则应准备好撤回,如果实现者提供定义,则应做好准备。
如果协议随 Clojure 自身提供,请避免将其扩展到您不拥有的类型,尤其是例如 java.lang.String 和其他核心 Java 接口。请放心,如果协议应该扩展到它,它就会扩展,否则请游说它。
正如 Rich Hickey 所说,其动机是防止“人们将协议扩展到对它们没有意义的类型,例如,协议作者考虑过但拒绝了实现,因为语义不匹配”。“不会有任何扩展(通过设计),并且缺乏足够理解/技能的人可能会用错误的想法填补空白。”