How to omit resources directory when using lein uberjar - clojure

I am building a MIDI application with Clojure and Leiningen, and I am including some example MIDI files in the resources directory for testing on the REPL. However, I would like to exclude these resources when using lein uberjar. I am not sure if this is possible, or if the best place for test files such as these is in the resources directory. I couldn't find anything specific to this... is there a way to exclude with uberjar-exclusions in project.clj?

The correct approach to your problem would be to have a separate resource directory for development purposes, and have it configured separately in your dev profile in leiningen.
:profiles {:dev {:resource-paths ["dummy-data"] ...
Remember settings get merged into existing ones, so you don't need to specify the standard resources path.
Look at the sample project here, and profiles doc here.

Related

Leiningen 'lein install' without writing pom.xml?

I've been contributing to a project in which there's a fixed pom.xml, but I tend to modify project.clj, temporarily, for various purposes. Most of the time, Leiningen seems to ignore pom.xml, but lein install and lein deploy rewrite pom.xml. Is this necessary to Leiningen's functioning? If not, can I stop it? Haven't found anything about this in the online docs yet.
It's not a big problem, but I'd rather not deal with having to restore the official pom.xml in my project before doing a 'git commit', for example.
EDIT: I discovered a solution for my situation, which is to create a 'checkouts' directory with a link to the other project. This causes the other project to be pulled in, without creating a new jar. However, I'm still curious: Does Leiningen need to create pom.xml e.g. for lein install? Why? I'd like to understand the process.
I'm unsure of whether lein install can be run without generating a pom.xml.
The reason it generates a pom is that leiningen uses maven to grab all the dependencies. In fact, maven is able to get dependencies from clojars and leiningen uses it for the clojure dependencies as well as the java ones. Maven requires a pom.xml to specify repository locations and other configuration necessary to run javac (or any other build commands) in addition to a groupId and artifactId to deploy your library to a (potentially local) repository
Another possible workaround to your issue is to use changelists (specifically, if using tortoiseSVN, I'd use the ignore-on-commit changelist) to ignore your pom.xml in most situations commitwise. I believe this stackoverflow answer may assist you with how to do that in git.

Using lein project with /lib doesn't work

When using lein 2.2, trying to put jar files in /lib does not work.
I tried and it doesn't seems to work but plenty of docs out there says this way still works.
The lib directory functionality was removed in Leiningen v2.0, in favor of a repository (repeatability).
To add free floating jars to a project, you will need to either deploy your dependency to Clojars or a Maven repository. The Maven repository can be as simple as a directory in your project folder.
Please see the answer to this question if you need the jar in a project local folder:
How do I use checked-in jars with leiningen
You do not need to use maven to access a local jar file in Leiningen v2.0
Just use syntax like this in your project.clj:
:resource-paths [ "local-jars/*" ]
and then place your *.jar files in the local-jars subdirectory of your project.
Please see this blog: http://www.troyastorino.com/tidbits/lein2-local-jars

Is it possible to add a specific JAR to the Clojure classpath used by the nrepl server?

I use Emacs and nrepl.el for Clojure development and I want to include a JAR file (a proprietary JDBC driver that isn't available on Leiningen/Maven) on the classpath for playing around in the REPL.
I have no intention of releasing this JAR as part of a project. I am just writing some utility functions for my own use so I would rather not make it work with Leiningen/Maven at all and just stick with the classpath.
Is it possible to add a jar manually to the set of dependencies that nrepl-jack-in uses?
It is possible, but not through nrepl.el, as it offloads classpath management to Leiningen.
You can use mvn deploy:deploy-file to deploy the JAR file into your local Maven repository. After that just add the identifier to :dependencies in project.clj and Leiningen will then pick it up just fine.
If that seems like too much manual work, check out lein-localrepo plugin: https://github.com/kumarshantanu/lein-localrepo.
Note that everyone who contributes to your project will need to do this manually. See https://github.com/technomancy/leiningen/wiki/Repeatability for extended discussion on why going this way is often a bad idea and goes against the grain of Leiningen. If you're working in a team, setting up a private repository is the best solution in the long run.

leiningen how to specify dependency for clojure without duplicating jar

Everytime I do a lein new I seem to get a copy of the clojure jar in the lib folder of that project. I thought that jars deps were copied to .m2/repository. Why is the clojure jar duplicated for every lein project?
This only happens with Leiningen 1. The reason for this (I think) was to allow tools to inspect the dependencies easily. With Leiningen 2, this is no longer an issue because it uses the pomegranate library (which is a wrapper for Aether) to manage dependencies. It allows for more robust dependency management, and therefore Leiningen can just link to the dependencies from your local Maven repository.
Jars are cached in your .m2 repo. However, to use them in your project, they need to be on your project's classpath, usually in your project/lib directory. Caching in your local Maven repo just saves you a download from the server.

For a lein project, why is lib/ in .gitignore?

I'm relatively new to Clojure and Java. Why is the lib folder in a lein project not added to the git repo of a lein project? I would think it that would be convenient to have all the necessary jars there for distributed development.
In a Leiningen project, the project.clj file dictates the project's dependencies, and when you run 'lein deps', all dependencies listed in the project.clj file are downloaded to lib/. Therefore, there's no need to check in the jars because the project.clj in combination with the 'lein deps' command is all that's necessary for another person to reproduce the same lib/ that you have. Checking in all the jars is redundant and a waste of space.
Moreover, as mblinn points out, it's better to pull jars from artifact repositories designed for the purpose of distributing and updating dependencies, rather than constantly changing and committing new jars whenever a dependency gets updated. This is especially true when your project depends on snapshot jars, which are subject to frequent change; if you checked in the jars, you'd have to check in a new jar every time the snapshot gets updated, but if you rely on 'lein deps' to pull jars from artifact repos, then you'll stay up to date with no effort. But even for non-snapshot jars, updating a dependency by changing its version in project.clj and then running 'lein deps' is a lot easier and faster than manually placing the jar in lib/ and checking it in.
I hope the above explanation was accessible. If not, and you don't understand some of the concepts discussed, like artifact repositories or dependencies, let me know and I'll explain.
Git is astonishingly bad at storing binary files. If you check in your jars and then have to perform upgrades down the line, soon your repository will be hundreds of megabytes.
One of the biggest advantage of automatic dependency management is that your libraries are not stored in your VCS, along with all its subtle implications when it comes to versioning.
As leiningen internally uses maven artifact resolution, you need to manually specify which artifact repositories in case the required dependency is not found in the default repository, namely maven central repository, clojure releases and clojars
E.g. in case of rome v1.0 which is not yet deployed on maven central but it's found on java.net project kenai repo you'll have to type in your project.clj something along these lines:
...
:dependencies [[rome/rome "1.0"] ...]
:repositories {"kenai" "http://download.java.net/maven/2/"}
...
Well the whole point of Leiningen or any other dependency management tool is that it manages your dependencies for you. Those dependencies are located in separate artifact repositories that are better suited to dealing with public releases of software artifacts than source control systems are. Leiningen piggybacks off Maven's (a populate java build/dependency management tool) repository system; however, there are Clojure-specific artifact repos as well.
Anyhow, the whole point is that you declare the dependencies that your project has in your project.clj, and check that project.clj file into source control. Other developers check it out and run 'lein deps' to pull those dependencies down, and voila!