Clojure and lein - clojure

Are there some useful ways of triggering complete rebuilds in lein? I'm finding it hard to understand how / when lein reruns/reloads code. Altering files doesn't always seems to result in the changes being applied, and manually requesting recompile for gen-class doesn't always seem to generate files.
Manually deleting files in the target directory doesn't always work, as even if I recompile those files are not always generated so I'll get ClassNotFound errors. How do I have lein properly rebuild everything on each invocation?
edit: most of my confusion was due to not specifying classes created with gen-class in the project.clj file with an :aot directive as suggested in #juan.facorro's comment, e.g.
(defproject
...
:aot [mytestclass.full.packagename.TestClass1 mytestclass.full.packagename.TestClass2 ]
...
)

This sounds like part of a bigger issue: making the clojure development cycle shorter. Once you have your project running happily in the REPL (and this is the first goal) there are several things thats can really drag down the development speed. Changing protocol deffinitions for instance requires you to hunt down and reload every namespace that has instances of that protocol. Stewart Sierra made a great project, gave a presentation and interview about how to set up your project and process so everything that needs reloading is reloaded as quickly as possible.

Related

In a Clojure/ClojureScript project, what are the advantages of declaring dependencies on a `deps.edn` file instead of using `shadow-cljs.edn`?

I have been using Clojure, ClojureScript, lein, shadow-cljs, re-frame, reagent, Emacs, and CIDER to work on a Clojure/ClojureScript dynamic web app project.
Currently, the project uses project.clj and shadow-cljs.edn to declare dependencies.
There is a discussion about changing things so that:
1 - We would start using a lein plug-in called lein-tools-deps
2 - Also, we would tweak shadow-cljs.edn file so that the dependencies would be removed and the file only indicate:
:dependencies true
3 - Finally, we would create a new deps.edn file holding all the dependencies.
It is not totally clear the advantages of this process.
I can see one: instead of declaring dependencies on shadow-cljs.edn and on project.clj they would be in a single file: deps.edn.
Is there another benefit of having dependency declaration via deps.edn instead of using shadow-cljs.edn and project.clj via :dependencies?
For instance, would this affect the use of Maven packages hosted on GitHub packages? Is deps.edn better for that?
deps.edn has the benefit that it supports direct git dependencies (ie. :git/url), as well as an easy mechanism for local dependencies (ie. :local/root). It is also more modern and becoming the "default".
shadow-cljs.edn has no support for these features, project.clj has some via plugins or other mechanism (eg. checkouts).
So, if you want those features it make sense to use deps.edn. However, depending on how complex your project is that might not be an easy switch.
shadow-cljs ultimately doesn't care how you manage your dependencies, but if you move things out of shadow-cljs.edn you are taking "power" away from it. If managed via shadow-cljs.edn it tries to prevent certain mistakes (eg. dependency conflicts), it can't do that when running via deps.edn. So, you'll have to sort those out manually potentially. It may just work, really depends on your project.

Interactive workflow with external libraries in Clojure [duplicate]

I have multiple, separate leiningen projects that ostensibly could depend on one-another.
Example:
~/projects/mywebapp (my own project)
~/projects/noir (a clone of the github repo)
~/projects/clojureql (a clone of the github repo)
I want to have them all compiled into the same JVM at the same time. I would like to run the git repos bleeding edge (pulling new commits/making my own commits) and not have to run lein jar or lein deps and certainly not have to restart the VM if I change any of the projects.
Here's a use case:
After running lein swank, from within emacs, I connect to the repl and compile a file from mywebapp (with C-c-k), which requires a file from noir. It finds the version of the file in my projects directory. Later, I open that file, edit it, and compile it (with C-c-k).
Note that I'm not asking for auto-compiling when I do git pull. I just don't want to have to restart the JVM or do lengthy jar compiling processes.
Is this possible in leiningen? How can I set this up?
Does this question from the Lein FAQ help?
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.
If you're already using swank, you don't need lein checkout dependencies. You can just C-c C-k your project (which will load the jarred versions of noir/whatever), and then browse to your local version of noir and C-c C-k that as well. Swank happily sends all the code to your repl, and the jvm never need know that it came from a different place!
I can only recommend this for smallish changes though, because I think if you compile noir.core, which depends on (say) noir.internal, clojure will load the jarred version of noir.internal even while you compile the local version of noir.core. Even so, it's a handy trick in general.

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.

make lein uberjar without source files

I'm using 'lein uberjar' to make a executable jar file of my project.
the jar is created correctly and runs as expected.
I just want to know if it is possible to NOT include my source .clj files in the generated .jar, since I'm planning to distribute it, and I don't want my source files available to the public.
I'm using lein 1.7.1
if not possible with lein, would it work if I just manually removed the .clj files from the jar? I did a test and it worked, by I want to be sure that this is safe to do.
thanks in advance.
Use :omit-source true in lein's project.clj.
Have you tried using the aot compilation step that is provided? See here for an example.
Also, someone blogged something not too long ago about aot compiling their entire project: http://blog.japila.pl/2012/02/aot-compile-all-namespaces-in-a-clojure-project-aot-all-in-project-clj-leiningen/
In that case, too, you might still have to dig in and remove the .clj files, I'm not sure. Maybe this is somewhere to start, though.
Edit 1
I should note that even if you were to use compilation to just distribute the .class files, there are really good tools to decompile those classes in a way that users can read (I've used this in the past when the documentation was so poor I had to look elsewhere to see how it worked).
In those cases, you'd be better off finding a way to implement your own code obfuscator, although I know little/nothing about that topic, here's a start.

How can I set up leiningen to work with multiple projects?

I have multiple, separate leiningen projects that ostensibly could depend on one-another.
Example:
~/projects/mywebapp (my own project)
~/projects/noir (a clone of the github repo)
~/projects/clojureql (a clone of the github repo)
I want to have them all compiled into the same JVM at the same time. I would like to run the git repos bleeding edge (pulling new commits/making my own commits) and not have to run lein jar or lein deps and certainly not have to restart the VM if I change any of the projects.
Here's a use case:
After running lein swank, from within emacs, I connect to the repl and compile a file from mywebapp (with C-c-k), which requires a file from noir. It finds the version of the file in my projects directory. Later, I open that file, edit it, and compile it (with C-c-k).
Note that I'm not asking for auto-compiling when I do git pull. I just don't want to have to restart the JVM or do lengthy jar compiling processes.
Is this possible in leiningen? How can I set this up?
Does this question from the Lein FAQ help?
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.
If you're already using swank, you don't need lein checkout dependencies. You can just C-c C-k your project (which will load the jarred versions of noir/whatever), and then browse to your local version of noir and C-c C-k that as well. Swank happily sends all the code to your repl, and the jvm never need know that it came from a different place!
I can only recommend this for smallish changes though, because I think if you compile noir.core, which depends on (say) noir.internal, clojure will load the jarred version of noir.internal even while you compile the local version of noir.core. Even so, it's a handy trick in general.