tools-deps 2023-09-01

I have been editing a java file in combination with clojure code, which means i have to recompile and restart my repl. is there a way to run clojure -T:build compile-java && clojure -M:dev:test:repl in a single call? it's annoying to have to wait for clojure to spin up twice

Very late to the party, but this is a perfect use case for Makefile:

.javac: $(wildcard java/foo/*.java)
    clojure -T:build compile-java

repl: .javac
    clojure -M:dev:test:repl
You will only compile java if some java file changed.

is that what wildcard does? I've never heard of that before

wildcard allows you to depend on multiple files (using glob-like syntax), or files that may be absent (which, if present, would invalidate the 'cache')

Alex Miller (Clojure team) 2023-09-01T14:22:24.513579Z

have you heard the good word about the repl?

😅 1
Alex Miller (Clojure team) 2023-09-01T14:22:59.293509Z

you could run the build in your repl, then restart

👍 1

care to explain a little? I thought i had to restart the repl to get the latest version of the compiled java class

Alex Miller (Clojure team) 2023-09-01T14:23:49.796869Z

you do (well, depends on your editor - Cursive can hot reload classes) but the tools.build call is ultimately just running a function

Alex Miller (Clojure team) 2023-09-01T14:24:55.800319Z

you might (depends on your deps) be able to include the :build alias in your repl (+ "." in :paths) and then just (build/compile {})

Alex Miller (Clojure team) 2023-09-01T14:25:26.590029Z

b/c tools.build will bring in a lot of deps, these might conflict with your app, but also they might not :)

Alex Miller (Clojure team) 2023-09-01T14:25:58.515119Z

OR you could do the same in a separate repl that you keep running for hte purpose of rebuilding

Alex Miller (Clojure team) 2023-09-01T14:26:36.105909Z

this is where "builds as programs" comes home :)

cool, that all makes sense

FWIW, I run a REPL for my build script 24x7 separate from my application so that I can run pipelines of tasks easily. I start my "build REPL" like this:

clj -M:build -i build.clj -e "(in-ns 'build)" -r
and I make sure all my build.clj functions return their options hash map argument so I can thread them easily. Although you'd still have to wait for your clojure -M:dev:test:repl command to spin up, at least you could use the "build REPL" to run:
build=> (compile-java {})
and not have to wait for it to spin up every time. An example of something I run in the "build REPL":
(->build=>  {} (check-all) (ancient) (cve-check) (cold-start) (test-stable) (build-uberjars))

https://meyvn.org will watch a directory of Java source files, and when modification occurs, it will recompile the affected class and its dependent classes. It achieves this by doing static analysis not on source files but on compiled classes. By keeping a dependency graph, it knows which classes need to be reloaded and in what order. This is a seamless experience. Here's a https://www.youtube.com/watch?v=xIuJ0f1Vqek.