Spin off separate profile guide from readme/tutorial.
This commit is contained in:
parent
9a5dba9a37
commit
dff9a6cf24
8 changed files with 146 additions and 156 deletions
99
README.md
99
README.md
|
@ -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
|
||||
The `project.clj` file can be customized further with the use of
|
||||
[profiles](https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md).
|
||||
|
||||
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."}
|
||||
|
||||
### Leiningen Plugins
|
||||
## Plugins
|
||||
|
||||
Leiningen supports plugins which may contain both new tasks and hooks
|
||||
that modify behaivour of existing tasks. See
|
||||
|
|
121
doc/PROFILES.md
Normal file
121
doc/PROFILES.md
Normal file
|
@ -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.
|
|
@ -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:
|
||||
|
|
1
resources/leiningen/help/profiles
Symbolic link
1
resources/leiningen/help/profiles
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../doc/PROFILES.md
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|
@ -13,7 +13,10 @@
|
|||
"Apply the given task with the profile(s) specified.
|
||||
|
||||
Comma-separated profiles may be given to merge profiles and perform the task.
|
||||
Colon-separated profiles may be given for sequential profile task application."
|
||||
Colon-separated profiles may be given for sequential profile task application.
|
||||
|
||||
To list all profiles or show a single one, see the show-profiles task.
|
||||
For a detailed description of profiles, see `lein help profiles`."
|
||||
[project profiles task-name & args]
|
||||
(let [profile-groups (seq (.split profiles ":"))
|
||||
project (:without-profiles (meta project) project)
|
||||
|
|
Loading…
Reference in a new issue