* @Making Leiningen work for You
[images/leiningen.png ]
** Clojure Conj 2010
** Phil Hagelberg
* @Making Leiningen work for You
** Designed to not set your hair on fire
**
** Started 31 October 2009... released 17 November
**
** 50+ contributors; 20000+ downloads
**
** Used by ~70% of OSS Clojure projects (c. July)
* @Usage
** You know the drill:
**
=$ lein new marabunta=
=$ find . -type f=
=./README=
=./project.clj=
=./src/marabunta/core.clj=
=./test/marabunta/test/core.clj=
=./.gitignore=
* @Usage: project.clj
-|clojure-mode
(defproject marabunta "1.0.0-SNAPSHOT"
:description "A sample project"
:url "http://example.com/marabunta"
:dependencies [[clojure "1.2.0"]
[robert/hooke "1.0.2"]]
:dev-dependencies [[lein-difftest "1.0.0"]
[swank-clojure "1.2.1"]]
:repositories {"private" {:url "http://private.repo"
:username "milgrim"
:password "locative.1"}})|
* @Usage: Dependencies
[images/clojars.png ]
* @Usage: Publishing
=$ lein jar && lein pom=
=$ scp pom.xml *jar clojars.org:=
**
** Now everyone can depend on it.
* @Advanced: Test Selectors
** New in 1.4
**
-|clojure-mode
;; in project.clj:
:test-selectors {:integration :integration
:default (fn [m] [...])
:all (constantly true)}|
**
=$ lein test :integration=
**
** Will skip deftests without :integration in metadata.
**
** You can create/compose arbitrary predicates.
* @Advanced: User Plugins
=$ ln -s swank-clojure.jar ~/.lein/plugins=
**
=$ lein help swank=
=Arguments: ([] [port] [port host & opts])=
=Launch swank server for Emacs [...]=
**
** Doesn't need to be added to every project.clj file.
**
** Coming in 1.4: plugin task to manage installation.
* @Advanced: Checkout Deps
=$ mkdir checkouts=
=$ ln -s ~/src/ring checkouts=
=$ lein classpath # has ring's src=
**
** Useful for hacking two projects in parallel.
**
** No need for the "install, switch projects, deps, restart" dance.
* @Advanced: Shell Wrappers
=$ lein install swank-clojure 1.3.0-SNAPSHOT=
=$ ~/.lein/bin/swank-clojure=
=#<ServerSocket ServerSocket[...]>=
**
** Nicer if you put ~/.lein/bin on your $PATH.
* @Advanced: Shell Wrappers
** Customizing Shell Wrappers
**
-|clojure-mode
;; in project.clj
:shell-wrapper {:bin "bin/marabunta"
:main marabunta.core}|
**
** Classpath and -main are interpolated into %s with format.
**
** Let's improve the state of CLI Clojure.
* @Writing Tasks
** Tasks are just functions.
**
-|clojure-mode
(ns leiningen.mytask)
(defn mytask [project]
(println "My project:" project))|
**
** Q: How should X be represented?
** A: clojure.lang.IFn
**
** Can leverage memoize, composability, etc.
**
** Project arg detected from arglists.
* @Writing Tasks: JVM Isolation
** We can't allow Leiningen's code to mix with the project.
**
** Launches a subprocess with the project's classpath.
**
** Allows projects to use any Clojure version.
**
-|clojure-mode
(eval-in-project project
`(doseq [n# '~namespaces]
(when-not ~*silently*
(println "Compiling" n#))
(clojure.core/compile n#)))|
* @Extending Tasks
** Robert Hooke!
**
-|clojure-mode
(defn spacing [f x]
(f (apply str (interpose " " x))))
(defn embiggen [f x]
(f (.toUpperCase x)))
(add-hook #'println spacing)
(add-hook #'println embiggen)
(println "foobar") ;; => F O O B A R|
* @Extending Tasks: Robert Hooke
** Hooke gives you total control over function execution.
**
*** binding (see test selectors)
**
*** decide not to continue
**
*** modify arguments
**
*** add side-effects
**
*** return different value
* @Extending Tasks: Guidelines
** Normally add hooks to Leiningen tasks or eval-in-project.
**
** ... but you can hook any function.
**
**
**
** Caveats:
**
*** Don't bother hooking functions you control.
**
*** Accept the same ranges of arguments as the original.
**
*** Hooking multimethods makes new defmethods impossible.
* @Community
** Leiningen is the most-contributed-to Clojure project.
**
[images/impact.png ]
**
** 50+ contributors as of early October:
**
** http://www.ohloh.net/p/leiningen/contributors
* @Community
** How do you make your project easy to contribute to?
**
*** Communicate low hanging fruit. (LHF)
**
*** Document internals, maintain a hacking guide.
**
*** Accept patches promptly.
**
*** Trust people! Commit rights should be easy to get.
**
*** Oh yeah, and stickers.
* @Community: Plugins
** Plugins are just jars that define tasks or include hooks.
**
*** lein-multi
**
*** lein-difftest
**
*** radagast
**
*** leiningen-war
**
*** ...and many more:
**
** http://github.com/technomancy/leiningen/wiki/Plugins
* @The Future
** • 1.4 release: test selectors, plugin consolidation.
**
** • Aether: aka Maven, the Good Parts.
**
** • Explicit public API.
**
** • Better Nailgun support for quick test runs.
**
** • Use jars straight out of ~/.m2/repository.
**
** • Make it easier to use Hudson. (CloudBees)
* @Thanks!
**
** Questions?
**
**
**
**
=$ git clone git://enigma.local/lein.git=
**
** http://github.com/technomancy/leiningen
**
** http://technomancy.us
**
** http://p.hagelb.org/conj-2010-slides.org.html