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.
Related
I am trying to link a local project to another local project that is under development using tools.deps :local/root option in deps.edn. It isn't working. I can't require the library's namespaces, and the path is correct.
The deps.edn entry looks like:
{:paths ["src" "resources"]
:deps {...
...
...
mylib {:local/root "../../../mylib"}
}}
The classpath that is generated, however, is incorrect:
../../../mylib/src/main/clojure
For some reason clojure/main is added on to the classpath for this library, and I don't know why. Then when I run clj to start the repl I am unable to load the library, and I get the FileNotFoundException.
To test that the addition of main/clojure to the lib path is the problem, I manually removed that part of the path in the cache file in .cpcache directory and was able to require the library namespaces once I'd removed clojure/main.
Does anyone know where the main/clojure is coming from and how I can stop it being added?
UPDATE
I did a new test that leads me to think this has something to do with the use of project.clj as opposed to deps.edn in the target project. In the test I had a project b with a deps.edn like this:
{:deps {a-proj {:local/root "../a-proj"}}}
While a-proj had a project.clj like this:
(defproject a-proj "0.1.0-SNAPSHOT"
:description "blah"
:url "http://example.com/FIXME"
:license {:name "The MIT Licence"
:url "https://opensource.org/licenses/MIT"}
:source-paths ["src"]
:dependencies [])
I then ran clj -Sforece -Spath and got:
~/Projects/b > clj -Sforce -Spath ethan at rembrandt.local
src:/Users/ethan/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar:/Users/ethan/Projects/b/src:/Users/ethan/Projects/a-proj/src/main/clojure:/Users/ethan/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar:/Users/ethan/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar
You can see there that the /main/clojure path has been aded on. When I instead use an essentially deps.edn in a-proj:
{:deps {}}
I get the following path, which seems correct:
~/Projects/b > clj -Sforce -Spath
src:/Users/ethan/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar:/Users/ethan/Projects/b/../a-proj/src:/Users/ethan/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar:/Users/ethan/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar
My deps.edn in ~/.clojure has only this:
{
:aliases {
:new {:extra-deps {seancorfield/clj-new {:mvn/version "0.9.0"}}
:main-opts ["-m" "clj-new.create"]}
:deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.5.435"}}}
:test {:extra-paths ["test"]}
}
}
project.clj is not supported as a project type by the Clojure CLI via deps.edn.
I have a Clojure application that is using a library which is symlinked from inside the "checkouts" directory.
This lets me work on both the app and the library at the same time. And lein knows how to compile and run the program without any problems.
But I want to make a standalone with lein uberjar, and it's complaining
Caused by: java.io.FileNotFoundException: Could not locate mylib/core__init.class, mylib/core.clj or mylib/core.cljc on classpath.
I assume that that is because mylib isn't mentioned in my project.clj file. It isn't, precisely because I want to use the version of mylib symlinked inside "checkouts".
But the uberjar command doesn't seem to be able to see it.
How can I solve this?
You can accomplish this by installing mylib in your local repository (~/.m2/repository).
Run lein install in the dependent project to install it in your local repository.
Add the project to :dependencies: in project.clj:
[mylib "version"]
Run lein uberjar in the main project.
The project will find the jar in your local repository.
/Edit
If you want to develop two libraries at the same time you can use a checkouts folder where checkouts contains a symlink to the dependent library.
mkdir checkouts
ln -nfs full-path-other-lib-dir full-path-checkouts-dir
Now changes in other-lib are immediately available in the main project.
See [https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies](the Leiningen checkouts documentation).
OK, it appears that the "checkouts" feature of lein works with lein test and lein run but not with lein uberjar.
I added the following to the local source code of a lib tupelo.core:
(def dummy-sample-data "Bogus!")
In the consuming project demo.core we can access the new Var:
(ns demo.core
(:use tupelo.core tupelo.test))
(defn -main [& args]
(println :foo-enter)
(spyx dummy-sample-data)
(println :foo-leave))
lein run produces:
:foo-enter
dummy-sample-data => "Bogus!"
:foo-leave
project.clj remains unchanged:
(defproject demo "0.1.0-SNAPSHOT"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
[criterium "0.4.5"]
[org.clojure/math.combinatorics "0.1.6"]
[org.clojure/clojure "1.10.1"]
[prismatic/schema "1.1.12"]
[tupelo "0.9.201"]
<snip>
where "0.9.201" is the latest version of tupelo on Clojars. Checkouts looks like:
~/expr/demo > ls -ldF checkouts/*
lrwxrwxrwx 1 alan alan 17 May 12 13:57 checkouts/tupelo -> /home/alan/tupelo/
but uberjar fails:
~/expr/demo > lein clean ; lein uberjar
Compiling demo.core
Syntax error compiling at (demo/core.clj:6:3).
Syntax error compiling at (demo/core.clj:6:3).
Unable to resolve symbol: dummy-sample-data in this context
Full report at:
/tmp/clojure-10416346559924917196.edn
Compilation failed: Subprocess failed
Options
If you are wanting to deploy an application, you have 2 options:
If the lib exists on Clojars or Maven, you should probably deploy a release there before making a uberjar. If the lib is not ready for Clojars or Maven, maybe you aren't ready to use it in a uberjar...?
Simply copy the source tree of mylib (or use a symlink!) under the ./src dir in your project. You'll also have to copy in the dependencies into myproj/project.clj. You are effectively merging myproj and mylib, at least temporarily with this approach. If the are coupled tightly enough to require co-development, perhaps it should be a permanent merge?
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.
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: