【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

使用 Clojars 与 Leiningen 自动管理 Clojure 类库及依赖

  • 2009-11-30
  • 本文字数:3378 字

    阅读完需:约 11 分钟

类库的使用是小菜一碟,但让系统使用正确的类库却远非易事。很多语言都通过仓库来解决该问题,其中仓库托管了类库、元数据以及工具,人们可以通过这种方式轻松从仓库中获取正确版本的类库。Ruby 世界的解决方案就是 Ruby Gems,它既是一个工具同时也是一个打包格式;托管于 Rubyforge( Gems 将于不久之后迁移到 GemCutter 系统上,因为后者提供了更好的灵活性)的默认仓库使得发布与使用 Gems 变得异常简单。而在 Java 世界中, Maven则是一个流行的解决方案。

新仓库 Clojars 旨在简化 Clojure 类库的共享与使用。 Leiningen 是由 Phil Hagelberg 创建的用于 Clojure 的构建工具,其目的在于让开发者能够轻松将 Clojure 类库发布到 Clojars 上,同时使用者也可以拿来就用且保证是其 Clojure 程序所需的。

InfoQ 有幸采访到了 Clojars 的创建者 Alex Osborne 以了解 Clojars 背后的动机、实现及工具等相关信息。

InfoQ:Clojars 是如何使用 Maven 的?如果从 Clojars 上安装了某些东西,我最终得到的是什么,类库的 Maven 安装抑或是其他什么东西?

Clojars 本身仅仅只是个仓库而已,其使用 Maven 的唯一目的就是将 jar 包和元数据放到结构中,这也是大多数构建工具的做法。所谓“安装”某些东西其实指的就是所有一切都完全依赖于构建工具。如果使用 Leiningen 或是 Maven 的话,我们将需要安装一个本地 Maven 仓库。Leingingen 仅仅把本地 Maven 仓库看作是一个缓存并将所有依赖复制到项目中名为“lib”的目录下,这样其他工具如 swank-clojure 就能找到他们了。这也意味着用户只需设定 classpath 即可而无需任何其他工具,可以这样做:```

java -cp ‘src:classes:lib/*’ myproject.main

复制代码
我非常推崇 Ruby Gems 能够安装可执行文件的做法,这样用户就可以从命令行执行了(比如说”rails“和”rake“)。我觉得我们也应该采取类似的方式,但目前还没有具体的计划。不过现在 Leiningen 插件已经在朝这个方向努力了。

InfoQ:如果我想往 Clojars 上增加一个类库,那需要创建哪些元数据呢,最好的处理方式是什么?

Clojars 仅仅需要一个最简单的 Maven 风格的 pom.xml 文件即可。至少需要指定 artifactId、groupId、version 及 dependencies,同时最好添上一些元数据字段,如 description、url 和 license 以便 Clojars 站点能够索引并搜索到他们,但我不打算强制用户这么去做。目前搜索功能还是非常基本的,然而我希望能够对其进行改进并为 Leiningen 增加一个搜索命令,这样用户甚至都不需要离开终端就能完成这一切。 POM 语法本身是非常单调乏味的,到处都充斥着 XML 命名空间和 schema,如果不打算通过 IDE 插件来生成该文件的话,我建议你使用 Leiningen 格式,如下所示:

复制代码
(defproject myproject "0.1.0"
:description "An example project."
:dependencies [[org.clojure/clojure "1.1.0-alpha-SNAPSHOT"]
[org.clojure/clojure-contrib "1.0-SNAPSHOT"]
[compojure "0.3.1"]])

可以通过如下命令让 Leiningen 导出 POM:```

lein pom

复制代码
然后通过如下命令将其添加到 Clojars 上:```
scp pom.xml myproject-0.1.0.jar clojars@clojars.org:

lein-clojars 插件可以将这两个命令简化为”lein push“这一条命令,但正如你所见,实际上并非所有东西都能够简化。:-) 有时我会通过“lein pom”命令为 Java 项目创建 POM 模板。你可以使用 Maven 的方式实现这一点,但我却记不住那么多的命令。

InfoQ:你想对那些常常陷入 Maven 梦魇的人们说些什么呢?

哈哈,肯定不止你一个人受此折磨。简单项目的构建就应该简单一些,我希望 Clojars 和 Leiningen 能够百尺竿头,更进一步,让你睡个好觉。

InfoQ:听说你正在用一个名叫 Compojure 的 Clojure Web 框架为 Clojars 构建 Web 前端,感觉 Compojure 怎么样?

我已经习惯于使用 Sinatra 和 Haml 并搭配 Ruby,因此 Compojure 是个很自然的选择。到目前为止,我觉得它很不错。我是一个“最小化工具”的狂热分子,只希望这些工具能恰到好处地简化日常开发而不会变得过于复杂和难于操控。

InfoQ:Clojars 托管在何处?仓库在哪里?

目前,它都放在一个小型的 Linode.com VPS 上,仓库也仅仅是磁盘上的普通文件而已(通过 lighttpd 向外提供服务)。Web 部分运行在 Jetty 中并使用 SQLite 数据库存储元数据,同时执行搜索等功能。对于类库的增添来说,我使用 Nailgun 通过 SSH 连接到运行着的应用。我用 Clojure 实现了一个 scp 服务器(它真的只是一个很简单的协议),它会检查上传的 POM 和 jar 的正确性以及是否通过 Maven 部署到仓库中。如果仓库变得足够大,我可能会将实际的 jar 文件迁移到 Amazon S3 上,但不打算对网站和元数据进行升级。

InfoQ:你提到 Clojars 类似于 Gemcutter;那你是如何处理诸如保存类库名、forking 等事情的?难道仅仅是先来先得么?

这个问题不好回答,我已经就该问题思考很长时间了,但尚未得到完美的答案。幸运的是,与 Gems 不同,POM 已经具备了命名空间机制(groupId),因此可供我们选择的也更多了。 我发现对于 Maven 来说,很多时候 groupId 都很碍事。我仅仅想用官方版本的“compojure”却并不关心其作者是谁,托管在何处。你经常会看到 Maven 类库的版本增加到 0.3 时可能还一直托管在 GitHub 上,因此会有形如“com.github.weavejester.compojure”的旧版本 groupId,但在他们有了新的域名后就会突然将其变为“org.compojure”。之后你会使用错误的版本,2 个月后才发现项目一直都是按照旧版本的类库开发的,这也说明了为何文档不匹配的原因所在。当然了,这么做的肯定不止我一个。

有一种事实上的标准用以规范类库的版本,那就是将 groupId 与 artifactId 设为相同的值。Phil Hagelberg 决定为 Leiningen 采取这种方式,因此在提到“compojure”时实际上说的是“compojure/compojure”,我也对 Clojars 采取了这种方式。我知道 Maven 的拥护者可能不赞成这个观点,但我觉得他们过于理想化了。 CPAN、PyPI 和 RubyGems 已经表明在实践中这并非那么重要,尤其是在你拥有中央仓库时更是如此。当然了,这只是偶尔才会出现的问题,但将域名作为命名空间会让事情变得复杂,不仅对于“类库作者”是这样,对于“类库使用者”来说更是如此。

但另一方面我有时还需要进行一些调整。或许官方版本的 Compojure 依赖于 Jetty,而我却想让其与 Server X 协同工作,但上面却不同意并拒绝了我给出的修复措施。或许我想用别人写的类库,但该类库并没有放到 Clojars 或 Maven Center 上,我不想说出他们的名字。对于这些情况来说确实需要一种命名空间机制。因此对于这类用法,我推荐在添加 jar 时将其 groupId 命名为“org.clojars.username”这种形式。我想将其命名为 username/project 而非 org.clojars.username/project,这里包含完整域名的方式其实更好。它表明了这并非官方版本并鼓励使用这种简易形式来标明官方版本。

目前在你首次添加具有特定 groupId 的 jar 时你就会成为该 jar 的唯一拥有者,其他人都无法再添加了。你可以通过网站将其他成员添加到组中。因此我们的原则就是先到先得。Clojure 社区是一个非常友好和成熟的社区,我觉得这么做不会产生什么问题,但如果有人反对这么做并且造成大家责权不分的话,我可能会帮下忙将保留的标准 group 名标注出来直到类别划分清楚为止。我觉得在问题出现时才进行处理要比中央集权的方式好一些,因为后者会浪费大家的时间并导致提交者和审批者彼此间的不信任。

InfoQ:要想与 Clojars 交互需要使用哪些工具?

我对 Phil 为 Leiningen 所做的一切感到非常满意。我对其的感觉与 Compojure 和 Sinatra 一样,它确实做到了“刚刚好”也不会妨碍你。但它也使用了 Maven 风格的仓库,因此你无需重新打包用于 Clojure 程序的所有 Java 类库。这里我向大家推荐 Leiningen,但实际上你可以将 Clojars 与任何能够从 Maven 仓库中下载的依赖工具搭配使用,大多数 Java 工具都是可以的。 对于类库的添加来说,除了 scp 以外你无需 Leiningen 或是 Maven 或是任何其他工具,事实上 scp 已经安装在每台 Unix 系统上了,很多 Windows 开发者都将其安装在了 PuTTY、MSysGit 或是 Cygwin 上。因此如果你想手动管理依赖、构建以及通过 Shell 脚本添加类库,那就去做吧。

查看英文原文: Clojars and Leiningen Automate Library and Dependency Management for Clojure

2009-11-30 21:334132
用户头像

发布了 88 篇内容, 共 258.7 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

改变

一把梭

生活 随笔

消息队列Kafka - 原理分析

Java收录阁

kafka

《我是余欢水》与《一个叫欧维的男人决定去死》

十三

思考如何节省时间,节省出时间进行思考

伯薇

思考 时间管理 思考力 工作效率 提升效率

没有了手机的诺基亚,过得远比你想象的要好

赵新龙

微软 手机 上市 诺基亚

Web3极客日报 #133

谢锐 | Frozen

区块链 技术社区 Rebase

苟富贵,勿相忘

十三

论十三

十三

为什么开源是基础软件的未来

顾钧

开源 基础软件

如何表达自己的感情?

zkh

如何成为一个靠谱的人

熊斌

个人成长 团队协作

万字破解云原生可观测性

谭建

云原生 APM 可观测性 链路追踪 Skywalking

HTTP的德性

十三

Disruptor 高效的秘密-Sequencer

Rayjun

Java 并发编程 Disruptor

张小龙 的 22 年和微信的 8 年

池建强

微信 张小龙

Web3极客日报#130

谢锐 | Frozen

区块链 创业 独立开发者 技术社区 Rebase

消息队列Kafka - 基本应用

Java收录阁

kafka

面向兴趣编程 - 一条微博和一个小程序的故事

遇见

小程序 微信小程序 副业 面向兴趣编程

程序员陪娃漫画系列——喂药

孙苏勇

程序员 生活 陪伴 漫画

OKR实践中的痛点(3):破3旧,迎3新!

大叔杨

OKR Scrum 敏捷 敏捷开发 绩效

重要:Kafka第3篇之一条消息如何被存储到Broker上

z小赵

kafka

容器日志采集利器:Filebeat深度剖析与实践

傅轶

Kubernetes 容器 云原生 日志 Filebeat

游戏夜读 | 2020周记(4.10-4.17)

game1night

为什么最该祝自己劳动节快乐

石君

劳动 劳动节 励志

Web3极客日报#131

谢锐 | Frozen

区块链 创业 独立开发者 技术社区 Rebase

我所想的跨平台开发:小程序+App+Web

曾伟@喵先森

flutter 小程序 微信小程序 跨平台

Java并发编程系列——常用并发工具类

孙苏勇

Java Java并发 并发编程 多线程

科技 vs 隐私:瘟疫下“以健康为名”会将我们推向何方?

陶乐思

Block底层原理探析

Damien

ios 源码分析

Web3极客日报 #132

谢锐 | Frozen

区块链 创业 独立开发者 技术社区 Rebase

以物理学思维破解分布式系统的本质

常平

分布式

使用Clojars与Leiningen自动管理Clojure类库及依赖_Java_Werner Schuster_InfoQ精选文章