Question

Quelle est la différence entre gâteau et Leiningen?

Était-ce utile?

La solution

Cette réponse continue d'obtenir un intérêt, probablement comme référence pour Leiningen dans StackOverflow il est maintenant considérablement modifié pour le mettre à jour pour 2014.

Leiningen et gâteau refusionnés en 2011. Leiningen (version 2) est désormais l'outil d'automatisation de facto Clojure.

Leiningen est un outil de construction et le gestionnaire de dépendance pour Clojure qui inclut la possibilité de mettre en place un REPL interactive avec la manière appropriée configuré classpath et avec toutes les dépendances java et Clojure acquises de manière automatisée à partir Maven dépôts et / ou la communauté en fonction Clojars .

gâteau était très semblable à Leiningen (jusqu'à utiliser le même format de fichier project.clj à l'époque) mais tenté d'éviter beaucoup de frais généraux de démarrage en gardant JVMs persistantes autour de l'arrière-plan. C'était plus réactif mais échangé commodité pour les bugs en raison de l'état accumulé dans les processus persistants (anciennes définitions de fonction traîner, etc.) au cours typique de développement basé sur REPL itérative. Cette avéré être une mauvaise affaire.

L'expérience de Leiningen et un désir constant des temps de démarrage plus rapides ont conduit à un certain nombre de recommandations et approches pour accélérer les choses: https://github.com/technomancy/leiningen/wiki/Faster

Autres conseils

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

L'approche du gâteau est « il est difficile d'étendre les fonctions après qu'ils ont été définis, alors inventons un nouveau mécanisme pour les tâches plutôt que des fonctions d'utilisation », ce qui a entraîné la macro deftask.

L'approche de Leiningen est « il est difficile d'étendre les fonctions après qu'ils ont été définis, nous devons donc faire une façon de le faire facilement, de cette façon nous pouvons utiliser des fonctions pour des tâches et aussi être en mesure d'étendre les choses qui ne sont pas des tâches « , ce qui vous permet d'appliquer tous les avantages composabilité des fonctions des tâches.

Comme mentionné Alex, la plus grande différence frappante est la vitesse de la ligne de commande. Gâteau utilise une machine virtuelle Java persistante, de sorte que vous rencontrez seulement le démarrage jvm tête lorsque vous exécutez une tâche dans votre projet pour la première fois. Si vous n'utilisez pas emacs + boue + clojure test en mode, cela peut être un gain de temps énorme. Par exemple, un ensemble assez grand nombre de tests sur un de mes projets fonctionne en 0,3 secondes à gâteau, vs 11.2s en lein.

En plus de la performance, l'idée de base derrière le gâteau est le modèle de tâche de dépendance. Chaque tâche est exécutée une fois que dans une construction donnée, compte tenu de toutes les conditions préalables transitif dans le graphe de dépendance. Voici un exemple de Martin Fowler sur râteau dans la syntaxe de gâteau, qui va directement dans votre 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...")
  ...)

Pour faire la même chose dans Leiningen, vous devez d'abord créer un répertoire de Leiningen dans votre projet avec 4 fichiers:. Code_gen.clj, compile.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 peut attendre ...

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

Mais à la fois des données de charge et mon décompiler dépendent du code-gen, de sorte que votre ouput réelle est ...

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

Vous auriez à 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...

Quel est ce que nous voulons.

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

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

Une autre différence est de savoir comment les tâches sont ajoutées à. Disons que nous voulions ajouter my-test comme condition préalable à gâteau / lein est construit dans la tâche de jar. Dans le gâteau, vous pouvez utiliser la macro deftask à ajouter aux formes et dépendances d'une tâche.

(deftask jar #{my-test})

Lein utilise Robert Hooke pour ajouter aux tâches. Il est une bibliothèque vraiment cool, du nom philospher naturel favori de tout le monde, mais il faudrait une macro pour la concision de deftask.

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

gâteau a aussi l'idée d'un projet global. Vous pouvez ajouter dev dépendances spécifiques de l'utilisateur, comme Swank, à ~/.cake/project.clj et avoir l'ensemble de vos projets. Le projet global est également utilisé pour démarrer une en dehors de rempl d'un projet d'expérimentation. Lein implémente des fonctionnalités similaires en soutenant la configuration par utilisateur dans ~/.lein/init.clj et plugins globaux dans ~/.lein/plugins. En général, Lein dispose actuellement d'un écosystème de plug-in beaucoup plus riche que le gâteau, mais le gâteau comprend plus de tâches de la boîte (guerre, Deploy, compilation java, dépendances indigènes, clojars et Swank). Cljr peut également être utile de vérifier, il est essentiellement juste un projet global avec un gestionnaire de paquets, mais sans capacités de construction (je n'ai aucune expérience avec elle cependant).

La vraie différence est irreconcible DEFINITIONS tâche, comme technomancie souligné. Dans mon (biaisé) avis, poignées de gâteau tâches beaucoup mieux. La nécessité d'un modèle de dépendance de tâche est devenu évident lorsque nous avons commencé à utiliser des tampons de protocole dans notre projet avec Lein. Protobufs étaient pré-requis pour toutes nos tâches, mais les compilant est vraiment lent. Nous avons aussi beaucoup de tâches interdépendantes, so toute construction était douloureuse. Je ne suis pas aussi comme l'exigence d'un espace de noms séparé, et par conséquent un fichier supplémentaire src, pour chaque tâche que je crée. Les développeurs devraient créer une tâche de lot, l'approche de lein dissuade en créant trop de frottement. Avec le gâteau, vous pouvez simplement utiliser la macro deftask dans les project.clj.

gâteau est encore jeune, et un travail en cours, mais il est un projet très actif.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top