When adding the lein-npm plugin to my re-frame project to manage npm dependencies, lein-npm unexpectedly adds dependencies of dependencies. My understanding is that that's unnecessary, because those are either included in my dependency's jar or otherwise not required (because adding lein-npm to my project is not required in the first place).
Using the re-frame template, I construct this minimal example of my project.clj:
(defproject stamm "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[re-frame "0.9.1"]]
:plugins [[lein-npm "0.6.2"]])
Calling lein npm list now returns the following:
project#0.1.0-SNAPSHOT /path/to/my/project
├── UNMET DEPENDENCY karma#1.0.0
├── UNMET DEPENDENCY karma-chrome-launcher#0.2.0
├── UNMET DEPENDENCY karma-cljs-test#0.1.0
└── UNMET DEPENDENCY karma-junit-reporter#0.3.8
This leads to some 15 MByte of dependencies being downloaded, just by adding lein-npm. I do not declare any of the karma* dependencies shown here in my project.clj (in fact: I do not declare any npm dependencies at all at this point). They originate from the dependency [re-frame "0.9.1"].
Is there a way to prevent that?
I've released re-frame 0.9.2 which puts the NPM dependencies in the :devDependencies key. This will mean that they are not transitive, and re-frame consuming projects won't need to install karma*.
Original answer:
At the time of writing, I don't think there's a way to get around this, but I've opened an issue at https://github.com/RyanMcG/lein-npm/issues/50 to report it.
Related
I'm calling some Clojure (1.8) code in a larger Java project that I don't entirely have control over. Recently some code has been added to the parent that's causing conflicts with the HTTP client clj-http.
From my Clojure project, here's the output of lein deps :tree|grep http:
[clj-http "3.7.0"]
[org.apache.httpcomponents/httpasyncclient "4.1.3" :exclusions [[org.clojure/clojure]]]
[org.apache.httpcomponents/httpcore-nio "4.4.6"]
[org.apache.httpcomponents/httpclient "4.5.3" :exclusions [[org.clojure/clojure]]]
[org.apache.httpcomponents/httpcore "4.4.6" :exclusions [[org.clojure/clojure]]]
[org.apache.httpcomponents/httpmime "4.5.3" :exclusions [[org.clojure/clojure]]]
Running mvn dependency:tree|grep http for the other project returns the following (note that this project is also a child of the parent):
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.1.1:compile
[INFO] | +- org.apache.httpcomponents:httpcore:jar:4.1:compile
Is there a way I can ignore conflicts originating outside of my Clojure code, in lein (or otherwise)?
it's necessary to slog through the conflicts and fix them. There are two approaches:
Exclusions:
Exclude each dependency that is reported in lein deps tree from each of the upstream dependencies where it's provided. This gives you complete control when you need to make sure a transitive dependency is not included. It can though ... "be a bit of a bother" ;-)
Managed Dependencies:
You can also add a managed-dependencies section to your project.clj where you specify the exact version of libraries that will be used, regardless of the resolution of other transitive dependencies. This is a somewhat more blunt instrurment, and one i tend to turn to.
A random example from a project:
:managed-dependencies [[http-kit "2.3.0"]
[org.clojure/clojure "1.9.0"]
[ring/ring-core "1.6.0"]
[ring/ring-jetty-adapter "1.6.0"]
... lots more ...]
I'm trying to use the Checkout Dependencies feature in Leiningen to work on a project that uses a checkout of Flambo. My project.clj looks something like:
(defproject spark-streaming "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]
[yieldbot/flambo "0.4.0-SNAPSHOT"]
[amazonica "0.2.29"]
[clj-time "0.8.0"]] ;other stuff omitted
My directory structure looks like this:
|- checkouts
|- <need symlink to yieldbot/flambo>
|- src
|- project.clj
What I tried:
Since the library name contains a slash, I can't make a symlink named "yieldbot/flambo" to the actual location of Flambo.
I can't do this either:
|- checkouts
|- yieldbot
|- flambo //this is a symlink
because Lein expects a project.clj in the yieldbot directory. Doing lein classpath confirms that my checkout isn't being used.
Directly checkout flambo into checkouts/yieldbot. Doesn't work, for the same reason as above
What can I do?
The only thing lein expects in the directory directly underneath checkouts is a project.clj file. The organization namespace is inferred from that project file, and has nothing to do with the directory structure above the symlink.
In your flambo project file, make sure you have (defproject yieldbot/flambo "version" ... correctly. Then in your checkouts of your spark-streaming project, create a symlink to the flambo directory itself.
I am using lein 2.0
If a main application
(defproject rexfer "1.0.1-SNAPSHOT"
:description "Filters standard report from Patriot Properties' AssessPro."
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/tools.cli "0.2.2"]
[org.clojure/data.csv "0.1.2"]
[rexfer-csv "1.0.0-SNAPSHOT"]
[util "1.0.7-SNAPSHOT"]]
:omit-source true
:main rexfer.core)
depends on a library (util 1.07-SNAPSHOT)
(defproject util "1.0.7-SNAPSHOT"
:description "A general purpose Clojure library"
:dependencies [[org.clojure/clojure "1.4.0"]
[clojure-csv/clojure-csv "1.3.2"]
[org.clojure/data.csv "0.1.2"]]
:aot [util.core]
:omit-source true)
is the reference fetching a .jar file or a standalone .jar?
Another way to ask this question is should I be building standalone jars for libraries like
util "1.0.7-SNAPSHOT"
that require a main application to use them?
You should deploy the jar produced by lein jar rather than lein uberjar. You can also safely expect all reasonable libraries to be deployed in this way.
This is roughly because of the following:
correctly prepared jars contain metadata on their dependencies, so users will know to fetch the dependencies along with your jar;
it often happens that a project uses several libraries which share common dependencies -- it would be wasteful to have each shared dependency replicated in several jars;
the user may have good reason to override some of your dependency choices (which happens all the time, incidentally; replacing a transitive dependency with a different version or excluding a transitive dependency is common) -- with a regular jar they will be able to do so easily, while it would be a pain with an überjar.
Of course if the coordinates of some of your dependencies do happen to point at überjars, that's what's going to end up being pulled in by Leiningen. I've never come across a library misdeployed like that though.
If you don't want to run lein uberjar then the answer to your second question would be yes. These jars need to be available on the class path for the main application to run. The job of lein uberjar is to include all the dependencies and dependencies of dependencies etc.
Can anyone tell me some working dependencies to get up and running with zeromq and clojure?
I've tried several but leiningen isn't able to fetch them:
(Could not find artifact org.zmq:zmq:jar:2.1.0 in central (http://repo1.maven.org/maven2))
[org.zmq/zmq "2.1.0"]
[org.zmq/jzmq "1.0.0"]
I have compiled jzmq (/usr/local/share/java/jzmq.jar) and added this to my project.clj:
:native-path "/usr/local/lib"
There's a 2.0-SNAPSHOT here:
Lein should already have the clojars repo loaded.
What I propose is a mixture of what's already been proposed, but for the sake of completeness and hopefully to give a final answer I give it a try.
Since the dependency is not in the online repos I would include the jar(s) in the project's directory structure itself, e.g. in the directory repository and keep it in the source control system as the other files of the project. It's an important part of the project and without the dependency it won't run.
In this directory I would save the jar with the help of Maven Install plugin.
mvn install:install-file \
-Dfile=/usr/local/share/java/jzmq.jar \
-DgroupId=org.zeromq \
-DartifactId=jzmq \
-Dversion=2.1.0 \
-Dpackaging=jar \
-DlocalRepositoryPath=repository
When the jar file gets copied to the local repository, you define it and the dependency in project.clj as follows:
(defproject clojure-interal-repo-test "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.4.0"]
[org.zeromq/jzmq "2.1.0"]]
:repositories [["zeromq-repository" {:url "file:repository"
:snapshots false
:checksum :ignore
:update :never}]])
Within the project, run lein2 deps :tree to verify its correctness.
$ lein2 deps :tree
Retrieving org/zeromq/jzmq/2.1.0/jzmq-2.1.0.jar (4k) from file:repository/
[org.clojure/clojure "1.4.0"]
[org.zeromq/jzmq "2.1.0"]
Please note that the 4k above is the size of a fake file I created to test it out.
Read the document Repeatability in Leiningen's wiki should you need a bit more.
The only way I could get it to work was to use jeromq.
[org.zeromq/jeromq "0.3.2"]
Jeromq is native Java.
You can create a Maven local repository, install the compiled library into your local repo, and then, add the following to your project.clj
:repositories {"local" ~(str (.toURI (java.io.File. "your_local_repository_path")))}
Similar question, I have answered earlier here
Unfortunately, ZeroMQ is not present in public repository, at least at the last time I checked (a month ago I think). So you have to install the jar manually:
mvn install:install-file -Dfile=/usr/local/share/java/jzmq.jar -DgroupId=org.zeromq \
-DartifactId=jzmq -Dversion=2.1.0 -Dpackaging=jar
Then you can use the artifact as [org.zeromq/jzmq "2.1.0"] in your project.clj.
I have a lein project in one directory, and instead of using the .jar that gets downloaded when I run
> lein deps
I want to use the source from a cloned github repository (It has recent fixes not in the current jar). What is the canonical way to do this with leiningen?
Here is my project file:
(defproject oroboros "1.0.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
[clojure-source "1.2.1"]
[overtone "0.3.0"]
[penumbra "0.6.0-SNAPSHOT"]]
:native-dependencies [[penumbra/lwjgl "2.4.2"]]
:dev-dependencies [[native-deps "1.0.5"]
[swank-clojure "1.4.0-SNAPSHOT"]])
I want to use the overtone repo from github, rather than the one from clojars.
https://github.com/overtone/overtone
Is this possible?
You can use checkout dependencies. From Leiningen's README:
Q: I want to hack two projects in parallel, but it's annoying to
switch between them.
A: Use a feature called checkout dependencies. If you create a
directory called checkouts in your project root and symlink some other
project roots into it, Leiningen will allow you to hack on them in
parallel. That means changes in the dependency will be visible in the
main project without having to go through the whole
install/switch-projects/deps/restart-repl cycle. Note that this is not
a replacement for listing the project in :dependencies; it simply
supplements that for tighter change cycles.
Back when I was using lein I simply put symlinks in my project directory to the checked out Overtone source dir.
I use cake for my Overtone hacking these days which has support for adding external projects to the class path. You just need to add the path to project.classpath in your project's .cake/config file:
project.classpath = /Users/sam/Development/improcess/lib/overtone/src: