Local dependencies in Leiningen without creating a Maven repo? - clojure

I'm building a Compojure web application, and I'd like it to use functions from another Clojure project I wrote. I'm not at all familiar with Maven, and from what I've heard, it has a very steep learning curve. Unfortunately, everything I've seen suggests using a private Maven repo as a dependency and doesn't suggest an alternative. I'd really like to avoid struggling with Maven if possible. Does anyone know of an alternative? I'm currently using the latest version of Leiningen.

If the other project is also a lein project, you just need to do a "lein install" and that will take care of creating all the local maven repo stuff. Then you can just depend on that project as you would do with any other lib. For example:
(defproject mylib "1.0"
....)
lein install
(defproject myotherproject "a.b.c"
:dependencies [[mylib "1.0"]]
.....)
If you are sharing "myotherproject" with other people and you want to remove some of the inconvenience of doing a "lein install" every time you change the mylib project, have a look at the lein checkouts feature and then use the equivalent of svn externals of your VCS of choice.

'lein checkout' appears to be another way to achieve the same goal. a lot more details here and here. In general, the idea is to create a symlink to the local copy of the dependency, but the process does require one lein install. I also found this lein plugin that might be even better, but I've yet to try it myself.

Related

How to add libraries in clojure?

Everywhere I see, it is suggested that I add :dependencies in project.clj and run lein deps. Where are these downloaded? What is my CLASSPATH and how can I add my own JARs to my clojure project?
While the answer for
Dependencies in maven local repositories with leiningen
kind of solves my need, I am not marking it duplicate as what I am asking is much simpler (being a beginner, who does not have much experience with Java to know about Maven). I am still finding it hard to understand where clojure ends and leiningen begins.
The thing I was looking for is a way to add library like we do in most other languages (e.g. copy JAR to project directory and import in code).
This is great question since it's not clear at all. Leiningen is often a black hole and if something isn't working it's often hard to debug.
I just recently had to do some manual scripting and leiningen does help you with finding out these things.
Where are these downloaded?
The directory is in $HOME/.m2. This is Maven's: http://maven.apache.org/settings.html
What is my classpath?
The classpath is set depending on your :dependencies as well as your :source-paths and :resource-paths vectors.
You can find out your classpath like this:
lein classpath
This will print a huge list depending on your configuration.
You could --for instance-- then run a script:
java -cp cljs-1.7.xx.jar:scripts:$(lein with-profile +dev-cljs classpath) clojure.main scripts/cljs-build.clj dev
That has access to all your projects dependencies and loads them properly.
Although you could use lein run to achieve something similar:
lein with-profile +dev-cljs run -m clojure.main scripts/cljs-build.clj dev
How do I add my own JARs?
See: leiningen - how to add dependencies for local jars?
Run lein install from your library's project dir.
Add an entry to :dependencies in client's project.clj.
Make sure the lib name/version and its reference match (eg. [mylib "0.0.1-SNAPSHOT"]).
Hope this helps, forget about jar loc and cp for now.

Getting Leiningen to download dependencies outside of a project

I'm learning Clojure, but I'm not really building whole projects for each little code snippet, I just drop them into a REPL. Occasionally code snippets I'm exploring require a dependency (usually something that is/was in clojure.contrib).
The only way I know how to get those dependencies onto my computer is to have an empty leiningen project, add the dependency to project.clj and run lein deps.
Is there any way I can download libraries globally, outside of a project? If it's that I really really don't want to, why?
I have a small project that I use for testing code snippets and answering SO questions, and am also constantly adding dependencies. The project.clj for this project includes Pomegranate as a dependency which then makes dynamically loading other dependencies as easy as:
(use '[cemerick.pomegranate :only (add-dependencies)])
(add-dependencies :coordinates '[[my-dependency "1.2.3"]])
Give lein-try a go. It's a leiningen plugin I wrote that lets you say something like lein try [my-dependency 1.0.0] or even lein try my-dependency at the command line and drop into a REPL with the dependency available.
If you are using lein-exec as your way of running one-off scripts, you can now use a little snippet at the top of the script. Add:
(use '[leiningen.exec :only (deps)])
(deps '[[clj-time "0.8.0"]])
to the top of your clj. Now running lein exec [example.clj] will automatically pull down the requirement.
If you are new to lein exec, just add {:user {:plugins [[lein-exec "0.3.4"]]}} to your ~/.lein/profiles.clj and you can begin running lein exec on your clj files. It is a great and quick way to run code without a project.

Installing libraries with leiningen without creating project

I am learning Clojure and coming from a Ruby background.
I am looking for something analogous to gem install <library>. The various incantations of lein install do not seem to fit this bill.
Is there a way to simply install a library locally so that it can be referenced in the REPL without the need to create a project?
Seems like, you want to install a library with lein. Here is the plugin, install it and use like
lein localrepo install <filename> <[groupId/]artifactId> <version>
If your aim is merely to load libraries in the REPL consider using alembic. It loads dynamically classpaths, resolve dependencies and automatically pulls libraries from the repositories.
Here is a use case:
(require 'alembic.still)
(alembic.still/distill '[enlive "1.1.1"])
It simply requires you to add the following entry to your .lein/project.clj:
{:dev {:dependencies [[alembic "0.1.1"]]}}
See this answer.
Java and thus clojure do not generally have the the idea of globally installed libraries. You should always be creating a classpath with the minimal set of dependencies. You need somehow to specify and manage this classpath and the easiest way to do this is with leiningen, which requires a project.
leiningen automates the process of retrieving the remote libraries and placing them in your local repository which is somewhat analogous to gem install, but these libraries do not become automatically available to a REPL.
The easiest way to have a set of libraries always available is to have a 'scratch' project which you use for REPL experiments before starting a new project. It's not too much of an overhead.
In lein 2 you can update profiles.clj with package you want to install:
~\user\.lein\profiles.clj
With the first run of any project with lein, the local repo will be updated with what was incereased in profiles.clj.
Sometimes I just run lein deps without being in a project folder, this will update the local repo for you.
This way you can add any library to your project.clj or call it from repl and it will be extracted from local repo.
If you don’t have a project, you add your dependencies in your global lein user profile instead located at ~/.lein/profiles.clj.
The doc isn’t great for lein to be honest. So this part is confusing. But you edit that file as such:
{:user {:plugins [[lein-pprint "1.1.1"]]
:dependencies [[slamhound "1.3.1"]]}}
In the :plugins vector you add whatever global lein plugin you want to have. And in the :dependencies vector you add whatever library you want available globally.
Then anywhere you start a lein repl you’d have those dependencies available to you. And everywhere you run lein you’ll have the additional plugin features available to you.
If you use tools.deps instead of lein, aka, the clj command instead of the lein command. Then it is a bit different. You instead want to modify your ~/.clojure/deps.edn file. Where you’d add dependencies there instead:
{:deps {clj-time {:mvn/version "0.14.2"}}}
So if you put the above in your user deps.edn whenever you run clj command the clj-time library will be available to you.

How to use lein to manage the dependency of a dependency?

Should I create a local repository to change the dependencies of a dependency in my project?
I have a clojure project that is using docjure. docjure contains a dependency on poi 3.6.
Because of a bug in generated Excel files I am reading, I have a local version of poi 3.8 that I hacked to workaround the bug.
It's easy enough to stick my poi 3.8 jars into my projects lib/ directory so that my project will run ok at the repl.
But, lein deps (or jar and uberjar) happily cleans the lib/ directory and reinstalls the 3.6 versions of poi, breaking my build.
I think the probable solution is two-fold:
1 - put my hacked poi 3.8 into a local repository
2 - create my own local copy of docjure and update it's dependencies to point to that local repository.
I am looking for confirmation that this is the "right thing" to do in this case or someone to point out that it is much easier to just do something else.
It is worth reading Leiningen's Repeatability wiki page if you haven't already. To quote part of it:
If the code is public, you should open a bug report with upstream to get them to publish it in a public repository like Clojars, Sonatype, or Maven Central, depending on the project. If they are resistant or too slow it's always possible to publish "Clojars forks"; see lein help deploying for further details there.
The ultimate solution is to try and get your changes pushed upstream. Then you can depend on the version you need, and I think Leiningen will prefer that version if it's higher than the transitive version.
Another option might be to include your jar in a safe (checked-in) directory. Then write a plugin that can hook into a built-in task and copy the jar to your lib directory for you. I really don't know if this will be successful, but it's worth looking into.

What do I do with ClojureScript One?

This is a wonderful project, but where to start?
I thought about making my own github fork for my own project. Or making a branch for each project "inside" of it.
Perhaps I do not really understand this social coding stuff yet -- but I am really feeling the allergy I have with "encapsulated" or "encapsulating" software frameworks and development environments.
Should one make a project inside of the source files, sitting next to the one.sample app? There are so many directories I do not know where to begin. Shouldn't most of the One project be sitting in clojars for us to use and spit out our own app templates, a bit like lein noir new <appname>?
Any and all insights appreciated, thank you!
In episode 3 of the Think Relevance podcast Brenton Ashworth says that at the moment there are three ways to take advantage of ClojureScript One (18min 38sec):
Copy the ClojureScript One project into your own project
Fork the ClojureScript One repo, delete the sample application, and build your own application inside the ClojureScript One project
Look at how CloureSript One handles dependencies, and then use the same approach to setup ClojureScript One as a dependency of your own project.
Sounds like the project team are aware of this being awkward at the moment, and they hope to be able to come up with a better story for this in the future.
To be honest with you.... I've had a ridiculous amount of trouble with clojurescript one. There's just too much code to work with and its good for a reference but not when beginners to clojurescript are just starting out.
The best way to get started with clojurescript is with chris granger's
https://github.com/ibdknox/cljs-template
start your project with:
lein new cljs-template <your project name>
cd <your project name>
lein run
That's it... just go into the src/client directory and start coding! basically, the template gives you a complete project that:
serves pages through ring
has cljs compilation on save so there is no need to muck around with lein cljsbuild
There is a 'clone' of clojurescript-one https://github.com/zcaudate/cljs-template-one made using cljs-template as a guide. It can be used as a project template:
lein new cljs-template-one <your project name>
cd <your project name>
chmod +x bootstrap.sh && ./bootstrap.sh
lein run
The project uses the twitter/bootstrap html template and can be viewed here:
http://cljs-bootstrapped.herokuapp.com/
ClojureScript One have a great wiki pages: https://github.com/brentonashworth/one/wiki. They seem very helpful.