Permalink
Browse files

Spin off separate profile guide from readme/tutorial.

  • Loading branch information...
1 parent 9a5dba9 commit dff9a6cf24920bbfe6407dc3fa381a7ee4a15a76 @technomancy committed May 25, 2012
View
@@ -54,11 +54,9 @@ project, but here are the commonly-used tasks:
$ lein repl # launch an interactive REPL session
- $ lein jar # package up the whole project as a .jar file
+ $ lein run -m my.namespace # run the -main function of a namespace
- $ lein install # install a project into the local repository
-
- $ lein search [TERM] # find jars for your project.clj dependencies
+ $ lein uberjar # package the project and dependencies as standalone jar
Use `lein help` to see a complete list. `lein help $TASK` shows the
usage for a specific task.
@@ -71,7 +69,7 @@ Most tasks need to be run from somewhere inside a project directory to
work, but some (`new`, `help`, `search`, `version`, and `repl`) may
run from anywhere.
-See the [FAQ](https://github.com/technomancy/leiningen/blob/preview/doc/FAQ.md)
+See the [FAQ](https://github.com/technomancy/leiningen/blob/master/doc/FAQ.md)
for more details.
## Configuration
@@ -82,103 +80,20 @@ The `project.clj` file in the project root should look like this:
(defproject myproject "0.5.0-SNAPSHOT"
:description "A project for doing things."
:url "http://github.com/technomancy/myproject"
- :dependencies [[org.clojure/clojure "1.2.1"]]
+ :dependencies [[org.clojure/clojure "1.4.0"]]
:plugins [[lein-ring "0.4.5"]])
```
-To find specific versions of a dependency, use `lein search`, though
-note that this can be extremely slow the first time you use it.
-
The `lein new` task generates a project skeleton with an appropriate
starting point from which you can work. See the
[sample.project.clj](https://github.com/technomancy/leiningen/blob/preview/sample.project.clj)
file (also available via `lein help sample`) for a detailed listing of
configuration options.
-### 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. To add resources
-directories during development, add a `:profiles` key to project.clj
-like so:
-
-```clj
-(defproject myproject "0.5.0-SNAPSHOT"
- :description "A project for doing things."
- :dependencies [[org.clojure/clojure "1.2.1"]]
- :profiles {:dev {:resources-path ["dummy-data"]}})
-```
-
-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. 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.
-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"]]}}
-```
-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-chains.
-
-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."}
+The `project.clj` file can be customized further with the use of
+[profiles](https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md).
-### Leiningen Plugins
+## Plugins
Leiningen supports plugins which may contain both new tasks and hooks
that modify behaivour of existing tasks. See
View
@@ -0,0 +1,121 @@
+# 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.
View
@@ -78,21 +78,6 @@ They usually contain .class files (JVM bytecode) and .clj source
files, but they can also contain other things like config
files.
-<!--
-TODO: bring back this section if we can speed up search
-
-The `lein search` command will search each remote repository:
-
- $ lein search lancet
- == Results from clojars - Showing page 1 / 1 total
- [lancet "1.0.0"] Dependency-based builds, Clojure Style.
- [lancet "1.0.1"] Dependency-based builds, Clojure Style.
-
-Note that this command will take many minutes to run the first time
-you invoke it on a given machine; it needs to download a rather large
-index.
--->
-
You can [search Clojars](http://clojars.org/search?q=clj-http) using its
web interface.
@@ -101,9 +86,9 @@ web interface.
This shows two different ways of specifying a dependency on the latest
stable version of the `clj-http` library, one in Leiningen format and
one in Maven format. We'll skip the Maven one for now, though you'll
-need to learn to read it for Java libraries. You can copy the
-Leiningen version directly into the `:dependencies` vector in
-`project.clj`.
+need to learn to read it for Java libraries from
+[Central](http://search.maven.org). You can copy the Leiningen version
+directly into the `:dependencies` vector in `project.clj`.
Within the vector, "clj-http" is referred to as the "artifact id".
"0.4.1" is the version. Some libraries will also have "group ids",
@@ -144,44 +129,6 @@ in project.clj. See the
TODO: cover repl, run, trampoline tasks
-<!-- TODO: move this section
-## Profiles
-
-Sometimes you want to pull in dependencies that are really only
-necessary while developing; they aren't required for the project to
-function in production. You can do this by adding a `:dependencies`
-entry to the `:dev` profile. These will be available unless you
-specify different profiles using the `with-profiles` task, but they
-are not brought along when another project depends on your project.
-
-Using [midje](https://github.com/marick/Midje) for your tests would be
-a typical example; you would not want it included in production, but it's
-needed to run the tests:
-
-```clj
-(defproject my-stuff "0.1.0-SNAPSHOT"
- :description "FIXME: write description"
- :url "http://example.com/FIXME"
- :license {:name "Eclipse Public License"
- :url "http://www.eclipse.org/legal/epl-v10.html"}
- :dependencies [[org.clojure/clojure "1.3.0"]]
- :profiles {:dev {:dependencies [[midje "1.3.1"]]}})
-```
-
-Note that profile-specific dependencies are different from plugins in
-context; plugins run in Leiningen's process while dependencies run in
-your project itself. (Older versions of Leiningen lacked this distinction.)
-
-If you have dependencies that are not _necessary_ for developing but
-just for convenience (things like
-[Swank Clojure](http://github.com/technomancy/swank-clojure) for Emacs
-support or [clj-stacktrace](http://github.com/mmcgrana/clj-stacktrace)
-you should add them to the `:user` profile in `~/.lein/profiles`
-instead of the `:dev` profile. Both those profiles are active by
-default; the difference is the convention for where they are specified.
-
--->
-
## Tests
It's easy to kick off a test run:
@@ -345,8 +292,8 @@ a public repository. While it's possible to
[maintain your own private repository](https://github.com/technomancy/leiningen/blob/preview/doc/DEPLOY.md)
or get it into Central, the easiest way is to publish it at
[Clojars](http://clojars.org). Once you have
-[created an account](https://clojars.org/register) there, publishing
-is easy:
+[created an account](https://clojars.org/register) there with your SSH
+public key, publishing is easy:
$ lein jar, pom
$ scp pom.xml target/my-stuff-0.1.0.jar clojars@clojars.org:
View
@@ -53,6 +53,7 @@
;; looked up in ~/.lein/profiles.clj rather than set in project.clj.
;; Use the with-profiles higher-order task to run a task with a
;; different set of active profiles.
+ ;; See `lein help profiles` for a detailed explanation.
:profiles {:dev {:resource-paths ["dummy-data"]
:dependencies [[clj-stacktrace "0.2.4"]]}
:debug {:debug true
View
@@ -92,7 +92,8 @@
(defn ^:no-project-needed help
"Display a list of tasks or help for a given task.
-Also provides readme, faq, tutorial, news, sample, deploying and copying info."
+Also provides readme, faq, tutorial, news, sample, profiles,
+deploying and copying info."
([project task] (println (or (static-help task) (help-for project task))))
([project]
(println "Leiningen is a tool for working with Clojure projects.\n")
@@ -105,4 +106,5 @@ Also provides readme, faq, tutorial, news, sample, deploying and copying info."
(println "\nAliases:")
(doseq [[k v] aliases]
(println (str k " " v)))))
- (println "\nSee also: readme, faq, tutorial, news, sample, deploying and copying.")))
+ (println "\nSee also: readme, faq, tutorial, news, sample, profiles,
+deploying and copying.")))
@@ -1,15 +1,15 @@
-(ns leiningen.profiles
+(ns leiningen.show-profiles
(:require [clojure.string]
[clojure.pprint :as pprint]
[leiningen.core.project :as project]
[leiningen.core.user :as user]))
(defn- all-profiles [project]
- (merge (deref project/default-profiles)
+ (merge @project/default-profiles
(user/profiles)
(:profiles project)))
-(defn ^:no-project-needed profiles
+(defn ^:no-project-needed show-profiles
"List all available profiles or display one if given an argument."
([project]
(->> (all-profiles project)
Oops, something went wrong.

0 comments on commit dff9a6c

Please sign in to comment.