Skip to content

Latest commit

 

History

History
91 lines (68 loc) · 3.53 KB

PLUGINS.md

File metadata and controls

91 lines (68 loc) · 3.53 KB

Leiningen Plugins

Leiningen tasks are simply functions named $TASK in a leiningen.$TASK namespace. So 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 the tasks it provides with "lein $TASK".

Writing a Plugin

Start by generating a new project with "lein new myplugin", and add a leiningen.myplugin namespace with a myplugin function. That function should take at least one argument: the current project. The project is a map which is based on the project.clj file, but it also has :name, :group, :version, and :root keys added in. If you want it to take parameters from the command-line invocation, you can make the function take more arguments.

Note that Leiningen is an implied dependency of all plugins; you don't need to explicitly list it in the project.clj file.

The docstring from the plugin's namespace will be displayed by the "lein help" task. The function's arglists will also be shown, so pick argument names that are clear and descriptive.

If your task returns an integer, it will be used as the exit code for the process.

You can set up aliases for your task by conjing a pair of strings with alias->task-name mappings on to the leiningen.core/aliases atom:

(swap! leiningen.core/aliases conj ["-v" "version"])

Lancet

If your plugins need to do a fair amount of filesystem-y things, you may want to take a look at using Ant tasks to do them since the JDK lacks a lot of simple functionality of this kind. Using the Ant API directly is a pain, but it can be eased to a degree using Lancet. Lancet is the Clojure adapter for Ant that is developed as the sample project in the Programming Clojure book.

You can look over the Ant API documentation's listing of tasks to find an appropriate task. See the deps task for an example of how to call a task from Clojure.

Hooks

You can modify the behaviour of built-in tasks to a degree using hooks. Hook functionality is provided by the Robert Hooke library. This is an implied dependency; as long as Leiningen 1.2 or higher is used it will be available.

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)]
    (apply task args)))

(add-hook #'leiningen.test/test skip-integration-hook)

Hooks compose, so be aware that your hook may be running inside another hook. To take advantage of this functionality, projects must set the :hooks key in project.clj to a seq of namespaces to load that call add-hook.

See the documentation for Hooke for more details.

Have Fun

Please add your plugins to the list on the wiki.

Hopefully the plugin mechanism is simple and flexible enough to let you bend Leiningen to your will.