В чем разница между Cake и Leiningen?
в чем разница между Cake и Leiningen?
4 ответа:
этот ответ продолжает вызывать интерес, предположительно, как ссылка на Leiningen в StackOverflow, поэтому теперь он значительно отредактирован, чтобы обновить его для 2014 года.
Лейнинген и торт слились еще в 2011 году. Leiningen (версия 2) теперь де-факто инструмент автоматизации Clojure.
Leiningenэто инструмент сборки и менеджер зависимостей для Clojure, который включает в себя возможность настроить интерактивный REPL с соответствующим образом настроенным classpath и со всеми зависимости java и clojure, полученные в автоматическом режиме из репозиториев maven и / или сообщества на основе Clojars.
торт был очень похож на Leiningen (вплоть до использования того же проекта.формат файла clj в то время), но попытался избежать больших накладных расходов при запуске, сохраняя постоянные JVMs в фоновом режиме. Это было более отзывчивым, но торговало удобством для ошибок из-за накопленного состояния в постоянных процессах (старые определения функций висят вокруг и т. д.) в течение типичного курса итеративной разработки на основе REPL. Это оказалось невыгодно.
опыт работы с Leiningen и постоянное стремление к более быстрому запуску привели к ряду рекомендаций и подходов для ускорения работы:https://github.com/technomancy/leiningen/wiki/Faster
основное отличие заключается в способе реализации задач.
подход Cake заключается в том, что "трудно расширить функции после их определения, поэтому давайте придумаем новый механизм для задач, а не использовать функции", что привело к макро deftask.
подход Лейнингена: "трудно расширить функции после того, как они были определены, поэтому мы должны сделать способ сделать это легко; таким образом, мы можем использовать функции для задач, а также иметь возможность расширять вещи, которые не являются задачи", которая позволяет применять все преимущества композиционности функций с задачами.
как уже упоминал Алекс, самое поразительное отличие-это скорость из командной строки. Cake использует постоянную JVM, поэтому вы сталкиваетесь с накладными расходами запуска jvm только при первом запуске задачи в вашем проекте. Если вы не используете emacs + slime + clojure-test-mode, это может быть огромная экономия времени. Например, достаточно большой набор тестов на одном из моих проектов выполняется за 0.3 секунды в cake, против 11.2 s в lein.
кроме представления, идея сердечника за тортом модель задачи зависимостей. Каждая задача выполняется только один раз в данной сборке с учетом всех транзитивных предпосылок в графе зависимостей. Вот пример из статья Мартина Фаулера о граблях в синтаксисе торта, который идет непосредственно в вашем проекте.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, вам сначала нужно будет создать каталог leiningen в вашем проекте с 4 файлами: code_gen.clj, compile.clj, data_load.clj, и мой тест.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...
но и Data-load и my-compile зависят от code-gen, поэтому ваш фактический выход...
generating code... compiling... generating code... loading test data... running tests...
вам придется запомнить код-gen, чтобы предотвратить его запуск нескольких раз:
(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...
что мы хотим.
сборки проще и эффективнее, если задача выполняется только один раз за сборку, поэтому мы сделали это поведение по умолчанию в сборках cake. Философия насчитывает десятилетия и разделяется родословной инструментов сборки. Вы все еще можете использовать функции, вы все еще можете вызывать их повторно, и у вас всегда есть полная мощность clojure в вашем распоряжении.
Lein просто дает вам простую функцию как задача, но с добавленным ограничением, что он должен иметь свое собственное пространство имен в src. Если задача зависит от него, она будет находиться в отдельном пространстве имен и должна использовать/требовать другого в нем
ns
макрос. Торт строит выглядеть гораздо аккуратнее и лаконичнее в сравнении.еще одно ключевое отличие заключается в том, как задачи добавляются. Допустим, мы хотели добавить
my-test
, как необходимое условие для торта/Лейн, построенный вjar
задач. В торт, вы можете использоватьdeftask
макрос для добавления к формам задачи и зависимости.(deftask jar #{my-test})
Лейн использует Роберта Гука для добавления к задачам. Это действительно классная библиотека, названная в честь любимого всеми естествоиспытателя, но для краткости
deftask
.(add-hook #'leiningen.jar/jar (fn [f & args] (my-test) (apply f args)))
торт также имеет понятие глобального проекта. Вы можете добавить пользовательские dev-зависимости, такие как swank, в
~/.cake/project.clj
и имеют его во всех ваших проектах. Глобальный проект также используется для запуска repl вне проекта для экспериментирование. Lein реализует аналогичные функции, поддерживая конфигурацию для каждого пользователя в~/.lein/init.clj
, и глобальные Плагины~/.lein/plugins
. В целом, Lein в настоящее время имеет гораздо более богатую экосистему плагинов, чем cake, но cake включает в себя больше задач из коробки (война, развертывание, компиляция java, собственные зависимости, clojars и swank). Cljr также может быть стоит проверить, это по сути просто глобальный проект с менеджером пакетов, но без возможностей сборки (у меня нет опыта работы с ним, однако).реальная непримиримая разница-это определения задач, как указала техномантия. По моему (предвзятому) мнению, торт справляется с задачами намного лучше. Необходимость в модели зависимости от задачи стала очевидной, когда мы начали использовать буферы протокола в нашем проекте с lein. Протобуфы были предпосылками для всех наших задач, но их компиляция очень медленная. У нас также есть много взаимозависимых задач, поэтому любая сборка была болезненной. Мне тоже не нравится требование отдельного пространства имен, и поэтому дополнительный src-файл для каждой задачи, которую я создаю. Разработчики должны создать много задач, подход Лейна препятствует этому, создавая слишком много трений. С помощью cake вы можете просто использовать макрос deftask в проекте.clj по.
торт еще молод, и работа идет, но это очень активный проект.
Как 2011-11-15, объявления торт и Лейн слияния