51 votes

Quelle est la différence entre Cake et Leiningen?

Quelle est la différence entre Cake et Leiningen?

48voto

Alex Stoddard Points 5300

Cette réponse ne cesse de prendre de l'intérêt, sans doute une référence pour les Leiningen dans StackOverflow de sorte qu'il est maintenant considérablement modifié pour le mettre à jour pour 2014.

Leiningen et Gâteau fusionné en 2011. Leiningen (version 2) est maintenant de facto Clojure outil d'automatisation.

Leiningenest un outil de construction et de la dépendance gestionnaire de Clojure qui inclut la possibilité de mettre en place un interactive REPL avec l'correctement configuré le chemin de classe et tous les produits java et clojure dépendances acquis de manière automatisée à partir de maven dépôts et/ou de la communauté en fonction de Clojars.

Le gâteau était très semblable à Leiningen (vers le bas à l'aide d'un même projet.clj format de fichier à l'époque), mais les tentatives pour éviter un lot de démarrage supplémentaire, en gardant persistante machines virtuelles autour de l'arrière-plan. Cela a été plus réactif mais négociés commodité pour les bugs en raison du cumul de l'état dans la persistance des processus (ancien définitions de fonction traîner etc.) sur le parcours typique de itératif de RÉPLICATION de base de développement. Ceci s'est avéré être une mauvaise affaire.

Expérience avec Leiningen et une poursuite de l'envie pour accélérer les temps de démarrage ont conduit à un certain nombre de recommandations et approches pour accélérer les choses: https://github.com/technomancy/leiningen/wiki/Faster

24voto

technomancy Points 2784

La principale différence est dans la façon dont les tâches sont mises en œuvre.

Gâteau de l'approche est "il est difficile d'étendre les fonctions après qu'ils ont été définis, de sorte que nous allons inventer un nouveau mécanisme pour les tâches plutôt que d'utiliser des fonctions", ce qui a entraîné la deftask macro.

Leiningen l'approche est "il est difficile d'étendre les fonctions après qu'ils ont été définis, nous devrions donc faire un moyen de le faire facilement; de cette façon, nous pouvons utiliser des fonctions pour les tâches et également être en mesure de proposer des choses qui ne sont pas des tâches", qui vous permet d'appliquer tous les composabilité avantages de fonctions avec des tâches.

20voto

lancepantz Points 205

Comme Alex mentionné, la différence la plus frappante est la vitesse à partir de la ligne de commande. Gâteau utilise une persistance de la JVM, de sorte que vous ne rencontrerez que la jvm de démarrage de charge lorsque vous exécutez une tâche au sein de votre projet pour la première fois. Si vous n'êtes pas en utilisant emacs + slime + clojure-en mode test, cela peut être un énorme gain de temps. Par exemple, un assez grand nombre de tests sur un de mes projets en 0.3 secondes gâteau, vs 11.2 s en lein.

Outre les performances, l'idée de base du gâteau est la dépendance modèle de tâche. Chaque tâche est exécuté qu'une fois dans une de construire, en tenant compte de l'ensemble transitif préalables dans le graphe de dépendance. Voici un exemple de Martin Fowler article sur râteau dans la gâteau de la syntaxe, qui va directement dans votre projet.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...")
  ...)

Faire la même chose dans Leiningen, il faut d'abord créer un leiningen-répertoire dans le répertoire de votre projet avec 4 fichiers: code_gen.clj, de la compilation.clj, data_load.clj, et 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..."))

On pourrait s'attendre...

generating code...
compiling...
loading test data...
running tests...

Mais les données de charge et de mon-compiler dépendent de code-gen, de sorte que votre sortie est...

generating code...
compiling...
generating code...
loading test data...
running tests...

Vous devez memoize code-gen pour l'empêcher d'être exécuté plusieurs fois:

(ns leiningen.code-gen
   "This task generates code. It has no dependencies.")

(def code-gen (memoize (fn []
                         (println "generating code..."))))

sortie:

generating code...
compiling...
loading test data...
running tests...

Qui est ce que nous voulons.

Versions sont plus simple et plus efficace si une tâche est seulement couru une fois par construire, de sorte que nous avons fait c'est le comportement par défaut dans le gâteau construit. La philosophie est vieux de plusieurs décennies et partagée par une lignée de construire des outils. Vous pouvez toujours utiliser des fonctions, vous pouvez toujours les appeler à plusieurs reprises, et vous avez toujours la pleine puissance de clojure à votre disposition.

Lein vous donne juste une simple fonction d'une tâche, mais avec la contrainte qu'il doit avoir son propre espace de noms de la src. Si une tâche dépend de lui, il sera dans un autre espace de noms, et que vous devez utiliser/exiger de l'autre dans ns macro. Gâteau construit l'air beaucoup plus propre et concis dans la comparaison.

Une autre différence importante est la façon dont les tâches sont ajoutées. Imaginons que nous voulions ajouter my-test comme condition préalable à gâteau/lein est construit en jar de la tâche. Dans le gâteau, vous pouvez utiliser l' deftask macro pour ajouter à une tâche de formes et de dépendances.

(deftask jar #{my-test})

Lein utilise Robert Hooke pour ajouter des tâches. C'est vraiment cool de la bibliothèque, nommé d'après le préféré de tous naturel philosophe, mais il aurait besoin d'une macro pour la concision de l' deftask.

(add-hook #'leiningen.jar/jar (fn [f & args]
                                (my-test)
                                (apply f args)))

Gâteau a aussi la notion d'un projet global. Vous pouvez ajouter un utilisateur spécifique dev-dépendances, comme swank, ~/.cake/project.clj et l'avoir sur l'ensemble de vos projets. Le projet global est également utilisé pour démarrer un repl l'extérieur d'un projet pour l'expérimentation. Lein implémente des fonctionnalités similaires, en soutenant par-configuration de l'utilisateur en ~/.lein/init.clj, et les mondial de plugins en ~/.lein/plugins. En général, Lein a actuellement beaucoup plus riches plugin écosystème de gâteau, mais le gâteau comprend plus de tâches hors de la boîte (la guerre, le déploiement, la java compilation native, dépendances, clojars, et swank). Cljr peut également être utile de vérifier, c'est avant tout un projet global avec un gestionnaire de paquet, mais sans renforcer les capacités (je n'ai aucune expérience avec elle, cependant).

Le réel irreconcible différence est la tâche de définitions, comme technomancy souligné. Dans mon (biaisée) avis, gâteau gère les tâches de beaucoup mieux. Le besoin pour une tâche de dépendance modèle est devenu évident lorsque nous avons commencé à utiliser le protocole de tampons dans notre projet avec lein. Protobufs ont été pré-requis pour l'ensemble de nos tâches, mais leur compilation est vraiment lent. Nous avons aussi beaucoup de l'inter-tâches dépendantes, de sorte que toute construire a été douloureux. Je n'aime pas l'exigence d'un autre espace de noms, et donc un ajout src fichier, pour chaque tâche, j'ai créer. Les développeurs doivent créer un grand nombre de tâches, lein approche de la décourage en créant trop de frottements. Avec un gâteau, vous pouvez simplement utiliser le deftask macro au sein du projet.clj.

Le gâteau est encore jeune, et d'un travail en cours, mais il est très active au projet.

7voto

zmx Points 66

Comme 2011-11-15, l'annonce de la fusion de gâteau et lein

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X