Remove Leiningen's run-task in favour of Robert Hooke.

This commit is contained in:
Phil Hagelberg 2010-06-11 23:03:02 -07:00
parent 3a3366dd47
commit 7d4444455b
5 changed files with 39 additions and 51 deletions

View file

@ -5,7 +5,7 @@ writing a Leiningen plugin is pretty straightforward; as long as it's
available on the classpath, Leiningen will be able to use it.
To use a plugin, add it to your project.clj :dev-dependencies and run
"lein deps". Then you'll be able to invoke it with "lein my-plugin".
"lein deps". Then you'll be able to invoke it with "lein myplugin".
## Writing a Plugin
@ -37,15 +37,24 @@ alias->task-name mappings on to the leiningen.core/aliases atom:
## Hooks
You can modify the behaviour of built-in tasks to a degree using
hooks. Inspired by clojure.test's fixtures functionality, hooks are
functions which wrap tasks and may alter their behaviour by using
binding, altering the return value, only running the function
conditionally, etc. The add-hook function takes a var of the task it's
meant to apply to:
hooks. Hook functionality is provided by [Robert
Hooke](http://github.com/technomancy/robert-hooke), a separate
library. Your plugin will have to declare it as a dependency in
project.clj if you want to use hooks:
(defn skip-integration-hook [task]
:dev-dependencies [[robert/hooke "1.0.1"]]
Inspired by clojure.test's fixtures functionality, hooks are functions
which wrap tasks and may alter their behaviour by using binding,
altering the return value, only running the function conditionally,
etc. The add-hook function takes a var of the task it's meant to apply
to and a function to perform the wrapping:
(use 'robert.hooke)
(defn skip-integration-hook [task & args]
(binding [clojure.test/test-var (test-var-skip :integration)]
(task)))
(apply task args)))
(add-hook #'leiningen.test/test skip-integration-hook)
@ -54,14 +63,14 @@ another hook. Hooks are loaded by looking for all namespaces under
leiningen.hooks.* on the classpath and loading them in alphabetical
order.
Please add your plugins to [the list on the
wiki](http://wiki.github.com/technomancy/leiningen/plugins).
If you want to call another task from a plugin, don't call it
directly. Call it with leiningen.core/run-task instead so it will load
all its hooks and run the task wrapped inside them.
See [the documentation for
Hooke](http://github.com/technomancy/robert-hooke/blob/master/README.md)
for more details.
## Have Fun
Please add your plugins to [the list on the
wiki](http://wiki.github.com/technomancy/leiningen/plugins).
Hopefully the plugin mechanism is simple and flexible enough to let
you bend Leiningen to your will.

View file

@ -2,7 +2,7 @@
"Compile the namespaces listed in project.clj or all namespaces in src."
(:require lancet)
(:use [leiningen.deps :only [deps]]
[leiningen.core :only [ns->path run-task]]
[leiningen.core :only [ns->path]]
[leiningen.classpath :only [make-path find-lib-jars get-classpath]]
[clojure.java.io :only [file]]
[clojure.contrib.find-namespaces :only [find-namespaces-in-dir]])
@ -95,7 +95,7 @@
(empty? (.list (file (:compile-path project)))))
(compile project))
(when (empty? (find-lib-jars project))
(run-task 'deps [project]))
(deps project))
(let [java (Java.)
native-path (or (:native-path project)
(find-native-lib-path project))]

View file

@ -65,33 +65,12 @@
(catch java.io.FileNotFoundException e
#'task-not-found))))
(defn- hookize [v]
(when-not (::hooks (meta @v))
(alter-var-root v vary-meta assoc ::hooks (atom []))))
(defn add-hook [task-var f]
(hookize task-var)
(swap! (::hooks (meta @task-var)) conj f))
(defn- load-hooks [task]
(defn- load-hooks []
(doseq [n (sort (find-namespaces-on-classpath))
:when (re-find #"^leiningen\.hooks\." (name n))]
(require n)))
;; These two were taken from fixtures in clojure.test; thanks Stuart!
(defn- compose-hooks [f1 f2]
(fn [g] (f1 (fn [] (f2 g)))))
(defn- join-hooks [hooks]
(reduce compose-hooks #(%) (and hooks @hooks)))
(defn run-task
"Run the given task with its hooks activated."
[task-name args]
(let [task (resolve-task task-name)]
(load-hooks task-name)
((join-hooks (::hooks (meta @task)))
#(apply @task args))))
(try (require n)
(catch Exception e
(println "Problem loading hooks:" n (.getMessage e))))))
(defn ns->path [n]
(str (.. (str n)
@ -105,17 +84,19 @@
(replace \/ \.)))
(defn -main
([& [task & args]]
(let [task (or (@aliases task) task "help")
args (if (@no-project-needed task)
([& [task-name & args]]
(let [task-name (or (@aliases task-name) task-name "help")
args (if (@no-project-needed task-name)
args
(conj args (read-project)))
compile-path (:compile-path (first args))]
(when compile-path (.mkdirs (File. compile-path)))
(binding [*compile-path* compile-path]
(load-hooks)
;; TODO: can we catch only task-level arity problems here?
;; compare args and (:arglists (meta (resolve-task task)))?
(let [value (run-task task args)]
(let [task (resolve-task task-name)
value (apply task args)]
(when (integer? value)
(System/exit value))))))
([] (apply -main (or *command-line-args* ["help"]))))

View file

@ -1,7 +1,6 @@
(ns leiningen.install
"Install the project and its dependencies in your local repository."
(:use [leiningen.core :only [run-task]]
[leiningen.jar :only [jar]]
(:use [leiningen.jar :only [jar]]
[leiningen.pom :only [pom make-model]]
[clojure.java.io :only [file]])
(:import [org.apache.maven.artifact.installer ArtifactInstaller]
@ -40,7 +39,7 @@
nil))
(defn install [project]
(let [jarfile (file (run-task 'jar [project]))
(let [jarfile (file (jar project))
model (make-model project)
artifact (make-artifact model)
installer (.lookup container ArtifactInstaller/ROLE)
@ -48,6 +47,6 @@
;; for packaging other than "pom" there should be "pom.xml"
;; generated and installed in local repo
(if (not= "pom" (.getPackaging model))
(add-metadata artifact (file (run-task 'pom [project]))))
(add-metadata artifact (file (pom project))))
(.install installer jarfile artifact local-repo)))

View file

@ -4,7 +4,6 @@
(:use [clojure.zip :only [xml-zip]]
[clojure.java.io :only [file copy]]
[clojure.contrib.zip-filter.xml :only [xml-> tag=]]
[leiningen.core :only [run-task]]
[leiningen.jar :only [jar]])
(:import [java.util.zip ZipFile ZipOutputStream ZipEntry]
[java.io File FileOutputStream PrintWriter]))
@ -44,7 +43,7 @@ the dependency jars. Suitable for standalone distribution. Note that this
will include all jars in lib, so if you have dev dependencies in there, you
may wish to clean first."
[project]
(run-task 'jar [project])
(jar project)
(let [jarname-root (str (:name project) \- (:version project))]
(with-open [out (-> (file (:root project)
(str jarname-root "-standalone.jar"))