1<!-- START doctoc generated TOC please keep comment here to allow auto update --> 2<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 3**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 4 5- [Profiles](#profiles) 6 - [Declaring Profiles](#declaring-profiles) 7 - [Default Profiles](#default-profiles) 8 - [Task Specific Profiles](#task-specific-profiles) 9 - [Profile Metadata](#profile-metadata) 10 - [Merging](#merging) 11 - [Activating Profiles](#activating-profiles) 12 - [Composite Profiles](#composite-profiles) 13 - [Dynamic Eval](#dynamic-eval) 14 - [Debugging](#debugging) 15 16<!-- END doctoc generated TOC please keep comment here to allow auto update --> 17 18# Profiles 19 20You can change the configuration of your project by applying various 21profiles. For instance, you may want to have a few extra test data 22directories on the classpath during development without including them 23in the jar, or you may want to have development tools like 24[Slamhound](https://github.com/technomancy/slamhound) available in 25every project you hack on without modifying every single `project.clj` 26you use. 27 28You can place any arbitrary key/value pairs supported by `defproject` 29into a given profile and they will be merged into the project map when 30that profile is activated. 31 32The example below adds a "dummy-data" resources directory during 33development and a dependency upon "expectations" that's only used for 34tests/development. 35 36```clj 37(defproject myproject "0.5.0-SNAPSHOT" 38 :description "A project for doing things." 39 :dependencies [[org.clojure/clojure "1.4.0"]] 40 :profiles {:dev {:resource-paths ["dummy-data"] 41 :dependencies [[expectations "1.4.41"]]}}) 42``` 43 44Use the `show-profiles` task to list the project's profiles. 45 46## Declaring Profiles 47 48In addition to `project.clj`, profiles also can be specified in `profiles.clj` 49within the project root. Profiles specified in `profiles.clj` will override 50profiles in `project.clj` (via [merging](#merging) logic described below), so 51this can be used for project-specific overrides that you don't want committed 52in version control. 53 54User-wide profiles can also be specified in 55`~/.lein/profiles.clj`. These will be available in all projects 56managed by Leiningen, though those profiles will be overridden by 57profiles of the same name specified in the project. System-wide 58profiles can be placed in `/etc/leiningen/profiles.clj`. They are 59treated the same as user profiles, but with lower precedence. 60 61You can also define user-wide profiles within `clj`-files inside 62`~/.lein/profiles.d`. The semantics within such files differ slightly 63from other profile files: rather than a map of maps, the profile map 64is the top-level within the file, and the name of the profile comes 65from the file itself (without the `.clj` part). Defining the same 66user-wide profile in both `~/.lein/profiles.clj` and in 67`~/.lein/profiles.d` is considered an error. 68 69## Default Profiles 70 71Certain profiles are active by default unless you specify another set 72of profiles using the `with-profile` task. Each of the default 73profiles have different semantics: 74 75If you want to access dependencies or plugins during development time 76for any project place them in your `:user` profile. Your 77`~/.lein/profiles.clj` file could look something like this: 78 79```clj 80{:user {:plugins [[lein-pprint "1.1.1"]] 81 :dependencies [[slamhound "1.3.1"]]}} 82``` 83 84The `:dev` profile is used to specify project specific development 85tooling. Put things here if they are required for builds or tests, 86rather than just convenience tooling. 87 88The `:user` profile is separate from `:dev`; the latter is intended to 89be specified in the project itself. In order to avoid collisions, the 90project should never define a `:user` profile, nor should a user-wide 91`:dev` profile be defined. Likewise, system profiles should use the 92`:system` profile, and define neither `:user` nor `:dev` profiles. 93 94The `:system` profile is similar to `:user`, except it applies 95system-wide instead of merely to a single user. 96 97The `:base` profile provides dependencies necessary for basic repl 98functionality, adds `dev-resources` to the `:resource-paths`, and sets 99defaults for `:jvm-opts`, `:checkout-deps-share` and 100`:test-selectors`. It is part of Leiningen itself; you shouldn't need 101to change it. 102 103The profiles listed above are active during development, but they are 104unmerged before the jar and pom files are created, making them 105invisible to code that depends upon your project. 106 107The `:provided` profile is used to specify dependencies that should be 108available during jar creation, but not propagated to other code that 109depends on your project. These are dependencies that the project 110assumes will be provided by whatever environment the jar is used in, 111but are needed during the development of the project. This is often 112used for frameworks like Hadoop that provide their own copies of 113certain libraries. 114 115The `:default` profile specifies the profiles that are active by 116default when running lein tasks. If not overridden, this is set to 117`:leiningen/default`, which is a composite profile with 118`[:base :system :user :provided :dev]`. 119 120## Task Specific Profiles 121 122Some tasks automatically merge a profile if specified. Examples of 123these are the `:test` profile, when running the `test` task, and the 124`:repl` profile, when running the `repl` task. Please note that 125putting things in the `:test` profile is strongly advised against as 126it can result in tests which can't be run from the repl. 127 128## Profile Metadata 129 130If you mark your profile with `^:leaky` metadata, then the profile 131will not be stripped out when the pom and jar files are created. 132 133If you mark a profile with `^{:pom-scope :test}` metadata, then the 134profile's `:dependencies` will be added with a `test` scope in the 135generated pom and jar when active. The `:dev`, `:test`, and `:base` 136profiles have this set automatically. 137 138If you mark a profile with `^{:pom-scope :provided}` metadata, then 139the profile's `:dependencies` will be added with a `provided` scope in 140the generated pom and jar when active. The `:provided` profile has 141this set automatically. 142 143## Merging 144 145Profiles are merged by taking each key in the project map or profile 146map, combining the value if it's a collection and replacing it if it's 147not. Profiles specified later take precedence when replacing, just 148like the `clojure.core/merge` function. The dev profile takes 149precedence over user by default. Maps are merged recursively, sets are 150combined with `clojure.set/union`, and lists/vectors are 151concatenated. You can add hints via metadata that a given value should 152take precedence (`:replace`) or defer to values from a different 153profile (`:displace`) if you want to override this logic: 154 155```clj 156{:profiles {:dev {:prep-tasks ^:replace ["clean" "compile"] 157 :aliases ^:displace {"launch" "run"}}}} 158``` 159 160The exception to this merge logic is that `:plugins` and `:dependencies` 161have custom de-duplication logic since they must be specified as 162vectors even though they behave like maps (because it only makes sense 163to have a single version of a given dependency present at once). The 164replace/displace metadata hints still apply though. 165 166Remember that if a profile with the same name is specified in multiple 167locations, only the profile with the highest "priority" is picked – no merging 168is done. The "priority" is – from highest to lowest – `profiles.clj`, 169`project.clj`, user-wide profiles, and finally system-wide profiles. 170 171If you need to enable personal overrides of parts of a profile, you can use a 172composite profile with common and personal parts - something like `:dev 173[:dev-common :dev-overrides]`; you would then have just `:dev-overrides {}` in 174`project.clj` and override it in `profiles.clj`. 175 176Another use of profiles is to test against various sets of dependencies: 177 178```clj 179(defproject swank-clojure "1.5.0-SNAPSHOT" 180 :description "Swank server connecting Clojure to Emacs SLIME" 181 :dependencies [[org.clojure/clojure "1.2.1"] 182 [clj-stacktrace "0.2.4"] 183 [cdt "1.2.6.2"]] 184 :profiles {:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]} 185 :1.4 {:dependencies [[org.clojure/clojure "1.4.0-beta1"]]}}) 186``` 187 188## Activating Profiles 189 190To activate a different set of profiles for a given task, use the 191`with-profile` higher-order task: 192 193 $ lein with-profile 1.3 test :database 194 195Multiple profiles may be combined with commas: 196 197 $ lein with-profile qa,user test :database 198 199Multiple profiles may be executed in series with colons: 200 201 $ lein with-profile 1.3:1.4 test :database 202 203The above invocations activate the given profiles in place of the 204defaults. To activate a profile in addition to the defaults, prepend 205it with a `+`: 206 207 $ lein with-profile +server run 208 209You can also use `-` to deactivate a profile. 210 211By default all profiles will share the same `:target-path`, which can 212cause problems if settings from one profile leak over into 213another. It's recommended to set `:target-path` to `"target/%s"`, 214which will isolate each profile set and prevent anything from bleeding over. 215 216## Composite Profiles 217 218Sometimes it is useful to define a profile as a combination of other 219profiles. To do this, just use a vector instead of a map as the profile value. 220This can be used to avoid duplication: 221 222```clj 223{:shared {:port 9229, :protocol "https"} 224 :qa-servers {:servers ["qa.mycorp.com"]} 225 :prod-servers {:servers ["prod1.mycorp.com", "prod1.mycorp.com"]} 226 :qa [:shared :qa-servers] 227 :production [:shared :prod-servers]} 228``` 229 230It is not recommended to make a composite profile which contains both 231keywords and maps; they should either be all keywords or all maps. 232 233Composite profiles also cannot have certain types of metadata 234propagated, which makes them incompatible with the `:provided` 235profile. If you get the error "Composite profiles are incompatible with :provided." 236consider adding `^{:pom-scope :provided}` metadata to the profile map 237which contains the dependencies instead. 238 239## Dynamic Eval 240 241Often you want to read an environment variable or execute a function to capture 242a value to use in your profiles. In order to do such a thing with the profiles.clj 243you'll need to use the read-eval syntax. 244 245Here is an example of such a case: 246 247```clj 248{:user {:compile-path #=(eval (System/getenv "ci.compile-path")), 249 :target-path #=(eval (System/getenv "ci.target-path"))}} 250``` 251 252## Debugging 253 254To see how a given profile affects your project map, use the 255[lein-pprint](https://github.com/technomancy/leiningen/tree/stable/lein-pprint) 256plugin: 257 258 $ lein with-profile 1.4 pprint 259 {:compile-path "/home/phil/src/leiningen/lein-pprint/classes", 260 :group "lein-pprint", 261 :source-path ("/home/phil/src/leiningen/lein-pprint/src"), 262 :dependencies 263 ([nrepl "0.8.3" :exclusions [org.clojure/clojure]] 264 [incomplete "0.1.0" :exclusions [org.clojure/clojure]] 265 [org.thnetos/cd-client "0.3.3" :exclusions [org.clojure/clojure]]), 266 :target-path "/home/phil/src/leiningen/lein-pprint/target", 267 :name "lein-pprint", 268 [...] 269 :description "Pretty-print a representation of the project map."} 270 271In order to prevent profile settings from being propagated to other 272projects that depend upon yours, the `:default` profiles are removed 273from your project when generating the pom, jar, and uberjar, and an 274`:uberjar` profile, if present, is included when creating 275uberjars. (This can be useful if you want to specify a `:main` 276namespace for uberjar use without triggering AOT during regular 277development.) Profiles activated through an explicit `with-profile` 278invocation will be preserved. 279