Cake和Leiningen有何区别?
Cake和Leiningen有何区别?
这个答案继续得到兴趣,大概作为在StackOverflow的Leiningen参考,所以现在已经大大的编辑,以更新它2014年。
Leiningen和Cake于2011年合并.Leiningen(第2版)现在是事实上的Clojure自动化工具。
Leiningen是一个Clojure的构build工具和依赖pipe理器,它包含了设置一个交互式REPL的能力,它具有适当configuration的类path,以及从maven仓库和/或基于社区的Clojars自动获取的所有java和clojure依赖关系。
Cake与Leiningen非常相似(当时使用相同的project.clj文件格式),但试图通过在后台保留持久JVM来避免大量启动开销。 这种响应更具响应性,但是由于迭代REPL开发的典型过程中的持久性进程(旧函数定义悬而未决)中的累积状态而导致错误方便。 结果这是一个糟糕的交易。
Leiningen的经验以及对更快启动时间的持续渴望已经导致了一些加快速度的build议和方法: https : //github.com/technomancy/leiningen/wiki/Faster
主要区别在于执行任务的方式。
Cake的方法是“定义之后很难扩展function,所以让我们发明一个新的机制来完成任务,而不是使用函数”,这就产生了一个灵巧的macros。
Leiningen的方法是“定义后很难扩展function,所以我们应该设法做到这一点,这样我们就可以使用function来完成任务,也可以扩展非任务的function”让您将所有function的可组合性优势与任务结合在一起。
正如亚历克斯所说,最显着的区别是命令行的速度。 Cake使用一个持久的JVM,所以当你第一次在你的项目中运行一个任务时,你只会遇到jvm的启动开销。 如果你不使用emacs + slime + clojure-test-mode,这可能是一个巨大的节省时间。 例如,在我的一个项目中,一个相当大的testing集在0.3秒内运行,而在11.2秒内运行。
除了performance之外,蛋糕背后的核心思想是依赖任务模型。 每个任务只在给定的构build中运行一次,同时考虑依赖关系图中的所有传递先决条件。 下面是Martin Fowler关于 Cake语法中rake的文章的一个例子,直接在你的project.clj中。
(deftask code-gen "This task generates code. It has no dependencies." (println "generating code...") ...) (deftask compile #{code-gen} "This task does the compilation. It depends on code-gen." (println "compiling...") ...) (deftask data-load #{code-gen} "This task loads the test data. It depends on code-gen." (println "loading test data...") ...) (deftask test #{compile data-load} "This task runs the tests. It depends on compile and data-load." (println "running tests...") ...)
要在Leiningen中执行相同的操作,首先必须在项目中创build一个包含4个文件的leiningen目录:code_gen.clj,compile.clj,data_load.clj和my_test.clj。
SRC / leiningen / code_gen.clj
(ns leiningen.code-gen "This task generates code. It has no dependencies.") (defn code-gen [] (println "generating code..."))
SRC / leiningen / my_compile.clj
(ns leiningen.my-compile "This task does the compilation. It depends on code-gen." (:use [leiningen.code-gen])) (defn my-compile [] (code-gen) (println "compiling..."))
SRC / leiningen / data_load.clj
(ns leiningen.data-load "This task loads the test data. It depends on code-gen." (:use [leiningen.code-gen])) (defn data-load [] (code-gen) (println "loading test data..."))
SRC / leiningen / my_test.clj
(ns leiningen.my-test "This task runs the tests. It depends on compile and data-load." (:use [leiningen.my-compile] [leiningen.data-load])) (defn my-test [] (my-compile) (data-load) (println "running tests..."))
人们会期待…
generating code... compiling... loading test data... running tests...
但是数据加载和我的编译都依赖于代码,所以你的实际输出是…
generating code... compiling... generating code... loading test data... running tests...
你将不得不记忆代码,以防止它被多次运行:
(ns leiningen.code-gen "This task generates code. It has no dependencies.") (def code-gen (memoize (fn [] (println "generating code..."))))
输出:
generating code... compiling... loading test data... running tests...
这是我们想要的。
如果任务只在每个构build中运行一次,则构build更简单和更高效,因此我们将其设置为构build蛋糕的默认行为。 这个哲学已经有几十年的历史,并且被构build工具的谱系所共享。 你仍然可以使用function,你仍然可以反复地打电话给你,而且你总是可以随意使用function。
Lein只是给你一个简单的函数作为一个任务,但是增加了一个约束,它必须在src中有它自己的命名空间。 如果一个任务依赖于它,它将在一个单独的命名空间中,并且必须在它的ns
macros中使用/要求另一个。 蛋糕的构build看起来更加整洁和简洁。
另一个关键的区别是如何追加任务。 比方说,我们想添加my-test
作为蛋糕/ lein的内置jar
任务的先决条件。 在cake中,你可以使用deftask
macros来追加到任务的窗体和依赖项。
(deftask jar #{my-test})
Lein使用Robert Hooke来追加任务。 这是一个非常酷的图书馆,以每个人最喜欢的自然deftask
名字命名,但它需要一个macros观的简洁性的deftask
。
(add-hook #'leiningen.jar/jar (fn [f & args] (my-test) (apply f args)))
蛋糕也有一个全球项目的概念。 您可以将用户特定的开发依赖关系(如~/.cake/project.clj
添加到~/.cake/project.clj
并将其~/.cake/project.clj
所有项目。 全球项目也被用来启动一个项目以外的实验。 Lein通过支持~/.lein/init.clj
每个用户configuration以及~/.lein/init.clj
plugins中的全局插件来实现类似的function。 总的来说,Lein目前比Cake的插件生态系统更加丰富,但Cake包含了更多的任务(war,deploy,java编译,native依赖,clojars和swank)。 Cljr也许值得一试,它本质上只是一个包pipe理器的全球项目,但没有构buildfunction(但我没有经验)。
正如技术人员指出的那样,真正的不可分割的区别是任务定义。 在我的(有偏见的)意见中,蛋糕处理任务要好得多。 当我们开始在lein项目中使用协议缓冲区时,对任务依赖模型的需求变得明显。 Protobufs是我们所有任务的先决条件,但编译起来却非常慢。 我们也有很多相互依赖的任务,所以任何构build都是痛苦的。 我也不喜欢单独命名空间的需求,因此对于我创build的每个任务都需要额外的src文件。 开发人员应该创造很多任务,Lein的做法是通过创造太多的摩擦来阻止这种做法。 用蛋糕,你可以在project.clj中使用deftaskmacros。
蛋糕还很年轻,还在进行中,但这是一个非常活跃的项目。
2011-11-15, 蛋糕和莱恩合并的公告