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

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!

Related

Do I need to stage the 'vcpkg' directory to git

I am new to c++ development environment from javascript dev environment. Comparing to javascript package management, c++ is complicated. I found vcpkg that like npm for cpp.
The question :- When it comes to 'vcpkg' do I need to stage all files (to git) that contains in /vcpkg directory. Or just add it to .gitignore.
The project diretory :-
The /vcpkg directory contains a lot of files, that why I asked.
You shouldn't upload the dependencies to your repository. The correct thing to do is to use vcpkg in manifest mode. This way vcpkg.json package will be used to keep track of your dependencies. Every time you install or remove a package vcpkg.json will be automatically updated eliminating the need to upload your dependencies to your repository. You only need to upload vcpkg.json to your repository which is much faster. It also has many more advantages, take a look at https://vcpkg.readthedocs.io/en/latest/users/manifests/

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.

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.

Maven dependencies for Clojure libraries on GitHub

I'm developing some applications in Clojure + Java using Eclipse and Maven with m2eclipse.
This works great when my dependencies are in a Maven repository. However there are some libraries that I would like to use that aren't in any repository - e.g. small open source Clojure libraries hosted on GitHub.
These projects typically have a build.xml or a project.clj but not a pom.xml.
Is there a any way to set up Maven to handle these dependencies automatically? Or do I need to manually download and build all of these?
Unfortunately no, you'll either have to:
find a repository containing those libraries
manually add these to your repository using mvn install (and if you're kind enough, ask for those to be published in the central maven repo)
ask the developers if they would be so kind to propose a mavenized version and publish it in some maven repository
Clojure libraries often provide their artifacts in clojars, you might solve your issues just by adding it as a repository in your pom.xml.
Another option available when integrating leiningen and maven builds is to automatically generate a POM out of a project.clj via lein pom
This would allow to include the libraries in your build as long as you checked them out locally.