leiningen/doc/PROFILES.md

121 lines
4.8 KiB
Markdown

# Profiles
In Leiningen 2.x you can change the configuration of your project by
applying various profiles. For instance, you may want to have a few
extra test data directories on the classpath during development
without including them in the jar, or you may want to have Swank
Clojure available in every project you hack on without modifying every
single project.clj you use.
By default the `:dev`, `:user`, and `:default` profiles are activated
for each task, but the settings they provide are not propagated
downstream to projects that depend upon yours. Each profile is defined
as a map which gets merged into your project map.
The example below adds a "dummy-data" resources directory during
development and a dependency upon "midje" that's only used for tests.
```clj
(defproject myproject "0.5.0-SNAPSHOT"
:description "A project for doing things."
:dependencies [[org.clojure/clojure "1.4.0"]]
:profiles {:dev {:resources-path ["dummy-data"]
:dependencies [[midje "1.4.0"]]}})
```
You can place any arbitrary defproject entries into a given profile
and they will be merged into the project map when that profile is
active.
## Declaring Profiles
In addition to `project.clj`, profiles specified in
`~/.lein/profiles.clj` will be available in all projects, though those
from `profiles.clj` will be overridden by profiles of the same name in
the `project.clj` file. This is why the `:user` profile is separate
from `:dev`; the latter is intended to be specified in the project
itself. In order to avoid collisions, the project should never define
a `:user` profile, nor should `profiles.clj` define a `:dev` profile.
Use the `show-profiles` task to see what's available.
If you want to access dependencies during development time for any
project place them in your `:user` profile.
```clj
{:user {:plugins [[lein-swank "1.4.0"]
[lein-pprint "1.1.1"]]}}
```
Profiles are merged by taking each key and combining the value if it's
a collection and replacing it if it's not. Profiles specified earlier
take precedence when replacing. The dev profile takes precedence over
user by default. Maps are merged recursively, sets are combined with
`clojure.set/union`, and lists/vectors are concatenated. You can add
hints via metadata that a given value should take precedence or be
displaced if you want to override this logic:
```clj
{:profiles {:dev {:prep-tasks ^:replace ["clean" "compile"]
:aliases ^:displace {"launch" "run"}}}}
```
The exception to this merge logic is that plugins and dependencies
have custom de-duplication logic since they must be specified as
vectors even though they behave like maps (because it only makes sense
to have a single version of a given dependency present at once). The
replace/displace metadata hints still apply though.
## Activating Profiles
Another use of profiles is to test against various sets of dependencies:
```clj
(defproject swank-clojure "1.5.0-SNAPSHOT"
:description "Swank server connecting Clojure to Emacs SLIME"
:dependencies [[org.clojure/clojure "1.2.1"]
[clj-stacktrace "0.2.4"]
[cdt "1.2.6.2"]]
:profiles {:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]}
:1.4 {:dependencies [[org.clojure/clojure "1.4.0-beta1"]]}})
```
To activate other profiles for a given run, use the `with-profile`
higher-order task:
$ lein with-profile 1.3 test :database
Multiple profiles may be combined with commas:
$ lein with-profile qa,user test :database
Multiple profiles may be executed in series with colons:
$ lein with-profile 1.3:1.4 test :database
A single `with-profile` call does not apply across task comma-chained tasks.
## Debugging
To see how a given profile affects your project map, use the
[lein-pprint](https://github.com/technomancy/leiningen/tree/master/lein-pprint)
plugin:
$ lein with-profile 1.4 pprint
{:compile-path "/home/phil/src/leiningen/lein-pprint/classes",
:group "lein-pprint",
:source-path ("/home/phil/src/leiningen/lein-pprint/src"),
:dependencies
([org.clojure/tools.nrepl "0.0.5" :exclusions [org.clojure/clojure]]
[clojure-complete "0.1.4" :exclusions [org.clojure/clojure]]
[org.thnetos/cd-client "0.3.3" :exclusions [org.clojure/clojure]]),
:target-path "/home/phil/src/leiningen/lein-pprint/target",
:name "lein-pprint",
[...]
:description "Pretty-print a representation of the project map."}
In order to prevent profile settings from being propagated to other
projects that depend upon yours, the default profiles are removed from
your project when generating the pom, jar, and uberjar. Profiles
activated through an explicit `with-profile` invocation will be
preserved. The `repl` task uses its own profile in order to inject
dependencies needed for the repl to function.