I have a project.clj file derived from someone else's git repo. There's a line that reads
:jvm-opts ^:replace []
I know that :jvm-opts allows adding java command line options. What does ^:replace do? There is some about it in Leiningen's profile.md, and it's mentioned in Leiningen's example project file sample.project.clj, but I still don't understand. I want to add "-Xmx1G" to to jvm-opts.
Just add to the options vector the one you need:
:jvm-opts ["-Xmx1g"]
If you have more than one:
:jvm-opts ["-Xmx1g" "-server"]
replace can be used in many configuration options where different map sets or vectors are merged.
So in this situation if you want the jvm-opts to be only the ones you specify use replace metadata (otherwise other options may be merged depending on your configuration)
Related
Is there a way to programmatically insert the name of my home directory into file paths in Leiningen's project.clj?
I run a Leiningen project on different machines, where I have different home directories. The project uses jar files that are not managed by Maven; I download 'em and put them in a directory that's relative to my home directory, or copy them into the Leiningen project. The second option works but is undesirable.
An easy way to use the first option--keeping the jar files somewhere else--is to add a soft link to the "somewhere else" directory in my Leiningen directory. That works, but the link has to be different on each machine, so I can't include the link file in the git repository, and I'd rather include everything in the git repo.
Isn't there a way to use environmental variables, or otherwise refer to my home directory, in my project.clj file? I've gone through the sample project file and have not found a solution, so far.
I thought I could just construct path strings at run time--what's in project.clj is just Clojure code, after all. Since hard-coding my home directory into project.clj works without any trouble:
:resource-paths [/Users/myhomedir/dist/mason/jar/mason.19.jar")]
I figured I could do this:
:resource-paths [(str (System/getenv "HOME") "/dist/mason/jar/mason.19.jar")]
However, Leiningen doesn't like this at all:
java.lang.IllegalArgumentException: No implementation of method: :as-file of protocol: #'clojure.java.io/Coercions found for class: clojure.lang.PersistentList
Changing [...] to (vector ...) gives the same error but with 'clojure.lang.Symbol` at the end.
In the name of repeatability you'd better have the jar installed in the local maven repository and have it added to the project.clj :dependencies so it's fetched from there. But you said those jars won't be managed by maven, so here we go:
defproject is a macro and it allows to use unquoting to do arbitrary evaluation. It does it by calling the internal fn unquote-project. So you can do the following:
:resource-paths [~(str (System/getenv "HOME") "/dist/mason/jar/mason.19.jar")]
I have a project that works fine using lein run. Now I want to compile it into a standalone jar using lein uberjar. However, there are a couple of source files in my src/projectname/ directory called e.g. playground.clj and stats.clj that I use for experimenting with emacs & the repl, but that I don't want to compile for the final project.
With something like make, I would specify all files that should be compiled. With clojure/leiningen, it seems, all files are compiled by default - how can I exclude files? I haven't found anything in the leiningen docs.
I am currently using :aot :all. Is this the place to change something? Again, I couldn't find detailed documentation on this.
UPDATE:
The suggestions so far haven't worked. What has worked, however, is to include all desired namespaces instead of excluding the ones that should not be compiled. E.g.:
(defproject myproject "version"
;; ...
:profiles {:uberjar {:aot [myproject.data
myproject.db
myproject.util]}})
Have a look at leiningen's sample project.clj, which describes how to use :jar-exclusions or :uberjar-exclusions to exclude arbitrary paths when creating jars (resp. uberjars).
;; Files with names matching any of these patterns will be excluded from jars.
:jar-exclusions [#"(?:^|/).svn/"]
;; Files with names matching any of these patterns will included in the jar
;; even if they'd be skipped otherwise.
:jar-inclusions [#"^\.ebextensions"]
;; Same as :jar-exclusions, but for uberjars.
:uberjar-exclusions [#"META-INF/DUMMY.SF"]
Old question, but I think I found the answer for those coming after me.
I found the answer in the link to the sample leiningen project from #amalloy's answer, except instead of :jar-exclusions I use source-paths, here.
The idea is to create two separate source directories, one for stuff you don't care to spread around and one for stuff you do:
dev-src/<your-project>/playground.clj
dev-src/<your-project>/stats.clj
src/<your-project>/<everything-else>
Then, in your project.clj, include src in source-paths normally, and include emacs-src in a special profile where your want it visible, say the usual :dev profile:
{
;; ...
:source-paths ["src"]
:profiles {
:dev {
:source-paths ["src" "dev-src"]
}
}
}
That way when you're messing around on your machine those files will be in the jar, and when you deploy to clojars or compile with uberjar they will not be included in the jar, nor compiled.
Try this (ns ^:skip-aot my-ns)
You can also do
(ns ^{:skip-aot true} my-ns
(require [...]))
Source
I'd like to add certain library dependencies to LightTable as a whole so that when I am messing around learning new stuff, I don't have to create a new project as a whole.
Let's say I want to always have access to these libraries: math.combinatorics and math.numeric-tower.
Lighttable seems to be calling a repl from leinigen, so am I really needing to add something there?
See https://github.com/LightTable/LightTable/blob/master/project.clj
It will be calling a repl of Leiningen. Rather than adding the dependencies to LightTable you could add them to your Leiningen Profile (~/.lein/profiles.clj)
The file would probably look something like this with your dependencies:
{:user {:dependencies [[math.combinatorics "x.x.x"]
[math.numeric-tower "x.x.x"]]}}
Generally this is not a very good idea. It will be a global thing and will probably cause you problems in the future. If you create an application you might find that these two libraries are available when they won't be for other people or on difference computers.
What would be a better option would be to create a new project using Leiningen. You can then edit your project.clj file to look something like this
(defproject math-thing "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.6.0"]
[math.combinatorics "x.x.x"]
[math.numeric-tower "x.x.x"]])
Then when editing your clj file LightTable uses your project.clj file to start instrepl and will resolve any needed dependencies.
Use the leiningen profile e.g. ~/.lein/profiles.clj and define a :injections [ ... ] node which performs the (require '[ ]) and import, refer-clojure and other items you have. I generally prefer to have at least Alembic present in my dev profile (wrapping Maven/Sonatype) so I can download, install in maven then classpath and project reload in one go using a macro/function wrapper around distill* to prevent a long load time due to too many libraries included in the user space. Pretty much this is the only function I usually want present in any REPL or LT InstaRepl and I put development and debugging snippets in project ./dev/user.clj to keep most of the messy stuff project specific.
This question is a follow up to How does one pre-load a clojure file in the leiningen repl?.
My ~/.lein/profiles.clj looks as follows:
{
:user {:source-paths ["C:/Users/username/.lein/src"] }
}
My ~/.lein/src/user.clj might look as follows:
(ns user)
(println "user file loaded")
When I run lein repl within a folder containing a project.clj, then the user.clj file is executed, but when I run lein repl from another folder it doesn't load my user profile. Is there a workaround for this or is this behavior by design? In fact, I know that Leinigen is indeed loading my profile.clj (even when there is no project.clj) because there are also other things inside (taken from the excellent pimp my repl article). Leinigen is just having problems with my additional source-paths setting.
One other question related to this is the fact that I need to specify the full path of the folder for my user.clj file : "C:/Users/username/.lein/src". When I change that to "~/.lein/src" leiningen fails to load my file.
It sounds like you just want some code loaded for your lein repl sessions. This is done with the :init key of the :repl-options in your profiles.clj. You can load-file other files in init if you want to organize in that fashion.
{:user
{:repl-options
{:init (load-file "path-to-file/user.clj")}
...}}
Note: If you are using Windows-style path delimiters /, you'll need to escape them //.
I want to create a number of uberjars with different main entrypoints from a single codebase. I see you can specify the main namespace as an argument to lein uberjar but I don't see a way to specify the resulting filename or path, so they'll just overwrite one another. Is there a way to override the output filename or path from the command line?
Or is there a better way of doing this? Have separate project files that all reference a central "library" project? If so, what would the physical structure of this look like and how to get it to build?
You can use multiple Leiningen profiles to accomplish what you are talking about.
(defproject project1 "0.1.0-SNAPSHOT"
:description "Something Amazing!"
:dependencies [[org.clojure/clojure "1.5.1"]]
:profiles {:v1 {:main project1.core1
:uberjar-name "uberjar1.jar"}
:v2 {:main project1.core2
:uberjar-name "uberjar2.jar"}
:v3 {:main project1.core3
:uberjar-name "uberjar3.jar"}})
And, you can build them with:
$ lein with-profile v1:v2:v3 uberjar
Here is an annotated reference source where you can find an option for specifying a name of your output jar or uberjar file and any other options that may be set in a project.clj file.
;;; Jar Output
;; Name of the jar file produced. Will be placed inside :target-path.
;; Including %s will splice the project version into the filename.
:jar-name "sample.jar"
;; As above, but for uberjar.
:uberjar-name "sample-standalone.jar"